frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java這個類是android4.0裏面的按鍵管理類,上層UI監聽的所有按鍵都在這個裏面進行分發,所以要想監聽到HOME鍵就要在這個類裏面做文章,怎麼做很簡單找到HOME按鍵在該類中的處理過程就好解决了,可以在分發HOME鍵的時候發送一個廣播然後在應用程序裏面接收該廣播就可以了,這個就是原理接下來直接貼代碼。

 /** {@inheritDoc} */
    @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鍵了,希望大家相互討論!


From:CSDN

arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()