【android开发】手机应用管理器的实现之实现软件加锁(四)

之前几篇文章我们介绍了如何去获取手机应用程序列表,已经实现对应用程序的一些操作:运行、卸载、分享。这个三个功能相对是比较简单,对于如何实现对一个应用程序加锁,这个相对复杂一点。在一些情况下,我们想对一个软件加锁,来保护我们的隐私或者增加安全,比如支付宝、银行软件,这些软件加锁都是有必要。前一段时间一直忙于项目,没对博客进行跟进,今天我们将介绍一下如何实现软件加锁。大家先看看实现的效果图(我们以加锁UC为例):

          UC之前显示没有加锁状态                                                     选择加锁UC                                                          运行UC显示验证页面

       

一、实现流程:

首先我们将要加锁的应用程序放到数据库中,然后开启一个服务监听栈顶应用程序,将当前栈顶应用程序与数据库加密应用程序进行匹配,匹配成功,则弹出身份验证页面。

我们需要注意的是身份验证通过之后,不能重复出现验证密码页面,这个需要一些逻辑上的判断。

将要加锁的应用程序存放到数据库中:

String itemPackageName = item.getPackageName();
			String pwd = preferencesPwd.getString("pwd", "");
			if(tv_app_lock.getText().equals("加锁")){
				if(TextUtils.isEmpty(pwd)){
					setPassWord(itemPackageName);
				}else{
					handleDB.add(itemPackageName);
					Toast.makeText(MainActivity.this, "加锁成功", Toast.LENGTH_SHORT).show();
				}
			}else if(tv_app_lock.getText().equals("解锁")){
				unLock(itemPackageName);
			}
			
			adapter.notifyDataSetChanged();


开启服务,用于监听栈顶:

 // 得到当前运行的任务栈,参数就是得到多少个任务栈,1就是只拿一个任务栈  
	                    // 对应的也就是正在运行的任务栈啦 ,注意别忘了在清单文件中添加获取的权限
						List<RunningTaskInfo> runTaskInfos = 
								activityManager.getRunningTasks(1);
						//拿到当前运行的任务栈 
						RunningTaskInfo runningTaskInfo = runTaskInfos.get(0);
						//拿到要运行的Activity的包名
						String runningpackageName = runningTaskInfo.topActivity.getPackageName();
						//判断监听的运行包是否加锁
						if(handleDB.find(runningpackageName)){
							runningApp = runningpackageName;
							//解决反复出现验证页面BUG:
							//如果runningApp.equals(lastRunningApp)=true
							//则说明当前栈顶运行的程序已经解锁了
							if((runningApp.equals(lastRunningApp)) == false){
								intentLockAppActivity.putExtra("packageName", runningpackageName);
								intentLockAppActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
								startActivity(intentLockAppActivity);
							}
						}


监听到要加锁的程序,弹出验证页面:

String input = etInputPwd.getText().toString().trim();
		preferences = getSharedPreferences("passWord", MODE_PRIVATE);
		passWord = preferences.getString("pwd", "");
        if(TextUtils.isEmpty(input))  
        {  
            Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show();  
        }  
        else if(passWord.equals(input))  
        { 
        	WatchAppService.lastRunningApp = WatchAppService.runningApp;//这里赋值,终于解决了反复弹出验证页面的BUG
            finish();  
        }  
        else  
        {  
            Toast.makeText(this, "密码错误", Toast.LENGTH_SHORT).show();
            etInputPwd.setText("");//置空
        }  


弹出自定义软键盘:

@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		//这样是在触摸到控件时,软键盘才会显示出来
		int inputback = etInputPwd.getInputType();  
		etInputPwd.setInputType(InputType.TYPE_NULL);  
        new KeyboardUtil(this, this, etInputPwd).showKeyboard();  
        etInputPwd.setInputType(inputback); 
		return false;
	}
自定义软件盘的实现这里将不再细说,具体请参考先前文章http://blog.csdn.net/acrambler/article/details/13020057

第一次进行加锁,会要求先设置密码:

//设置密码
    public void setPassWord(final String itemPackageName){
    	 new AlertDialog.Builder(this).setTitle("设置安全锁密钥").setIcon(R.drawable.ic_setting_pwd)
    	.setView(viewSetPwd)
    	.setPositiveButton("确定", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				if((etPwd1.getText().toString()).equals(etPwd2.getText().toString())){
					if(TextUtils.isEmpty(etPwd1.getText().toString()) | TextUtils.isEmpty(etPwd2.getText().toString())){
						Toast.makeText(MainActivity.this, "密码不能为空", Toast.LENGTH_SHORT).show();
						boolean isVisible = false;
						dialogView(dialog,isVisible);
					}else{
						editor.putString("pwd", etPwd1.getText().toString());
						editor.commit();
						handleDB.add(itemPackageName);
						Toast.makeText(MainActivity.this, "密码设置成功", Toast.LENGTH_SHORT).show();
						Toast.makeText(MainActivity.this, "加锁成功", Toast.LENGTH_SHORT).show();
						boolean isVisible = true;
						dialogView(dialog,isVisible);
					}
				}else{
					etPwd1.setText("");
					etPwd2.setText("");
					Toast.makeText(MainActivity.this, "两次密码不相同", Toast.LENGTH_SHORT).show();
					boolean isVisible = false;
					dialogView(dialog,isVisible);
				}
			}
		})
		.setNeutralButton("重置", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				etPwd1.setText("");
				etPwd2.setText("");
				boolean isVisible = false;
				dialogView(dialog,isVisible);
			}
		})
		.setNegativeButton("取消", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				boolean isVisible = true;
				dialogView(dialog,isVisible);
			}
		} )
		.create().show();
    	 }


我们设置了长按进行重新设置密码:

@Override
    public boolean onLongClick(View v) {
    	// TODO Auto-generated method stub
    	switch (v.getId()) {
		case R.id.ll_app_lock:
			String stringPwd = preferencesPwd.getString("pwd", "");
			if(TextUtils.isEmpty(stringPwd)){
				//没有首次设置密码,长按无效
			}else{
				changePwd();
			}
			break;
		default:
			break;
		}
    	return true;
    }  


在清单文件里面别忘了添加:

<activity android:name="com.xh.ui.LockAppActivity"
            android:excludeFromRecents="true"
            android:theme="@style/AppThemeBlack">
        </activity>
        <!-- android:persistent="true" 将服务设置为系统服务,防止被系统意外回收-->
        <service 
            android:persistent="true"
            
            android:name="com.xh.service.WatchAppService"/>


上面就是主要代码,现在我们发现其实实现起来也是很简单的。


由于这次代码比较多,我就不全部贴出来了,我把链接发给大家,可以下载源码。

总结:到此这个手机应用管理器就做完了,当然了还有很多bug存在,一些逻辑考虑的还不够完整,这个大家可以运行看看,欢迎一起交流。对于附带的资源下载,本人都是运行后没有问题才上传的,如果你无法运行,一般都是配置问题,有问题可以在评论中交流,在资源处评论,无法和大家进行交流。欢迎大家继续关注……


【android开发】手机应用管理器的实现(完整版)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章