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


    今天源码下载



  • 相关阅读:
    多级指针类型
    核心转储(core dump)
    地址总线
    eda soa
    QT信号槽简易分析_如何查看与分析QT的源码实现
    The Meta-Object System Signals & Slots 信号槽机制
    可重入 threadsafe reentrant nonreentrant
    秘钥文件
    服务启动基本
    格言
  • 原文地址:https://www.cnblogs.com/pangblog/p/3366117.html
Copyright © 2011-2022 走看看