Android开发——Home键监听方法总结

上周遇到一个这样的问题:监听Home键。
对于Back键的监听比较容易,可以在多个系统回调处拦截,使用onKeydown方法可以处理菜单键和back键。

@Override
    public void onBackPressed() {
        // super.onBackPressed();//注释掉这行,back键不退出activity
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {

        return super.dispatchKeyEvent(event);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        return super.onKeyDown(keyCode, event);

    }

但这些方法不能处理Home事件,因为Home键是系统键,可以将程序退出放在后台,所以这个事件是直接分发给系统,系统接收到之后做相应处理,Home键的事件不是直接传递到应用里面,在framework层就已经被拦截,所以在上述监听Back键的回调方法中是收不到Home键的事件的。

查阅了网上的资料,总结下方法:
1. 对Home键的监听主要通过注册广播接收器实现
拦截让窗口关闭的系统动作,然后根据Intent里面的具体参数,分析当前到底是Home键, 应用切换键,还是其他功能按键。
在使用广播监听使用ACTION_CLOSE_SYSTEM_DIALOGS。
下面是http://blog.csdn.net/way_ping_li/article/details/8953622里给出的封装好了的监听Home键的方法:

/** * Home键监听封装 * * @author way * */
public class HomeWatcher {

    static final String TAG = "HomeWatcher";
    private Context mContext;
    private IntentFilter mFilter;
    private OnHomePressedListener mListener;
    private InnerRecevier mRecevier;

    // 回调接口
    public interface OnHomePressedListener {
        public void onHomePressed();

        public void onHomeLongPressed();
    }

    public HomeWatcher(Context context) {
        mContext = context;
        mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
    }

    /** * 设置监听 * * @param listener */
    public void setOnHomePressedListener(OnHomePressedListener listener) {
        mListener = listener;
        mRecevier = new InnerRecevier();
    }

    /** * 开始监听,注册广播 */
    public void startWatch() {
        if (mRecevier != null) {
            mContext.registerReceiver(mRecevier, mFilter);
        }
    }

    /** * 停止监听,注销广播 */
    public void stopWatch() {
        if (mRecevier != null) {
            mContext.unregisterReceiver(mRecevier);
        }
    }

    /** * 广播接收者 */
    class InnerRecevier extends BroadcastReceiver {
        final String SYSTEM_DIALOG_REASON_KEY = "reason";
        final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
        final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
        final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
                String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
                if (reason != null) {
                    Log.e(TAG, "action:" + action + ",reason:" + reason);
                    if (mListener != null) {
                        if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
                            // 短按home键
                            mListener.onHomePressed();
                        } else if (reason
                                .equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
                            // 长按home键
                            mListener.onHomeLongPressed();
                        }
                    }
                }
            }
        }
    }
}

注意到上面是采用动态注册,那采用静态注册呢?

        <receiver android:name="~~~~" >
            <intent-filter>
                <action android:name="android.intent.action.CLOSE_SYSTEM_DIALOGS" />
            </intent-filter>
        </receiver>

结果你会发现静态注册不起作用,即收不到onReceive回调。

接下来,我们需要在应用中开启监听,下面是以在Activity中根据需要在其他合适的时机注册和注销。
比如在Activity的onResume和onPause里面分别调用。

2. framework中PhoneWindowManager.java 处理
来自http://862123204-qq-com.iteye.com/blog/1888532
想要完全监听home键需要在framework层去处理。
/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
里面去修改private void handleLongPressOnHome() 这个方法。

private void handleLongPressOnHome() {
        // We can't initialize this in init() since the configuration hasn't been loaded yet.
        if (mLongPressOnHomeBehavior < 0) {
            mLongPressOnHomeBehavior
                    = mContext.getResources().getInteger(R.integer.config_longPressOnHomeBehavior);
            if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
                    mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
                mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
            }
        }

        if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
            performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);

            // Eat the longpress so it won't dismiss the recent apps dialog when
            // the user lets go of the home key
            mHomeLongPressed = true;
        }

        if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
            showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
        } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
            try {
                IStatusBarService statusbar = getStatusBarService();
                if (statusbar != null) {
                    statusbar.toggleRecentApps();
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "RemoteException when showing recent apps", e);
                // re-acquire status bar service next time it is needed.
                mStatusBarService = null;
            }
        }
    }

你可能感兴趣的:(android,监听Home键)