zoukankan      html  css  js  c++  java
  • Android项目实战--手机卫士24--程序锁的实现以及逻辑

    昨天我们已经把程序全部读取出来,显示到界面上了,那今天,我们就来讲一下那个程序锁的实现啦。其实也很简单啦,我们主要就是把用户要锁定的程序放到一个表里面,然后就监听手机里面的任务栈,如果发现任务栈里面出现了,数据库里面的应用,那么就提示用户要输入密码才能打开,就是这样一个简单的流程。

    按照这个流程,那样我们肯定是先建一张表的啦,那样肯定是继承Android的SQLiteOpenHelper,然后在它的onCreate方法里面写建表语句这些的啦,如果是单独的应用,那肯定没错的,但是现在在我们的这个项目里面,那就不行了,因为我们的项目里面已经有一个数据库了,那么我们在新增表,这些操作的时候,就要特别小心啦。

    当时我们写我们的黑名单的数据库的时候,是看到这样一个方法的onUpgrade,这个方法就是在当数据库版本不同的时候执行的操作,那么在那里控制那个版本呢,那就是在构造方法里面的最后一个参数啦,那个就是控制数据库的版本的了,那么现在,我们就有一个解决办法了,我们只在把表的创建语句写在onUpgrade里面,然后修改一下数据库的版本号就可以啦!

    好,那我们就来写一下

    com.xiaobin.security.utils.DBHelper

    package com.xiaobin.security.utils;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    public class DBHelper extends SQLiteOpenHelper
    {
    
    	public DBHelper(Context context)
    	{
    		super(context, "security.db", null, 2);
    	}
    
    	@Override
    	public void onCreate(SQLiteDatabase db)
    	{
    		db.execSQL("create table blacknumber (_id integer primary key autoincrement, number varchar(20))");
    	}
    
    	@Override
    	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    	{
    		db.execSQL("create table applock (_id integer primary key autoincrement, packagename varchar(30))");
    	}
    
    }
    


    就这样,我们就可以把程序锁的表给创建出来的啦。那么我们现在肯定就要写一些这个表的增删改查操作的啦

    com.xiaobin.security.dao.AppLockDao

    package com.xiaobin.security.dao;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    
    import com.xiaobin.security.utils.DBHelper;
    
    public class AppLockDao
    {
    	private DBHelper dbHelper;
    	
    	public AppLockDao(Context context)
    	{
    		dbHelper = new DBHelper(context);
    	}
    	
    	public boolean find(String packageName)
    	{
    		boolean result = false;
    		SQLiteDatabase db = dbHelper.getReadableDatabase();
    		if(db.isOpen())
    		{
    			Cursor cursor = db.rawQuery("select packagename from applock where packagename = ? ", new String[] {packageName});
    			if(cursor.moveToNext())
    			{
    				result = true;
    			}
    			cursor.close();
    			db.close();
    		}
    		return result;
    	}
    	
    	public void add(String packageName)
    	{
    		if(find(packageName))
    		{
    			return ;
    		}
    		SQLiteDatabase db = dbHelper.getWritableDatabase();
    		if(db.isOpen())
    		{
    			db.execSQL("insert into applock (packagename) values (?)", new Object[] {packageName});
    			db.close();
    		}
    	}
    	
    	public void delete(String packageName)
    	{
    		SQLiteDatabase db = dbHelper.getWritableDatabase();
    		if(db.isOpen())
    		{
    			db.execSQL("delete from applock where packagename = ? ", new Object[] {packageName});
    		}
    	}
    	
    	public List<String> getAllPackageName()
    	{
    		SQLiteDatabase db = dbHelper.getReadableDatabase();
    		List<String> packageNames = new ArrayList<String>();
    		if(db.isOpen())
    		{
    			Cursor cursor = db.rawQuery("select packagename from applock", null);
    			while(cursor.moveToNext())
    			{
    				String packageName = cursor.getString(0);
    				packageNames.add(packageName);
    			}
    			cursor.close();
    			db.close();
    		}
    		return packageNames;
    	}
    
    }
    


    都是一些很简单的增删改查操作了,所以我就不多说啦

    好啦,写完这些之后,我们就要回到我的们界面里面写一些逻辑啦,首先,我们先给它加一个进度条,因为这个读取所有的应用是会花费挺长时间的,免得用户以为我们的应用挂掉了,所以我们就加一个进度条显示。这个进度条和我们之前说的程序管理那里的是差不多的,布局文件也差不多,所以我就不多说了,主要就是在线程加载完应用信息之后,发送一个消息给Handler,然后Handler就处理一下界面上的东西。


    那么我们现在主要就是完成锁的功能了,也就是说,当我一点击应用的条目的时候,那我就要把这个条目的包名给加入到我们的数据库里面啦,还要在界面上显示一个加锁的图标啦!当我再次点击的时候,我就要把这个锁给打开啦,也就是把这个条目从数据库里面删除啦,还要在界面上显示解锁的图标啦。

    那好,我们就来给我们上一次写好的listview加一个事件啦

    		lv_app_lock.setOnItemClickListener(new OnItemClickListener()
    		{
    
    			@Override
    			public void onItemClick(AdapterView<?> parent, View view, int position, long id)
    			{
    				//添加动画效果,动画结束后,就把锁的图片改变
    				TranslateAnimation translateAnimation = new TranslateAnimation(
    						Animation.RELATIVE_TO_SELF, 0.0f, 
    						Animation.RELATIVE_TO_SELF, 0.5f, 
    						Animation.RELATIVE_TO_SELF, 0.0f, 
    						Animation.RELATIVE_TO_SELF, 0.0f);
    				translateAnimation.setDuration(300);
    				view.startAnimation(translateAnimation);
    				
    				AppInfo info = list.get(position);
    				String packageName = info.getPackageName();
    				ImageView iv_lock = (ImageView) view.findViewById(R.id.iv_app_lock);
    				if(dao.find(packageName))
    				{
    					dao.delete(packageName);
    					lockApps.remove(packageName);
    					iv_lock.setImageResource(R.drawable.unlock);
    				}
    				else
    				{
    					dao.add(info.getPackageName());
    					lockApps.add(packageName);
    					iv_lock.setImageResource(R.drawable.lock);
    				}
    			}
    			
    		});


    大家可以看到,我们还给它加了一个动画,看起来就更动感一些了。


    写完上面的一些,我们还有一个问题要处理的,就是adapter里面,我们下拉的时候,我们还要知道那些条目的锁定情况呢,以拿做出界面上相应的变化嘛。但是问题来了,

    难道我们每生成一个条目,我们都要去用dao.find来判断一下嘛,这样子岂不是每一次都要打开关闭数据库,那样的开销是非常的大的,是严重影响性能的,所以我们绝对是不能这样做的,那么我们就可以新建一个List啦,用来存放那些已经加锁了的应用,那么我们只要在每一次生成条目的时候,我们就可以判断它是不是在list里面,而知道加锁的情况了

    		@Override
    		public View getView(int position, View convertView, ViewGroup parent)
    		{
    			AppInfo info = list.get(position);
    			if(convertView == null)
    			{
    				View view = View.inflate(AppLockActivity.this, R.layout.app_lock_item, null);
    				AppManagerViews views = new AppManagerViews();
    				views.iv_app_icon = (ImageView) view.findViewById(R.id.iv_app_lock_icon);
    				views.tv_app_name = (TextView) view.findViewById(R.id.tv_app_lock_name);
    				views.iv_app_lock = (ImageView) view.findViewById(R.id.iv_app_lock);
    				views.iv_app_icon.setImageDrawable(info.getIcon());
    				views.tv_app_name.setText(info.getAppName());
    				if(lockApps.contains(info.getPackageName()))
    				{
    					views.iv_app_lock.setImageResource(R.drawable.lock);
    				}
    				else
    				{
    					views.iv_app_lock.setImageResource(R.drawable.unlock);
    				}
    				view.setTag(views);
    				return view;
    			}
    			else
    			{
    				AppManagerViews views = (AppManagerViews) convertView.getTag();
    				views.iv_app_icon.setImageDrawable(info.getIcon());
    				views.tv_app_name.setText(info.getAppName());
    				if(lockApps.contains(info.getPackageName()))
    				{
    					views.iv_app_lock.setImageResource(R.drawable.lock);
    				}
    				else
    				{
    					views.iv_app_lock.setImageResource(R.drawable.unlock);
    				}
    				return convertView;
    			}
    		}
    		
    	}


    而我们的list的更新也在条目点击的时候做了处理啦,所以写到这里,我们就可以把这个加锁的完成的啦,剩下的就是监听任务栈里面的运行情况啦,这个我们明天再说啦

    下面把完整的activity粘出来

    com.xiaobin.security.ui.AppLockActivity

    package com.xiaobin.security.ui;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.annotation.SuppressLint;
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.Window;
    import android.view.animation.Animation;
    import android.view.animation.TranslateAnimation;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.BaseAdapter;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.ListView;
    import android.widget.TextView;
    
    import com.xiaobin.security.R;
    import com.xiaobin.security.dao.AppLockDao;
    import com.xiaobin.security.domain.AppInfo;
    import com.xiaobin.security.engine.AppInfoProvider;
    
    public class AppLockActivity extends Activity
    {
    	private ListView lv_app_lock;
    	private LinearLayout ll_load;
    	private AppLockAdapter adapter;
    	private List<AppInfo> list;
    	private AppInfoProvider provider;
    	private AppLockDao dao;
    	private List<String> lockApps;
    	
    	@SuppressLint("HandlerLeak")
    	private Handler handler = new Handler()
    	{
    		public void handleMessage(Message msg) 
    		{
    			ll_load.setVisibility(View.GONE);
    			adapter = new AppLockAdapter();
    			lv_app_lock.setAdapter(adapter);
    		}
    	};
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		requestWindowFeature(Window.FEATURE_NO_TITLE);
    		setContentView(R.layout.app_lock);
    		
    		ll_load = (LinearLayout) findViewById(R.id.ll_app_lock_progress);
    		dao = new AppLockDao(this);
    		lockApps = new ArrayList<String>();
    		lv_app_lock = (ListView) findViewById(R.id.lv_app_lock);
    		lv_app_lock.setOnItemClickListener(new OnItemClickListener()
    		{
    
    			@Override
    			public void onItemClick(AdapterView<?> parent, View view, int position, long id)
    			{
    				//添加动画效果,动画结束后,就把锁的图片改变
    				TranslateAnimation translateAnimation = new TranslateAnimation(
    						Animation.RELATIVE_TO_SELF, 0.0f, 
    						Animation.RELATIVE_TO_SELF, 0.5f, 
    						Animation.RELATIVE_TO_SELF, 0.0f, 
    						Animation.RELATIVE_TO_SELF, 0.0f);
    				translateAnimation.setDuration(300);
    				view.startAnimation(translateAnimation);
    				
    				AppInfo info = list.get(position);
    				String packageName = info.getPackageName();
    				ImageView iv_lock = (ImageView) view.findViewById(R.id.iv_app_lock);
    				if(dao.find(packageName))
    				{
    					dao.delete(packageName);
    					lockApps.remove(packageName);
    					iv_lock.setImageResource(R.drawable.unlock);
    				}
    				else
    				{
    					dao.add(info.getPackageName());
    					lockApps.add(packageName);
    					iv_lock.setImageResource(R.drawable.lock);
    				}
    			}
    			
    		});
    		
    		provider = new AppInfoProvider(this);
    		
    		initAppInfos();
    	}
    	
    	private void initAppInfos()
    	{
    		ll_load.setVisibility(View.VISIBLE);
    		new Thread()
    		{
    			@Override
    			public void run()
    			{
    				list = provider.getAllApps();
    				handler.sendEmptyMessage(0);
    			}
    		}.start();
    	}
    	
    	//===========================================================================
    	
    	private class AppLockAdapter extends BaseAdapter
    	{
    
    		@Override
    		public int getCount()
    		{
    			return list.size();
    		}
    
    		@Override
    		public Object getItem(int position)
    		{
    			return list.get(position);
    		}
    
    		@Override
    		public long getItemId(int position)
    		{
    			return position;
    		}
    
    		@Override
    		public View getView(int position, View convertView, ViewGroup parent)
    		{
    			AppInfo info = list.get(position);
    			if(convertView == null)
    			{
    				View view = View.inflate(AppLockActivity.this, R.layout.app_lock_item, null);
    				AppManagerViews views = new AppManagerViews();
    				views.iv_app_icon = (ImageView) view.findViewById(R.id.iv_app_lock_icon);
    				views.tv_app_name = (TextView) view.findViewById(R.id.tv_app_lock_name);
    				views.iv_app_lock = (ImageView) view.findViewById(R.id.iv_app_lock);
    				views.iv_app_icon.setImageDrawable(info.getIcon());
    				views.tv_app_name.setText(info.getAppName());
    				if(lockApps.contains(info.getPackageName()))
    				{
    					views.iv_app_lock.setImageResource(R.drawable.lock);
    				}
    				else
    				{
    					views.iv_app_lock.setImageResource(R.drawable.unlock);
    				}
    				view.setTag(views);
    				return view;
    			}
    			else
    			{
    				AppManagerViews views = (AppManagerViews) convertView.getTag();
    				views.iv_app_icon.setImageDrawable(info.getIcon());
    				views.tv_app_name.setText(info.getAppName());
    				if(lockApps.contains(info.getPackageName()))
    				{
    					views.iv_app_lock.setImageResource(R.drawable.lock);
    				}
    				else
    				{
    					views.iv_app_lock.setImageResource(R.drawable.unlock);
    				}
    				return convertView;
    			}
    		}
    		
    	}
    	
    	//用来优化listview的类
    	private class AppManagerViews
    	{
    		ImageView iv_app_icon;
    		TextView tv_app_name;
    		ImageView iv_app_lock;
    	}
    
    }
    


    好啦,今天我们就讲到这里,我们明天就会讲程序锁里面最重要的一总分,监听任务栈


    最后,和大家说一下

     

    为了方便大家的交流,我创建了一个群,这样子大家有什么疑问也可以在群上交流

    群号是298440981


    今天源码下载



  • 相关阅读:
    thinkphp5 tp5 命名空间 报错 Namespace declaration statement has to be the very first statement in the script
    开启 php 错误 提示 php-fpm 重启 nginx 500错误 解决办法 wdlinux lnmp 一键包 php脚本无法解析执行
    js 设置 cookie 定时 弹出层 提示层 下次访问 不再显示 弹窗 getCookie setCookie setTimeout
    php 二维数组 转字符串 implode 方便 mysql in 查询
    nginx 重启 ps -ef|grep nginx kill -HUP 主进程号
    jquery bootstrap help-block input 表单 提示 帮助 信息
    jquery 倒计时 60秒 短信 验证码 js ajax 获取
    jQuery如何获取同一个类标签的所有的值 遍历
    linux下C语言文件操作相关函数
    gcc,gdb用法
  • 原文地址:https://www.cnblogs.com/pangblog/p/3366117.html
Copyright © 2011-2022 走看看