许多安全软件都提供了程序锁服务,打开加锁的程序时必须正确输入密码才能够进入程序,那么如何实现程序锁呢?
程序锁基本原理就是监控Activity的任务栈,核心方法如下:
private void appLock() {
// TODO Auto-generated method stub
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
ActivityManager am=(ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningTaskInfo> runningTasks = am.getRunningTasks(1);//获取最新的任务栈
RunningTaskInfo runningTaskInfo = runningTasks.get(0);//最新打开的任务栈
//任务栈中获取顶部activity
String packname = runningTaskInfo.topActivity.getPackageName();
//判断是否加锁,allLockApp存储着所有加锁的app的包名
if (allLockApp.contains(packname)) {
//启动密码输入界面
Intent enterpass = new Intent(getApplicationContext(),EnterPassword.class);
enterpass.putExtra("packname", packname);
enterpass.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(enterpass);
} else {
//什么也不做
}
SystemClock.sleep(50);//每隔50ms监控一次任务栈
}
}
}).start();
}
通过这个方法可以监控每一个app的启动,上述的代码只是简单呈现的监控方法,它的内部逻辑还需要修改(按上述代码,当你在一个加锁app中停留时,会不断弹出密码输入界面),具体的修改这里就不说了。当然要做一个完善的程序锁还要记得对锁屏和开屏时的广播进行监控,并在相应的广播接收者中执行任务栈监控。
下面的代码就是一个完善的程序锁Service
public class AppLockService extends Service{
private LockDbTools db;
private boolean flag;
private ActivityManager am;
private LockBroadcast receiver;
private String pass="";
private List<String> allLock=new ArrayList<String>();
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
initReceiver();
initData();
Toast.makeText(this, "程序锁开启", 0).show();
appLock();
}
private void initData() {
// TODO Auto-generated method stub
db=new LockDbTools(this);
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
allLock=db.getAll();
}
}).start();
//注册内容观察者,实时更新所监控的app
ContentObserver observer=new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
// TODO Auto-generated method stub
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (new Object()) {
allLock=db.getAll();
}
}
}).start();
super.onChange(selfChange);
}
};
getContentResolver().registerContentObserver(AppLockDbConstans.uri, true, observer);
}
private void initReceiver() {
am=(ActivityManager) getSystemService(ACTIVITY_SERVICE);
receiver=new LockBroadcast();
IntentFilter filter=new IntentFilter("com.example.lockapp");
filter.addAction(Intent.ACTION_SCREEN_OFF);// 锁屏
filter.addAction(Intent.ACTION_SCREEN_ON);// 解锁
registerReceiver(receiver, filter);
}
private void appLock() {
// TODO Auto-generated method stub
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
flag=true;
while(flag){
List<RunningTaskInfo> runningTasks = am.getRunningTasks(1);//获取最新的任务栈
RunningTaskInfo runningTaskInfo = runningTasks.get(0);//最新打开的任务栈
//任务栈中获取顶部activity
String packname = runningTaskInfo.topActivity.getPackageName();
//判断
//非常关键的一步,注意第一个判断条件
if(!packname.equals("com.example.activity")&&!pass.equals(packname))
pass="";
if (allLock.contains(packname)) {
//是否是加锁的,true
if(!TextUtils.equals(pass, packname))
{
Intent enterpass = new Intent(getApplicationContext(),EnterPassword.class);
enterpass.putExtra("packname", packname);
enterpass.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(enterpass);
}
} else {
//什么也不做
}
SystemClock.sleep(50);//每个50毫秒 狗监控任务栈
}
}
}).start();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
flag=false;
unregisterReceiver(receiver);
Toast.makeText(this, "程序锁关闭", 0).show();
}
//监听锁屏的广播
private class LockBroadcast extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals("com.example.lockapp"))
pass=intent.getStringExtra("packname");
else
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
flag=false;
else
if(intent.getAction().equals(Intent.ACTION_SCREEN_ON))
{
appLock();
pass="";
}
}
}
}