最近想做的小新工具箱,一直想做一个程序锁,其实原理,很简单,先注册一个服务,检测手机所有进程,如果发现被加锁的app启动,马上弹出一个输入程序锁界面,但是这样子bug很多。我先做一个基本后面慢慢把bug修复。
①基本软件管理器做一个程序锁
懒得写界面了,如果你没看软件管理器,建议你看一下、
②UI界面的完成
其实也就是在软件管理器中 后面加了一个 图片 lock
③业务逻辑的完成
其实我在一直做的软件管理器,因为要修复bug,但是又不能保准哪里出错,所以在eclipse里面有个很好的标记
/*
* TODO 数据库查询
*/
eclipse 会自动在在旁边打个蓝色的标记
OK, 最后我会把我的测试项目上传上来,哎 里面有好多干货的.............
1.初始化组件
<span style="white-space:pre"> </span>/*
* TODO 修改部分
*/
ImageView iv_status;
holder.tv_name = (TextView) view.findViewById(R.id.tv_app_name);
2.数据库存储状态
因为现在手机软件那么多,所以如果加密的话,选择数据库存储比较好。
一,建立数据库帮助类
package com.example.Darkbutton.Appmanager;
import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class ApplockDBOpenHelper extends SQLiteOpenHelper {
public ApplockDBOpenHelper(Context context) {
super(context, "applcok.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
// db.execSQL("create table applock (_id integer primary key autoincrement,packname varchar(20))");
db.execSQL("create table applock (_id integer primary key autoincrement,packname varchar(20))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
二,建立数据库查询类
package com.example.Darkbutton.Appmanager;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
/**
* @author xiaoxin007 2014-12-7下午11:57:27 TODO
*/
public class ApplockDao {
private Context context;
private ApplockDBOpenHelper helper;
public ApplockDao(Context context) {
super();
this.context = context;
helper = new ApplockDBOpenHelper(context);
}
/**
* 添加一个要锁定应用程序的包名
* @param packname
*/
public void add(String packname){
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("packname", packname);
db.insert("applock", null, values);
db.close();
}
/**
* 删除一个要锁定应用程序的包名
* @param packname
*/
public void delete(String packname){
SQLiteDatabase db = helper.getWritableDatabase();
db.delete("applock", "packname=?", new String[]{packname});
db.close();
}
/**
* 查询一条程序锁包名记录是否存在
* @param packname
* @return
*/
public boolean find(String packname){
boolean result = false;
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor=db.query("applock", null, "packname=?", new String[]{packname}, null, null, null);
if(cursor.moveToNext()){
result = true;
}
cursor.close();
db.close();
return result;
}
/**
* 查询全部的包名
* @param packname
* @return
*/
public List<String> findAll(){
List<String> protectPacknames = new ArrayList<String>();
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.query("applock", new String[]{"packname"}, null,null, null, null, null);
while(cursor.moveToNext()){
protectPacknames.add(cursor.getString(0));
}
cursor.close();
db.close();
return protectPacknames;
}
}
三,使用数据库
/*
* TODO 数据库查询
*/
private ApplockDao dao;
<span style="white-space:pre"> </span>/*
* TODO 实例化
*/
dao = new ApplockDao(this);
在lock那个图标查询数据库显示 是否有锁
<span style="white-space:pre"> </span>/*
* TODO
* */
if(dao.find(appInfo.getPackname())){
holder.iv_status.setImageResource(R.drawable.lock);
}else{
holder.iv_status.setImageResource(R.drawable.unlock);
}
④ 加锁应用
利用listview长按点击事件 进行加锁........
/*
* TODO 修改部分
*/
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
// 设置点击第一个条目的时候不显示,因为不是软件
if (position == 0) {
return false;
// 以此类推
} else if (position == (userAppInfos.size() + 1)) {
return false;
} else if (position <= userAppInfos.size()) {// 用户程序
int newposition = position - 1;
appInfo = userAppInfos.get(newposition);
} else {// 系统程序
int newposition = position - 1 - userAppInfos.size() - 1;
appInfo = systemAppInfos.get(newposition);
}
ViewHolder holder=(ViewHolder) view.getTag();
if (dao.find(appInfo.getPackname())) {
dao.delete(appInfo.getPackname());
holder.iv_status.setImageResource(R.drawable.unlock);
} else {
dao.add(appInfo.getPackname());
holder.iv_status.setImageResource(R.drawable.lock);
}
return false;
}
因为在listview 中 有两个条目不是软件 所以进行判断
⑤ 监控软件
监控软件那就要一直在想就只能用服务了
首先要得到系统最近运行的程序,这时候有需要activitymanager
package com.example.Darkbutton.Appmanager;
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class WatchDogService extends Service {
private ActivityManager am;
private boolean flag;
//2.第二部 已经检测软件先了,现在用数据库去查询是否需要保护的
private ApplockDao dao;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
am=(ActivityManager)getSystemService(ACTIVITY_SERVICE);
dao=new ApplockDao(this);
flag=true;
new Thread(){
public void run() {
while (flag) {
//得到正在运行的运行task ,因为只要APP一运行就会建立一个人物栈
List<RunningTaskInfo> infos = am.getRunningTasks(1);
String packageName = infos.get(0).topActivity.getPackageName();
if (dao.find(packageName)) {
//③当需要保护的时候 蹦出来一个输入界面
Intent intent=new Intent(getApplicationContext(),EnterPwdActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
然后再设置界面中 打开他 他就会去监控了
package com.example.Darkbutton.Appmanager;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import com.example.Darkbutton.R;
import com.example.Darkbutton.SetingItem;
import com.example.Darkbutton.Utils.ServiceUtils;
public class SetingActivity extends Activity {
private SetingItem siv_watchdog;
private Intent watchIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
//程序锁设置
siv_watchdog = (SetingItem) findViewById(R.id.siv_watchdog);
watchIntent = new Intent(this, WatchDogService.class);
siv_watchdog.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (siv_watchdog.isChecked()) {
// 变为非选中状态
siv_watchdog.setChecked(false);
stopService(watchIntent);
} else {
// 选择状态
siv_watchdog.setChecked(true);
startService(watchIntent);
}
}
});
}
@Override
protected void onResume() {
super.onResume();
boolean iswatchdogServiceRunning = ServiceUtils.isServiceRunning(
SetingActivity.this,
"com.example.Darkbutton.Appmanager.WatchDogService");
siv_watchdog.setChecked(iswatchdogServiceRunning);
}
}
注意 服务要在配置文件中注册 好需要一个权限 get_Task
当用户打开了app就会弹出一个输入密码的界面 这时候我们要编写这里的逻辑
package com.example.Darkbutton.Appmanager;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.Darkbutton.R;
public class EnterPwdActivity extends Activity {
private EditText et_password;
private String packname;
private TextView tv_appname;
private ImageView iv_appicon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_pwd);
et_password = (EditText) findViewById(R.id.et_password);
tv_appname = (TextView) findViewById(R.id.tv_appname);
iv_appicon = (ImageView) findViewById(R.id.iv_appicon);
Intent intent = getIntent();
//当前要保护的应用程序包名
packname = intent.getStringExtra("packname");
PackageManager pm = getPackageManager();
try {
ApplicationInfo info = pm.getApplicationInfo(packname, 0);
tv_appname.setText(info.loadLabel(pm));
iv_appicon.setImageDrawable(info.loadIcon(pm));
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
@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);
//所有的activity最小化 不会执行ondestory 只执行 onstop方法。
}
@Override
protected void onStop() {
super.onStop();
finish();
}
public void click(View view){
String pwd = et_password.getText().toString().trim();
if(TextUtils.isEmpty(pwd)){
Toast.makeText(this, "密码不能为空", 0).show();
return;
}
//假设正确的密码是123
if("123".equals(pwd)){
//告诉看门狗这个程序密码输入正确了。 可以临时的停止保护。
//自定义的广播,临时停止保护。
// Intent intent = new Intent();
// intent.setAction("com.xiaoxin.mobilesafe.tempstop");
// intent.putExtra("packname", packname);
// sendBroadcast(intent);
finish();
}else{
Toast.makeText(this, "密码错误。。", 0).show();
}
}
}