[Android]如何監控手機是否進入休眠

請參考標題連結的作法

比較特別要注意的一點是

監控手機是否進入休眠,不能放在 Android Manifest

需要要註冊receiver時,要加入兩個filter

  • Intent.ACTION_SCREEN_OFF
  • Intent.ACTION_SCREEN_ON

[Android]讓ListView item被選擇時可以變換背景

看到標題時,一開始以為是個很簡單的問題,結果搞了我一、兩天試了n種方法,都無法解決。後來看了一些文章後,得到了一些解答,首先要明白一點,在觸碰模式下(Touch Mode)下是沒有selection state的,這是android developer blog的說明

In touch mode, there is no focus and no selection.

所以必須想一下有哪些作法,可以騙過android以達到selected的效果,想了想,可能還是要從自訂的layout來下手,果然神人vimalrajpara2006 有解答啦!就是自訂一個CheckAbleLayout來達到ListView有單選的效果,以下是我參考其原始碼修改而來

  • 首先自訂一個CheckAbleLayout
package com.example.listview.selected.row;

import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.widget.Checkable;
import android.widget.LinearLayout;

public class CheckableLayout extends LinearLayout implements Checkable {
    private boolean mChecked;

    public CheckableLayout(Context context) {
        super(context);
    }

    public CheckableLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setChecked(boolean checked) {
        mChecked = checked;
        
        // Use this code for setting custom color in background of this layout
        // 當item被點選後,將其背景色改為藍色
        setBackgroundDrawable(checked ? new ColorDrawable(android.graphics.Color.BLUE) : null);
        
        // Use this code for setting custom image in background of this layout
        /*setBackgroundResource(checked ? R.drawable.ic_action_search
                : R.drawable.ic_launcher);*/
    }

    public boolean isChecked() {
        return mChecked;
    }

    public void toggle() {
        setChecked(!mChecked);
    }

}

  • 再來要將ListView的choiseMode設定為singleChoise
  • 最後設定相關的listener

這樣子就大功告成啦!

範例原始檔下載

[Android]偵測軟體鍵盤是否已經隱藏

眾所皆知,android的手機五花八門,其輸入法的型態也是一樣,像Sony的手機會有這個隱藏鍵盤的圖示,紅色框框處。

image

那該如何偵測鍵盤是否已經按下了隱藏鍵盤圖示呢?找了一些論譠和資源,發現並沒有提供,唯一的線索就是顯示軟體鍵盤時,整理的View的配置會有改變,看來是得從這邊下手了。

做法很簡單,只要Activity或Fragment所繫結的Root view layout動個手腳就可以了。假如App的畫面是佔滿螢幕畫面的話,可以參考下列的作法。

  • 實作一個Custom View,假設Root view layout是RelativeLayout
/**
 * Input {@link RelativeLayout}
 * <p>
 * 為了能夠偵測鍵盤在顯示時,被按下隱藏鍵盤圖示(EX: sony的手機, htc sensation, etc....)後,做一些處理的自訂RelativeLayout
 * 
 * @author Jay Lee
 * 
 */
public class KeyboardAwareRelativeLayout extends RelativeLayout {
    private OnKeyboardHiddenListener mCallBack;

    /**
     * 鍵盤被隱藏的Listener
     * 
     */
    public interface OnKeyboardHiddenListener {

        /**
         * 當鍵盤被點選穩藏時要執行的動作
         */
        public void onKeyboardHidden();
    }

    private boolean mKeyboardVisible = false;

    /**
     * Construct a KeyboardAwareRelativeLayout object.
     * 
     * @param context
     *            Context
     */
    public KeyboardAwareRelativeLayout(Context context) {
        super(context);
    }

    /**
     * Construct a KeyboardAwareRelativeLayout object.
     * 
     * @param context
     *            Context
     * @param attrs
     *            AttributeSet
     */
    public KeyboardAwareRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * Construct a KeyboardAwareRelativeLayout object.
     * 
     * @param context
     *            Context
     * @param attrs
     *            AttributeSet
     * @param defStyle
     *            Default style
     */
    public KeyboardAwareRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public boolean isKeyboardVisible() {
        return mKeyboardVisible;
    }

    /**
     * 定義當隱藏鍵盤的Listener
     * 
     * @param listener
     *            OnKeyboardHiddenListener
     */
    public void setOnKeyboardHiddenListener(OnKeyboardHiddenListener listener) {
        mCallBack = listener;
    }

    private void updateKeyboardVisible() {
		// 取得此View的高度
        int viewHeight = getHeight();
		// 取得手機螢幕實際高度
        int displayHeight = getDisplayHeight();

        // 計算時,需要包含Status Bar,而Status Bar的高度為25dp
		// 需要利用程式動態計算出來
		Resources r = getResources();
        int maxStatusBarHeight = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 25f, r.getDisplayMetrics()));
        
        // 當View的高度加上Status Bar的高度比螢幕小時,代表軟體鍵盤目前顯示在畫面上
        boolean oldValue = mKeyboardVisible;
        mKeyboardVisible = (viewHeight + maxStatusBarHeight < displayHeight);
        if (oldValue != mKeyboardVisible && !mKeyboardVisible && mCallBack != null) {
            mCallBack.onKeyboardHidden();
        }
    }
	
	private int getDisplayHeight() {
        WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);

        Display display = windowManager.getDefaultDisplay();

        return display.getHeight();
    }

    /**
     *  如果在onLayout時無法辨識鍵盤被關閉時,也可以透過設定mKeyboardVisible的屬性
     *  並且在mKeyboardVisible為false時,執行mCallBack的動作
     */
    public void setKeyboardVisible(boolean mKeyboardVisible) {
        this.mKeyboardVisible = mKeyboardVisible;
        if (!mKeyboardVisible && mCallBack != null ) {
            mCallBack.onKeyboardHidden();
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (!this.isInEditMode()) {
            updateKeyboardVisible();
        }
    }

}
  • 在Activity或Fragment裡面,將此View實作OnKeyboardHiddenListener
public class MyActivity extends Activity {
    // Views
    private KeyboardAwareRelativeLayout mRootLayout;
    
    // Listeners
    private KeyboardAwareRelativeLayout.OnKeyboardHiddenListener mRootLayoutOnKeyboardHiddenListener = new KeyboardAwareRelativeLayout.OnKeyboardHiddenListener() {

        @Override
        public void onKeyboardHidden() {
            // TODO 在這邊撰寫當軟體鍵盤隱藏時,要做的處理
        }
    };

    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mRootLayout = (KeyboardAwareRelativeLayout) view.findViewById(R.id.root);
		mRootLayout.setOnKeyboardHiddenListener(mRootLayoutOnKeyboardHiddenListener);        
    } 

}
  • 最後在AndroidManifest.xml裡面的<activity>節點裡面,加入android:windowSoftInputMode=”adjustResize” 

如此一來,就能在軟體鍵盤被隱藏時來處理一些事情。

參考資源:

  1. Canned Coding
  2. http://stackoverflow.com/q/3425932/1004367