当前位置: 代码迷 >> Android >> android4.0阻截HOME
  详细解决方案

android4.0阻截HOME

热度:118   发布时间:2016-05-01 14:42:32.0
android4.0拦截HOME
android4.0拦截HOME键
        由于android4.0和2.3里面的按键机制有所不同,今天做了这样一个demo可以监听到HOME在android4.0上面,好了废话不说了直接先上原理在贴代码。
frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java这个类是android4.0里面的按键管理类,上层UI监听的所有按键都在这个里面进行分发,所以要想监听到HOME键就要在这个类里面做文章,怎么做很简单找到HOME按键在该类中的处理过程就好解决了,可以在分发HOME键的时候发送一个广播然后在应用程序里面接收该广播就可以了,这个就是原理接下来直接贴代码。
 /** [email protected]} */    @Override    public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {        final boolean keyguardOn = keyguardOn();        final int keyCode = event.getKeyCode();        final int repeatCount = event.getRepeatCount();        final int metaState = event.getMetaState();        final int flags = event.getFlags();        final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;        final boolean canceled = event.isCanceled();        if (false) {            Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="                    + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);        }        // If we think we might have a volume down & power key chord on the way        // but we're not sure, then tell the dispatcher to wait a little while and        // try again later before dispatching.        if ((flags & KeyEvent.FLAG_FALLBACK) == 0) {            if (mVolumeDownKeyTriggered && !mPowerKeyTriggered) {                final long now = SystemClock.uptimeMillis();                final long timeoutTime = mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;                if (now < timeoutTime) {                    return timeoutTime - now;                }            }            if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN                    && mVolumeDownKeyConsumedByScreenshotChord) {                if (!down) {                    mVolumeDownKeyConsumedByScreenshotChord = false;                }                return -1;            }        }        // First we always handle the home key here, so applications        // can never break it, although if keyguard is on, we do let        // it handle it, because that gives us the correct 5 second        // timeout.        if (keyCode == KeyEvent.KEYCODE_HOME) {            // If we have released the home key, and didn't do anything else            // while it was pressed, then it is time to go home!	    Intent myHomeKey = new Intent("HomeKeyDispatch");            myHomeKey.putExtra("HomeKey", "HomeKeyIntent");	    mContext.sendBroadcast(myHomeKey);            if (mHomePressed && !down) {                mHomePressed = false;                if (!canceled) {                    // If an incoming call is ringing, HOME is totally disabled.                    // (The user is already on the InCallScreen at this point,                    // and his ONLY options are to answer or reject the call.)                    boolean incomingRinging = false;                    try {                        ITelephony telephonyService = getTelephonyService();                        if (telephonyService != null) {                            incomingRinging = telephonyService.isRinging();                        }                    } catch (RemoteException ex) {                        Log.w(TAG, "RemoteException from getPhoneInterface()", ex);                    }                    if (incomingRinging) {                        Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");                    } else {                        launchHomeFromHotKey();                    }                } else {                    Log.i(TAG, "Ignoring HOME; event canceled.");                }                return -1;            }            // If a system window has focus, then it doesn't make sense            // right now to interact with applications.            WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;            if (attrs != null) {                final int type = attrs.type;                if (type == WindowManager.LayoutParams.TYPE_KEYGUARD                        || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {                    // the "app" is keyguard, so give it the key                    return 0;                }                final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;                for (int i=0; i<typeCount; i++) {                    if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {                        // don't do anything, but also don't pass it to the app                        return -1;                    }                }            }            if (down) {                if (repeatCount == 0) {                    mHomePressed = true;                } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {                    if (!keyguardOn) {                        handleLongPressOnHome();                    }                }            }            return -1;        } else if (keyCode == KeyEvent.KEYCODE_MENU) {            // Hijack modified menu keys for debugging features            final int chordBug = KeyEvent.META_SHIFT_ON;            if (down && repeatCount == 0) {                if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {                    Intent intent = new Intent(Intent.ACTION_BUG_REPORT);                    mContext.sendOrderedBroadcast(intent, null);                    return -1;                } else if (SHOW_PROCESSES_ON_ALT_MENU &&                        (metaState & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) {                    Intent service = new Intent();                    service.setClassName(mContext, "com.android.server.LoadAverageService");                    ContentResolver res = mContext.getContentResolver();                    boolean shown = Settings.System.getInt(                            res, Settings.System.SHOW_PROCESSES, 0) != 0;                    if (!shown) {                        mContext.startService(service);                    } else {                        mContext.stopService(service);                    }                    Settings.System.putInt(                            res, Settings.System.SHOW_PROCESSES, shown ? 0 : 1);                    return -1;                }            }        } else if (keyCode == KeyEvent.KEYCODE_SEARCH) {            if (down) {                if (repeatCount == 0) {                    mShortcutKeyPressed = keyCode;                    mConsumeShortcutKeyUp = false;                }            } else if (keyCode == mShortcutKeyPressed) {                mShortcutKeyPressed = -1;                if (mConsumeShortcutKeyUp) {                    mConsumeShortcutKeyUp = false;                    return -1;                }            }            return 0;        } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {            if (down && repeatCount == 0) {                showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);            }            return -1;        }        // Shortcuts are invoked through Search+key, so intercept those here        // Any printing key that is chorded with Search should be consumed        // even if no shortcut was invoked.  This prevents text from being        // inadvertently inserted when using a keyboard that has built-in macro        // shortcut keys (that emit Search+x) and some of them are not registered.        if (mShortcutKeyPressed != -1) {            final KeyCharacterMap kcm = event.getKeyCharacterMap();            if (kcm.isPrintingKey(keyCode)) {                mConsumeShortcutKeyUp = true;                if (down && repeatCount == 0 && !keyguardOn) {                    Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState);                    if (shortcutIntent != null) {                        shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                        try {                            mContext.startActivity(shortcutIntent);                        } catch (ActivityNotFoundException ex) {                            Slog.w(TAG, "Dropping shortcut key combination because "                                    + "the activity to which it is registered was not found: "                                    + KeyEvent.keyCodeToString(mShortcutKeyPressed)                                    + "+" + KeyEvent.keyCodeToString(keyCode), ex);                        }                    } else {                        Slog.i(TAG, "Dropping unregistered shortcut key combination: "                                + KeyEvent.keyCodeToString(mShortcutKeyPressed)                                + "+" + KeyEvent.keyCodeToString(keyCode));                    }                }                return -1;            }        }
粗体部分就是处理HOME键的地方我加了一个广播,在应用程序里面按下面的方式处理就能拦截到HOME键了
BroadcastReceiver  myBroadcastReceivernew= new  BroadcastReceiver() {						@Override			public void onReceive(Context context, Intent intent) {				// TODO Auto-generated method stub				String homeKey = intent.getExtras().get("HomeKey").toString();				Log.i(tag, homeKey);			}		};				IntentFilter intentFilter = new IntentFilter( "HomeKeyDispatch" );		registerReceiver( myBroadcastReceivernew , intentFilter);


这样就可以拦截到HOME键了,希望大家相互讨论!
  相关解决方案