1、接上文,我们锁定了UC浏览器,现在打开设置中心,关闭程序锁服务然后再打开程序锁服务:
目的是让看门狗服务关闭后再重新启动,使得tempStopProtectPacknames清空。
然后按HOME键回到手机桌面,启动UC浏览器,弹出输入密码框:
输入正确密码后点确定,显示的并不是UC浏览器的界面,而是:
也就是刚刚在设置中心的界面。
问题原因:activity任务栈的问题。由于在启动UC浏览器前是按HOME键将安全卫士隐藏起来的,但是安全卫士的任务栈还在,并且处于栈顶。密码输入框其实是安全卫士的activity,当输入正确的密码后,密码输入框调用finish将activity移出了栈顶,便会显示安全卫士任务栈的上一个activity,也就是刚刚的“设置中心”页面。
解决方案:将密码输入框的activity放在单独的任务栈中:
<activity android:name=".EnterPswdActivity" android:launchMode="singleInstance"/>
解决方案:将密码输入框的activity排除在最近列表里显示:
<activity android:name=".EnterPswdActivity" android:launchMode="singleInstance" android:excludeFromRecents="true"/>正确显示效果:
3、用户锁屏后重新打开锁定的程序,应该要求重新输入密码。
解决方案:设置广播接受器
为WatchDogService创建一个内部类:
/** * 锁屏清空“临时停止保护列表” */ public class LockScreenReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { tempStopProtectPacknames.clear(); } }在xml中添加:
<receiver android:name=".service.WatchDogService$LockScreenReceiver"> <intent-filter> <action android:name="android.intent.action.SCREEN_OFF"/> </intent-filter> </receiver>实际测试并没有产生预期效果,书中说是android的一个bug,需要动态注册来解决:
在WatchDogService的onCreate中添加:
//动态注册锁屏的广播接受者 IntentFilter filter = new IntentFilter(); filter.setPriority(1000); filter.addAction(Intent.ACTION_SCREEN_OFF); receiver = new LockScreenReceiver(); registerReceiver(receiver, filter);在onDestroy中调用unregisterReceiver(receiver);反注册。
WatchDogService的完整代码:
package com.example.mobilesafe.service; import android.app.ActivityManager; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.util.Log; import com.example.mobilesafe.EnterPswdActivity; import com.example.mobilesafe.db.AppLockDao; import com.example.mobilesafe.engine.IService; import java.util.ArrayList; import java.util.List; /** * Created by sing on 14-1-16. * desc: */ public class WatchDogService extends Service { public static final String TAG = "WatchDogService"; boolean flag; private Intent pswdIntent; private List<String> lockPacknames; private List<String> tempStopProtectPacknames; private AppLockDao dao; private MyObserver observer; private MyBinder binder; private LockScreenReceiver receiver; public IBinder onBind(Intent intent) { binder = new MyBinder(); return binder; } private class MyBinder extends Binder implements IService { @Override public void callTempStopProtect(String packname) { tempStopProtect(packname); } } @Override public void onDestroy() { flag = false; getContentResolver().unregisterContentObserver(observer); observer = null; unregisterReceiver(receiver); super.onDestroy(); } @Override public void onCreate() { //注册内容观察者 Uri uri = Uri.parse("content://com.example.mobilesafe.applock/"); observer = new MyObserver(new Handler()); getContentResolver().registerContentObserver(uri, true, observer); //动态注册锁屏的广播接受者 IntentFilter filter = new IntentFilter(); filter.setPriority(1000); filter.addAction(Intent.ACTION_SCREEN_OFF); receiver = new LockScreenReceiver(); registerReceiver(receiver, filter); super.onCreate(); dao = new AppLockDao(this); flag = true; lockPacknames = dao.findAll(); tempStopProtectPacknames = new ArrayList<String>(); pswdIntent = new Intent(this, EnterPswdActivity.class); //服务没有任务栈,如果要开启一个在任务栈中运行的activity,需要为其创建一个任务栈 pswdIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); new Thread() { @Override public void run() { while (flag) { ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); //获取当前正在栈顶运行的activity ActivityManager.RunningTaskInfo taskInfo = am.getRunningTasks(1).get(0); String packname = taskInfo.topActivity.getPackageName(); Log.i(TAG, packname); if (tempStopProtectPacknames.contains(packname)) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } continue; } pswdIntent.putExtra("packname", packname); if (lockPacknames.contains(packname)) { startActivity(pswdIntent); } try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } public void tempStopProtect(String packname) { tempStopProtectPacknames.add(packname); } private class MyObserver extends ContentObserver { public MyObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange) { lockPacknames = dao.findAll(); super.onChange(selfChange); } } /** * 锁屏清空“临时停止保护列表” */ public class LockScreenReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { tempStopProtectPacknames.clear(); } } }