Android4.4 灭屏kill第三方app

来源:互联网 发布:微信支付服务器端php 编辑:程序博客网 时间:2024/06/08 11:53

在android4.4上添加功能当手机短按power键,灭屏的时候。kill三方的app进程。

在我之前的博客中分析过,按键处理,会从InputManager的native层,先到PhoneWindowManager的interceptKeyBeforeQueueing函数,先对按键进行处理,比如power键,会禁止把这Event传给应用。

下来我们来看下源码实现:

@Override    public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {..........        int result;        if ((isScreenOn && !mHeadless) || (isInjected && !isWakeKey)) {            // When the screen is on or if the key is injected pass the key to the application.            result = ACTION_PASS_TO_USER;        } else {            // When the screen is off and the key is not injected, determine whether            // to wake the device but don't pass the key to the application.            result = 0;            if (down && isWakeKey && isWakeKeyWhenScreenOff(keyCode) && !mRejectShortPressPowerKey) {                result |= ACTION_WAKE_UP;sendBootCompleted();//新加,杀了进程之后,起开的时候发一个开机广播,防止有些应用是根据这个广播启动的            }        }...........            case KeyEvent.KEYCODE_POWER: {                result &= ~ACTION_PASS_TO_USER;                if (down) {                    mImmersiveModeConfirmation.onPowerKeyDown(isScreenOn, event.getDownTime(),                            isImmersiveMode(mLastSystemUiFlags));                    if (isScreenOn && !mPowerKeyTriggered                            && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {                        mPowerKeyTriggered = true;                        mPowerKeyTime = event.getDownTime();                        interceptScreenshotChord();                    }                    ITelephony telephonyService = getTelephonyService();                    boolean hungUp = false;                    if (telephonyService != null) {                        try {                            if (telephonyService.isRinging()) {                                // Pressing Power while there's a ringing incoming                                // call should silence the ringer.                                telephonyService.silenceRinger();                            } else if ((mIncallPowerBehavior                                    & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0                                    && telephonyService.isOffhook()) {                                // Otherwise, if "Power button ends call" is enabled,                                // the Power button will hang up any current active call.                                hungUp = telephonyService.endCall();                            }                        } catch (RemoteException ex) {                            Log.w(TAG, "ITelephony threw RemoteException", ex);                        }                    }                    Log.i(TAG, "PowerKey down, isScreenOn = " + isScreenOn);                    interceptPowerKeyDown(!isScreenOn || hungUp                            || mVolumeDownKeyTriggered || mVolumeUpKeyTriggered);                } else {                    Log.i(TAG, "PowerKey up");                    mPowerKeyTriggered = false;                    cancelPendingScreenshotChordAction();                    if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {                        result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;                        KillProcess();//到kill进程的函数                    }                    mPendingPowerKeyUpCanceled = false;                }                break;            }........}

代码中在返回result的标志位有ACTION_GO_TO_SLEEP的时候,开启kill进程,返回ACTION_WAKE_UP的时候,发送开机广播(防止一些应用根据开机广播启动)


至于这个goToSleep和wakeUp的处理,and4.4和5.1有差别。4.4是InputManager的native层根据PhoneWindowManager返回的flag,然后在native层去调PowerManagerService的goToSleep和wakeup函数。而5.1之后就直接在PhoneWindowManager中去调PowerManagerService的这两个函数。没有在native层绕了一把。


下面我们再看下killProcess这个函数:

    private void sendBootCompleted() {//发送开机广播        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED);        mContext.sendBroadcast(intent);    }    private void KillProcess() {        List<ActivityManager.RunningAppProcessInfo> appProcessList = null;        appProcessList = mActivityManager.getRunningAppProcesses();//获取运行的app列表        for (ActivityManager.RunningAppProcessInfo appProcessInfo : appProcessList) {            int pid = appProcessInfo.pid;            int uid = appProcessInfo.uid;            String processName = appProcessInfo.processName;    PackageManager pm = mContext.getPackageManager();    try {        ApplicationInfo appinfo = pm.getApplicationInfo(processName, 0);//获取applicationinfo    boolean isSystemApp = (appinfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1;//判断是否系统应用        if (!isSystemApp) {        Log.d(TAG, "process '" + processName + "' will be killed");                    mActivityManager.forceStopPackage(processName);        }    } catch(NameNotFoundException e) {        Log.e(TAG, "can not find processName:" + processName);    }        }    }



1 0