android的程序锁
来源:互联网 发布:医院药房软件系统 编辑:程序博客网 时间:2024/06/16 11:19
程序锁
分析:
- 循环获得任务栈中的topActivity 以包名的形式判断是否使用程序锁(新线程)
- 如果一个应用程序使用程序锁,则在开启的时候会首先进入一个输入密码的界面
- 输入界面 需要显示是因为哪个应用程序才调用的程序锁
- 将需要使用程序锁的应用程序获取出来,存储到集合中,方便快速调用
- 使用内容观察者的方式,得知数据库修改,重新获得内存中的应用程序集合
- 以广播接收者的方式,注册临时广播接收者。当应用程序锁屏或停止服务的时 做相应操作
- 在输入界面点击返回,会回到桌面,并将输入界面关闭
// 声明开启黑名单拦截显示服务的意图对象
private Intent callSmsSafeIntent ;
watchDogIntent = new Intent( this, WatchDogService.class );
开启服务
startService(watchDogIntent);
程序锁增删查业务类
public class ApplockDao {
private ApplockDBOpenHelper helper;
private Context context;
public ApplockDao(Context context) {
helper = new ApplockDBOpenHelper(context);
this.context = 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();
// 向外大吼一声数据库的内容变化了。
Uri uri = Uri.parse("content://com.itheima.mobilesafe.applock");
context.getContentResolver().notifyChange(uri, null);
}
/**
* 删除锁定包名 希望当数据库的内容发生变化的时候,服务能够知道数据库的内容发生了变化
* @param packname
* 包名
*/
public void delete(String packname) {
SQLiteDatabase db = helper.getWritableDatabase();
db.delete( "applock", "packname=?" , new String[] { packname });
db.close();
// 向外大吼一声数据库的内容变化了。
Uri uri = Uri.parse("content://com.itheima.mobilesafe.applock");
context.getContentResolver().notifyChange(uri, null);
}
/**
* 查询某个包名是否需要锁定
* @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;
}
/**
* 获取所有的被锁定应用程序的包名。
*
* @return
*/
public List<String> getLockedPackNames() {
// 所有被锁定的包名集合
List<String> lockedPacknames = new ArrayList<String>();
// 获取只读的数据库
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.query( "applock", new String[]{"packname" }, null,
null, null , null, null);
while (cursor.moveToNext()) {
String packname = cursor.getString(0);
lockedPacknames.add(packname);
}
cursor.close();
db.close();
return lockedPacknames;
}
程序锁服务
public class WatchDogService extends Service {
// 获得进程管理器
private ActivityManager am;
// 程序锁数据库工具类对象
private ApplockDao dao;
// 存放所有被锁定的应用程序的包名
private List<String> lockedPackNames;
private Intent intent;
// 定义停止程序锁的标记
private boolean flag ;
// 临时停止保护的包名
private String tempStopProtectPackname;
private InnerReceiver receiver;
private ScreenlockReceiver lockReceiver;
private MyDataObserver observer;
public void onCreate() {
super.onCreate();
dao = new ApplockDao(this);
// 查询所有需要使用程序锁的应用程序
lockedPackNames = dao .getLockedPackNames();
// 对进程管理器进行初始化
am = (ActivityManager) getSystemService(ACTIVITY_SERVICE );
// 定义意图对象 跳转到输入密码界面
intent = new Intent(WatchDogService.this, EnterPwdActivity.class );
// 如果在服务中开启一个界面,那么必须设置一个Flags 表示在当前任务栈下开启
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// 注册广播接收者
// 停止服务的广播接收者
receiver = new InnerReceiver();
registerReceiver( receiver, new IntentFilter(
"com.itheima.mobilesafe.stopprotect" ));
// 屏幕锁定的广播接收者
lockReceiver = new ScreenlockReceiver();
registerReceiver( lockReceiver, new IntentFilter(
Intent. ACTION_SCREEN_OFF));
// 注册内容观察者
// 在程序锁数据库增删方法中发送这个观察信息
Uri uri = Uri.parse("content://com.itheima.mobilesafe.applock");
observer = new MyDataObserver(new Handler());
getContentResolver().registerContentObserver(uri, false, observer );
new Thread() {
public void run() {
flag = true ;
while (flag ) {
// getRunningTasks(1) 获取任务栈 参数为 最多可以获得多少任务栈
RunningTaskInfo runningTaskInfo = am.getRunningTasks(1)
.get(0);
// 获得栈顶activity的包名
String packname = runningTaskInfo.topActivity
.getPackageName();
if (lockedPackNames.contains(packname)) {
if (packname.equals(tempStopProtectPackname )){
//第一进入输入界面的时候,tempStopProtectPackname对象还没有初始化,即为空
} else {
// 在意图中添加数据
intent.putExtra("packname" , packname);
startActivity( intent);
}
}
// 延时操作
SystemClock. sleep(30);
}
}
}.start();
}
/**
* 服务停止时 关闭两个广播接收者 一个内容观察者
*/
public void onDestroy() {
super.onDestroy();
flag = false ;
//取消临时广播接收者
unregisterReceiver( receiver);
receiver = null ;
unregisterReceiver( lockReceiver);
lockReceiver = null ;
//取消内容观察者
getContentResolver().unregisterContentObserver( observer);
observer = null ;
}
/**
* 自定义停止保护广播
*
* @author gj
*/
private class InnerReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
tempStopProtectPackname = intent.getStringExtra("packname" );
System. out.println("接收到了停止保护的广播事件" + tempStopProtectPackname);
}
}
/**
* 自定义屏幕锁屏广播
*
* @author gj
*/
private class ScreenlockReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
System. out.println("屏幕锁屏了" );
tempStopProtectPackname = null ;
}
}
public IBinder onBind(Intent intent) {
return null ;
}
/**
* 自定义内容观察者 观察者接受到数据库更改的信息 刷新程序锁集合
*
* @author gj
*/
private class MyDataObserver extends ContentObserver {
public MyDataObserver(Handler handler) {
super(handler);
}
public void onChange(boolean selfChange) {
System. out.println("观察者接受到了消息,数据库的内容变化了" );
// 刷新程序锁集合 让程序锁服务可以正常运行 因为 使用程序锁服务的调用的数据库信息 是缓存到内存中的
// 直接查询数据库会浪费时间 不能第一时间使用程序锁服务
lockedPackNames = dao.getLockedPackNames();
super.onChange(selfChange);
}
}
}
程序锁输入密码界面
public class EnterPwdActivity extends Activity {
//声明输入密码界面的布局文件
private TextView tv_name;
private ImageView iv_icon;
private EditText et_password;
//意图对象传过来的数据 包名
private String packname;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_enter_pwd);
//初始化布局文件
tv_name = (TextView) findViewById(R.id.tv_name );
iv_icon = (ImageView) findViewById(R.id.iv_icon );
et_password = (EditText) findViewById(R.id.et_password );
//获取意图对象中的数据
packname = getIntent().getStringExtra("packname" );
//获取包管理器
PackageManager pm=getPackageManager();
try {
//获取包信息
PackageInfo packageInfo=pm.getPackageInfo(packname , 0);
//设置图标和 应用程序名称
tv_name.setText(packageInfo.applicationInfo .loadLabel(pm));
iv_icon.setImageDrawable(packageInfo.applicationInfo .loadIcon(pm));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 点击返回键时回到桌面
*/
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);
}
/**
* 失去焦点时关闭该界面
*/
protected void onStop() {
super.onStop();
finish();
}
/**
* 确定按钮的点击事件
* @param view
*/
public void click(View view){
String password = et_password.getText().toString().trim();
if(TextUtils.isEmpty(password)){
Toast. makeText(this, "密码不能为空" , 0).show();
return;
}
//假设正确的密码是123
if("1" .equals(password)){
//告诉看门狗 不要再去保护当前的应用程序了。
//一个组件 想给另外一个组件发个信号 自定义的广播消息
Intent intent = new Intent();
intent.setAction( "com.itheima.mobilesafe.stopprotect" );
intent.putExtra( "packname", packname );
//发送自定义的广播要求停止保护 packname的应用程序
sendBroadcast(intent);
//关闭掉输入密码的界面
finish();
}
}
}
0 0
- android的程序锁
- Android程序锁的实现
- Android:程序锁功能的简单实现
- 我的Android 程序
- android 程序的生命周期
- Android程序的升级
- android md5的程序
- Android程序的退出
- android打电话的程序
- Android程序的生命周期
- Android的helloworld程序
- android程序的调试
- Android程序的反编译
- Android 程序的快捷方式
- android程序的调试
- android程序的入口
- Android 程序的组成
- Android程序的安装
- Shell脚本实践笔记-备份数据库
- JAVA之使用JDBC连接数据库-使用微软sqljdbc连接SQL Server 2005数据库
- Android中的布局属性
- 排列问题(这个格式我也是无语了)
- URI与URL、URN区别
- android的程序锁
- hadoop学习之HDFS(2):CentOS7安装完全分布式hadoop-2.7.2
- z-index属性的总结
- 删除CentOS更新后,启动项上多余的内核
- Linux kernel -- 内核对象kobject
- BZOJ3714 [PA2014]Kuglarz
- 二维背包问题 + 代码模板
- 安卓全屏设置
- MyEclipse集成Gradle