程序锁需要实时监听应用程序,利用看门狗服务实现。首先获取到所有的任务栈,任务栈最上面的就是刚刚点击的应用,然后便利程序锁数据库,看在不在程序锁数据库中,在程序锁数据库中,就直接跳转到输入密码的界面,由于EditText会获取到焦点,点击的时候会获取到系统的键盘,需要先隐藏系统的键盘et_pwd.setInputType(InputType.TYPE_NULL);
服务不能直接跳activity,需要设置标记
//服务网activity跳转需要设置flag
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
获取任务栈需要权限
<uses-permission android:name="android.permission.GET_TASKS"></uses-permission>
注册看门狗的服务
<service android:name="com.ldw.safe.service.WatchDogService"></service>
设置密码的界面activity_set_pwd.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
style="@style/TitleStyle"
android:text="请输入隐私密码"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_lock_big"
android:layout_marginTop="20dp"
android:layout_gravity="center_horizontal"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="20dp"
/>
<Button
android:id="@+id/bt_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="确定"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:background="@drawable/desktop_button_1"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:orientation="vertical"
android:background="#22000000">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/bt_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="1" />
<Button
android:id="@+id/bt_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="2" />
<Button
android:id="@+id/bt_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="3" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/bt_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="4" />
<Button
android:id="@+id/bt_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="5" />
<Button
android:id="@+id/bt_6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="6" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/bt_7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="7" />
<Button
android:id="@+id/bt_8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="8" />
<Button
android:id="@+id/bt_9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="9" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/bt_clean_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="清空" />
<Button
android:id="@+id/bt_0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="0" />
<Button
android:id="@+id/bt_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="删除" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
看门狗服务开启的界面activity_setting.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ldw="http://schemas.android.com/apk/res/com.ldw.safe"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
style="@style/TitleStyle"
android:text="手机设置"
/>
<com.ldw.safe.view.SettingItemView
android:id="@+id/siv_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ldw:title="自动更新设置"
ldw:desc_on="自动更新已开启"
ldw:desc_off="自动更新已关闭"
/>
<com.ldw.safe.view.SettingItemView
android:id="@+id/siv_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ldw:title="电话归属地显示设置"
ldw:desc_on="电话归属地显示已开启"
ldw:desc_off="电话归属地显示已关闭"
/>
<com.ldw.safe.view.SettingClickView
android:id="@+id/scv_address_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<com.ldw.safe.view.SettingClickView
android:id="@+id/scv_address_location"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<com.ldw.safe.view.SettingItemView
android:id="@+id/siv_callsafe"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ldw:title="黑名单更新设置"
ldw:desc_on="黑名单更新已开启"
ldw:desc_off="黑名单更新已关闭"
/>
<com.ldw.safe.view.SettingItemView
android:id="@+id/siv_watch_dog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ldw:title="看门狗设置"
ldw:desc_on="看门狗已经打开"
ldw:desc_off="看门狗已经关闭"
/>
</LinearLayout>
看门狗服务的初始化逻辑文件SettingActivity.java
package com.ldw.safe.Activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import com.ldw.safe.R;
import com.ldw.safe.service.AddressService;
import com.ldw.safe.service.CallSafeService;
import com.ldw.safe.service.WatchDogService;
import com.ldw.safe.utils.ServiceStatusUtils;
import com.ldw.safe.view.SettingClickView;
import com.ldw.safe.view.SettingItemView;
/**
* 设置中心
*/
public class SettingActivity extends Activity {
private SettingItemView siv_update;//设置自动更新
private SettingItemView siv_address;//归属地
private SettingClickView scv_address_style;//归属地显示的风格
private SettingClickView scv_address_location;//初始化归属地的位置
private SettingItemView siv_callsafe;//黑名单
private SettingItemView siv_watch_dog;//看门狗
private SharedPreferences mPref;//把设置的数据保存在mPref
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
//把设置的数据保存在mPref
mPref = getSharedPreferences("config", MODE_PRIVATE);
initUpdateView();//初始化自动升级开关
initAdressView();//初始化归属地开关
initAddressStyle();//初始化归属地样式的选择
initAddressLocation();//初始化归属地出现的位置
initBlackView();//黑名单设置开关
initWatchDog();
}
/*
* 看门狗设置初始化
*/
private void initWatchDog() {
siv_watch_dog = (SettingItemView) findViewById(R.id.siv_watch_dog);
// 根据归属地服务是否运行来更新checkbox
boolean serviceRunning = ServiceStatusUtils.isServiceRunning(this,
"com.ldw.safe.service.WatchDogService");
if (serviceRunning) {
siv_watch_dog.setChecked(true);
} else {
siv_watch_dog.setChecked(false);
}
siv_watch_dog.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (siv_watch_dog.isChecked()) {
siv_watch_dog.setChecked(false);
stopService(new Intent(SettingActivity.this,
WatchDogService.class));// 停止归属地服务
} else {
siv_watch_dog.setChecked(true);
startService(new Intent(SettingActivity.this,
WatchDogService.class));// 开启归属地服务
}
}
});
}
/*
* 黑名单设置初始化
*/
private void initBlackView() {
siv_callsafe = (SettingItemView) findViewById(R.id.siv_callsafe);
// 根据归属地服务是否运行来更新checkbox
boolean serviceRunning = ServiceStatusUtils.isServiceRunning(this,
"com.ldw.safe.service.CallSafeService");
if (serviceRunning) {
siv_callsafe.setChecked(true);
} else {
siv_callsafe.setChecked(false);
}
siv_callsafe.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (siv_callsafe.isChecked()) {
siv_callsafe.setChecked(false);
stopService(new Intent(SettingActivity.this,
CallSafeService.class));// 停止归属地服务
} else {
siv_callsafe.setChecked(true);
startService(new Intent(SettingActivity.this,
CallSafeService.class));// 开启归属地服务
}
}
});
}
/*
* 初始化自动升级开关
*/
private void initUpdateView(){
siv_update = (SettingItemView)findViewById(R.id.siv_update);
//siv_update.setTitle("自动更新设置");
//获取保存的数据,判断之前选择的是开始还是关闭,初始化进入界面是否勾选
boolean autoUpdate = mPref.getBoolean("auto_update", true);
if(autoUpdate){
siv_update.setDesc("自动更新已经开启");
siv_update.setChecked(true);
}else{
siv_update.setDesc("自动更新已经关闭");
siv_update.setChecked(false);
}
siv_update.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//判断右边框的勾选状态
if(siv_update.isChecked()){
//设置不勾选
siv_update.setChecked(false);
//siv_update.setDesc("自动更新已经关闭");
//编辑mPref的值
mPref.edit().putBoolean("auto_update", false).commit();
}else{
//设置勾选
siv_update.setChecked(true);
//siv_update.setDesc("自动更新已经开启");
//编辑mPref的值
mPref.edit().putBoolean("auto_update", true).commit();
}
}
});
}
/*
* 初始化归属地开关
*/
private void initAdressView(){
siv_address = (SettingItemView) findViewById(R.id.siv_address);
//判断归属地的服务是否在运行
boolean serviceRunning = ServiceStatusUtils.isServiceRunning(this, "com.ldw.safe.service.AddressService");
//让服务的那个勾选框根据系统中是否有服务来判断是否去开启
if(serviceRunning){
siv_address.setChecked(true);
}else{
siv_address.setChecked(false);
}
siv_address.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
if(siv_address.isChecked()){
siv_address.setChecked(false);
stopService(new Intent(SettingActivity.this, AddressService.class));
}else{
siv_address.setChecked(true);
//号码归属地显示开启的时候要开启服务
startService(new Intent(SettingActivity.this, AddressService.class));
}
}
});
}
/*
* 修改号码归属地提示框的风格
*/
private void initAddressStyle(){
scv_address_style = (SettingClickView) findViewById(R.id.scv_address_style);
scv_address_style.setTitle("归属地提示框风格");
//获取保存的样式
int style = mPref.getInt("address_Style", 0);
//设置样式
scv_address_style.setDesc(items[style]);
scv_address_style.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
showSingleChooseDialog();
}
});
}
final String[] items = new String[]{"半透明", "活力橙", "卫士蓝", "金属灰", "苹果绿"};
/*
* 弹出归属地样式选择的单选框
*/
public void showSingleChooseDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
//设置选择框额logo
builder.setIcon(R.drawable.ic_launcher);
builder.setTitle("归属地提示框风格");
//获取保存的风格样式,默认为0
int style = mPref.getInt("address_Style", 0);
builder.setSingleChoiceItems(items, style,
new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
//保存选择的样式的序号
mPref.edit().putInt("address_Style", which).commit();
//点击以后对话框消失
dialog.dismiss();
//设置组合控件的文字描述
scv_address_style.setDesc(items[which]);
}
});
builder.setNegativeButton("取消", null);
builder.show();
}
/*
* 初始化归属地出现的位置
*/
private void initAddressLocation(){
scv_address_location = (SettingClickView) findViewById(R.id.scv_address_location);
scv_address_location.setTitle("归属地提示框的显示位置");
scv_address_location.setDesc("设置归属地提示框的显示位置");
scv_address_location.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//点击以后直接跳转页面
startActivity(new Intent(SettingActivity.this, DragViewActivity.class));
}
});
}
}
看门狗的服务,同时注册广播,根据屏幕的开启和关闭来启动和关闭看门狗WatchDogReceiver.java
package com.ldw.safe.service;
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.os.SystemClock;
import com.ldw.safe.Activity.EnterPwdActivity;
import com.ldw.safe.db.dao.AppLockDao;
public class WatchDogService extends Service {
private ActivityManager activityManager;
private AppLockDao dao;
private List<String> appLockInfos;
//临时停止保护的包名
private String tempStopProtectPackageName;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private class WatchDogReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("com.ldw.safe.stopprotect")){
//获取到停止保护的对象
tempStopProtectPackageName = intent.getStringExtra("packageName");
}else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
tempStopProtectPackageName = null;
// 让看门狗休息
flag = false;
}else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
//让看门狗继续干活
if(flag == false){
startWatchDog();
}
}
}
}
@Override
public void onCreate(){
super.onCreate();
dao = new AppLockDao(this);
appLockInfos = dao.findAll();
receiver = new WatchDogReceiver();
IntentFilter filter = new IntentFilter();
//停止保护
filter.addAction("com.ldw.safe.stopprotect");
//注册一个锁屏的广播,当锁屏的时候看门狗关闭
//屏幕解锁的时候看门狗打开
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
//注册广播
registerReceiver(receiver, filter);
//获取到进程管理器
activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
//首先获取到当前的任务栈
//知道任务栈最上面的任务(刚刚点击操作的任务栈)
startWatchDog();
}
//标记当前看门狗的状态,默认false
private boolean flag = false;
private WatchDogReceiver receiver;
private void startWatchDog() {
//由于看门狗一直在后台运行,子线程中操作,防止阻塞主线程
new Thread(){
public void run(){
flag = true;
//一直在后台运行
while (flag) {
//由于这个狗一直在后台运行。为了避免程序阻塞。
//获取到当前正在运行的任务栈
List<RunningTaskInfo> tasks = activityManager.getRunningTasks(1);
//获取到最上面的进程
RunningTaskInfo taskInfo = tasks.get(0);
//获取到最顶端应用程序的包名
String packageName = taskInfo.topActivity.getPackageName();
System.out.println(packageName);
//让狗休息一会
SystemClock.sleep(30);
//直接从数据库里面查找当前的数据
//这个可以优化。改成从内存当中寻找
if(appLockInfos.contains(packageName)){
// if(dao.find(packageName)){
// System.out.println("在程序锁数据库里面");
//说明需要临时取消保护
//是因为用户输入了正确的密码
if(packageName.equals(tempStopProtectPackageName)){
}else{
Intent intent = new Intent(WatchDogService.this,EnterPwdActivity.class);
/**
* 需要注意:如果是在服务里面往activity界面跳的话。需要设置flag
*/
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//停止保护的对象
intent.putExtra("packageName", packageName);
startActivity(intent);
}
}
}
};
}.start();
}
@Override
public void onDestroy(){
super.onDestroy();
flag = false;
unregisterReceiver(receiver);
receiver = null;
}
}
密码输入的逻辑文件EnterPwdActivity.java
package com.ldw.safe.Activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import com.ldw.safe.R;
import com.ldw.safe.utils.UIUtils;
public class EnterPwdActivity extends Activity implements OnClickListener {
private EditText et_pwd;
private Button bt_0;
private Button bt_1;
private Button bt_2;
private Button bt_3;
private Button bt_4;
private Button bt_5;
private Button bt_6;
private Button bt_7;
private Button bt_8;
private Button bt_9;
private Button bt_clean_all;
private Button bt_delete;
private Button bt_ok;
private String packageName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_pwd);
initUi();
}
private void initUi() {
et_pwd = (EditText) findViewById(R.id.et_pwd);
// 隐藏当前的键盘
et_pwd.setInputType(InputType.TYPE_NULL);
bt_0 = (Button) findViewById(R.id.bt_0);
bt_1 = (Button) findViewById(R.id.bt_1);
bt_2 = (Button) findViewById(R.id.bt_2);
bt_3 = (Button) findViewById(R.id.bt_3);
bt_4 = (Button) findViewById(R.id.bt_4);
bt_5 = (Button) findViewById(R.id.bt_5);
bt_6 = (Button) findViewById(R.id.bt_6);
bt_7 = (Button) findViewById(R.id.bt_7);
bt_8 = (Button) findViewById(R.id.bt_8);
bt_9 = (Button) findViewById(R.id.bt_9);
bt_ok = (Button) findViewById(R.id.bt_ok);
bt_ok.setOnClickListener(this);
bt_clean_all = (Button) findViewById(R.id.bt_clean_all);
bt_delete = (Button) findViewById(R.id.bt_delete);
// 清空
bt_clean_all.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
et_pwd.setText("");
}
});
// 删除
bt_delete.setOnClickListener(new OnClickListener() {
private String str;
@Override
public void onClick(View v) {
str = et_pwd.getText().toString();
if (str.length() == 0) {
return;
}
et_pwd.setText(str.substring(0, str.length() - 1));
}
});
bt_0.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String str = et_pwd.getText().toString();
et_pwd.setText(str + bt_0.getText().toString());
}
});
bt_1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String str = et_pwd.getText().toString();
et_pwd.setText(str + bt_1.getText().toString());
}
});
bt_2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String str = et_pwd.getText().toString();
et_pwd.setText(str + bt_2.getText().toString());
}
});
bt_3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String str = et_pwd.getText().toString();
et_pwd.setText(str + bt_3.getText().toString());
}
});
bt_4.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String str = et_pwd.getText().toString();
et_pwd.setText(str + bt_4.getText().toString());
}
});
bt_5.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String str = et_pwd.getText().toString();
et_pwd.setText(str + bt_5.getText().toString());
}
});
bt_6.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String str = et_pwd.getText().toString();
et_pwd.setText(str + bt_6.getText().toString());
}
});
bt_7.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String str = et_pwd.getText().toString();
et_pwd.setText(str + bt_7.getText().toString());
}
});
bt_8.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String str = et_pwd.getText().toString();
et_pwd.setText(str + bt_8.getText().toString());
}
});
bt_9.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String str = et_pwd.getText().toString();
et_pwd.setText(str + bt_9.getText().toString());
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_ok:
String result = et_pwd.getText().toString();
if ("123".equals(result)) {
// 如果密码正确。说明是自己人
/**
* 是自己家人。不要拦截他
*/
System.out.println("密码输入正确");
Intent intent = new Intent();
// 发送广播。停止保护
intent.setAction("com.ldw.safe.stopprotect");
// 跟狗说。现在停止保护短信
intent.putExtra("packageName", packageName);
sendBroadcast(intent);
finish();
} else {
UIUtils.showToast(EnterPwdActivity.this, "密码错误");
}
break;
}
}
@Override
public void onBackPressed() {
// 当用户输入后退健 的时候。我们进入到桌面
Intent intent = new Intent();
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.HOME");
intent.addCategory("android.intent.category.DEFAULT");
intent.addCategory("android.intent.category.MONKEY");
startActivity(intent);
}
}