Android 5.0 避免重复启动KeyguardService导致系统报错

在android5.0以后,引入了多用户的概念,当我们在第三方服务中调用启动系统相关的服务(如:KeyguardService)时,如果仍然用bindService方式进行启动,

在系统进行用户切换或者切换访客模式等操作时会导致重复启动系统服务 KeyguardService,从而使得系统崩溃报错。

故需要利用bindServiceAsUser方式进行替换来实现绑定服务的调用方式。

在 frameworks\base\policy\src\com\android\internal\policy\impl\keyguard\KeyguardServiceDelegate.java 类中有绑定KeyguardService的代码,

其也是利用bindServiceAsUser方式来实现获取KeyguardService的实例。


tips:在Service中启动activity时也需要用startActivityAsUser(intent,UserHandle.CURRENT_OR_SELF);的方式进行activity的启动,否则无法成功启动相关activity。


代码如下:

import com.android.internal.policy.IKeyguardService;
import android.app.IProcessObserver;
import android.app.ActivityManagerNative;


    private KeyguardManager.KeyguardLock mLock;
    private KeyguardManager mKeyguardManager;
    private TelephonyManager mTelemanager;
    private PowerManager.WakeLock mWakeLock;
    private PowerManager mPowerManager;
    private IKeyguardService mKeyguardService;
    

     @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "FpService $$$$ 444 $$$$ onCreate BOOT_COMPLETED = "
                + BOOT_COMPLETED);
        mContext = this;
        mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        mLock = mKeyguardManager.newKeyguardLock("KeyguardLock");

        mTelemanager = (TelephonyManager) getSystemService(Service.TELEPHONY_SERVICE);
        mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        // bind to KeyguardService
        bindService(this);
        
        if(!FpControllerNative.S_SDK_ONLY){
            try {
            ActivityManagerNative.getDefault().registerProcessObserver(
                    new IProcessObserver.Stub() {
                        @Override
                        public void onForegroundActivitiesChanged(int pid,
                                int uid, boolean foregroundActivities) {
                            synchronized (lock) {
                                Log.d(DataUtil.TAG_LOG, TAG
                                        + " onForegroundActivitiesChanged pid = "
                                        + pid + " --uid: " + uid
                                        + " isForegroundAct: " + foregroundActivities);
                                if (foregroundActivities) {
                                    PackageManager pm = getPackageManager();
                                    mForegroundPkgs = pm.getPackagesForUid(uid);
                                    mCurrentPid = pid;
                                    mHandler.removeCallbacks(mShowPwdRunnable);
                                    // the delay time must need because of some APP
                                    // has a activity jump, if not delay time may be can't
                                    // locked the APP.(etc. MeiYanCamera)
                                    mHandler.postDelayed(mShowPwdRunnable,
                                            SHOW_PASSWORD_ACTIVITY_DELAY);
                                } else {
                                    mHandler.removeCallbacks(mShowPwdDelayRunnable);
                                    mHandler.postDelayed(mShowPwdDelayRunnable,
                                            UNMATCH_DIALOG_NORMAL_TIMEOUT);
                                }
                            }
                        }

                        @Override
                        public void onProcessStateChanged(int pid, int uid,
                                int importance) {
                            Log.d(TAG, "onProcessStateChanged pid = " + pid
                                    + ":" + uid + ":" + importance);
                        }

                        @Override
                        public void onProcessDied(int pid, int uid) {
                            Log.d(TAG, "onProcessDied pid = " + pid + ":" + uid);
                        }
                    });
        } catch (RemoteException e) {
            Log.d(TAG, " FpService RemoteException occurs, " + e);
        }
      }
    }
    
        @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "FpService onDestroy");
        mLock.reenableKeyguard();
        unbindService(mKeyguardConnection);
    }
    
    public void bindService(Context context) {
        Intent intent = new Intent();
        intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
        // use the 'bindServiceAsUser' to replace the 'bindService' if the android version after 5.0
        // because of support the multiple user in android.
        //if (!context.bindService(intent, mKeyguardConnection, Context.BIND_AUTO_CREATE)) {
        if (!context.bindServiceAsUser(intent, mKeyguardConnection, Context.BIND_AUTO_CREATE,
                UserHandle.OWNER)) {
            Log.v(DataUtil.TAG_LOG, TAG + " ** bindService: can't bind to "
                + KEYGUARD_CLASS);
        } else {
            Log.v(DataUtil.TAG_LOG, TAG + " ** bindService started");
        }
    }
    
    private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.v(DataUtil.TAG_LOG, TAG + " ** Keyguard connected (yay!)");
            mKeyguardService = IKeyguardService.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.v(DataUtil.TAG_LOG, TAG + " ** Keyguard disconnected (boo!)");
            mKeyguardService = null;
        }
    };
    
    public boolean unLock(boolean  wakeupLock) {
        Log.d(TAG, " unLock before keyguardDone");
        try {
            if(!wakeupLock){
               mKeyguardService.keyguardDone(false, true);
            }else{
               mKeyguardService.fpKeyguardDone(false,true);
            }
            
        } catch (RemoteException e) {
            Log.e(TAG, " unLock occurs RemoteException when keyguardDone" + e);
        }
        // mKeyguardManager.dismissKeyguard();
        return true;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值