当前位置:文档之家› 杨光福-手机卫士day9

杨光福-手机卫士day9

杨光福-手机卫士day9
杨光福-手机卫士day9

手机卫士

讲师:杨光福

Day9

82_程序锁的UI_48

1、参照腾讯手机管家,看一看演示软件锁功能;设置密码,启动软件试试;

2、在高级工具里面添加“程序锁”enterApplock,添加点击事件。

3、创建新的类AppLockActivity,并在功能清单文件注册;

写布局文件

标题用线性布局:

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:gravity="center_horizontal">

android:textColor="#ffffff"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="@drawable/tab_left_pressed"

android:gravity="center"

android:text="未加锁" />

android:textColor="#ffffff"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="@drawable/tab_right_default"

android:gravity="center"

android:text="已加锁" />

中间部分,显示软件的地方代码,有两个ListView;

android:id="@+id/ll_unlock"

android:visibility="gone"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="未加锁软件 xx个"/>

android:id="@+id/lv_unlock"

android:layout_width="match_parent"

android:layout_height="match_parent" >

android:id="@+id/ll_locked"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="已加锁软件 xx个"/>

android:id="@+id/lv_locked"

android:layout_width="match_parent"

android:layout_height="match_parent" >

4、初始化两个TextView和线性布局加上点击事件;

A:初始化TextView和线性布局

B:两个TextView 加上点击事件

@Override

public void onClick(View v) {

switch (v.getId()) {

case https://www.doczj.com/doc/965330709.html,_unlock:

tv_unlock.setBackgroundResource(R.drawable.tab_left_pressed);

tv_locked.setBackgroundResource(R.drawable.tab_right_default);

ll_unlock.setVisibility(View.VISIBLE);

ll_locked.setVisibility(View.GONE);

break;

case https://www.doczj.com/doc/965330709.html,_locked:

tv_unlock.setBackgroundResource(R.drawable.tab_left_default);

tv_locked.setBackgroundResource(R.drawable.tab_right_pressed);

ll_unlock.setVisibility(View.GONE);

ll_locked.setVisibility(View.VISIBLE);

break;

}

}

演示测试,看看效果;

5、未加锁模块的实现

A:初始化两个ListView

lv_unlock = (ListView) findViewById(R.id.lv_unlock);

lv_locked = (ListView) findViewById(R.id.lv_locked);

B:利用软件管理模块已经写过的工具得到系统所有的信息

//先得到安装的所有程序//建议在子线程去写

appInfos = AppInfoProvider.getAllAppInfos(this);

C:创建适配器AppLockAdapter 并自定义Item 的View

布局文件名叫list_applock_item.xml

使用相对布局比较方便

xmlns:android="https://www.doczj.com/doc/965330709.html,/apk/res/android"

android:layout_width="match_parent"

android:layout_height="wrap_content">

android:id="@+id/iv_icon"

android:layout_width="50dip"

android:layout_height="50dip"

android:src="@drawable/app"/>

android:id="@+id/tv_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:layout_toRightOf="@id/iv_icon"

android:text="软件名称"

android:textSize="20sp">

android:id="@+id/iv_status"

android:layout_width="30dip"

android:layout_height="30dip"

android:layout_alignParentRight="true"

android:layout_centerVertical="true"

android:layout_marginRight="5dip"

android:src="@drawable/lock"/>

D:在适配器的getView()方法里实例化布局文件;

View view = null;

ViewHolder holder = null;

if(convertView != null&& convertView instanceof RelativeLayout){

view = convertView;

holder = (ViewHolder) view.getTag();

}else{

view = View.inflate(getApplicationContext(), https://www.doczj.com/doc/965330709.html,yout.list_applock_item, null);

holder = new ViewHolder();

holder.iv_icon= (ImageView)

view.findViewById(R.id.iv_icon);

https://www.doczj.com/doc/965330709.html,_name= (TextView) view.findViewById(https://www.doczj.com/doc/965330709.html,_name);

view.setTag(holder);

}

AppInfo appInfo = appInfos.get(position);

holder.iv_icon.setImageDrawable(appInfo.getIcon());

https://www.doczj.com/doc/965330709.html,_name.setText(appInfo.getName());

return view;

E:设置未加锁个数

A:定义ID为tv_unlock_count、tv_locked_count初始TextView

tv_unlock_count = (TextView) findViewById(https://www.doczj.com/doc/965330709.html,_unlock_count);

tv_locked_count = (TextView) findViewById(https://www.doczj.com/doc/965330709.html,_locked_count);

B:在getCount()方法赋值;

public int getCount() {

tv_unlock_count.setText("未加锁软件:"+appInfos.size()+"个");

return appInfos.size();

}

83_创建已加锁数据_22

1、创建数据库,用户保存已加锁数据;

A:基于BlackNumberDBOpenHelper修改名称AppLockDBOpenHelper B:修改数据库名称blacknumber.db ---> applock.db

C:修改表明:改成如下

/**

* _id 主键自增长,packname 包名

*/

private String sql = "create table applock(_id integer primary key autoincrement,packname varchar(20))";

D:基于BlackNumberDao 复制改名成 AppLockDao

public class AppLockDao {

private AppLockDBOpenHelper openHelper;

public AppLockDao(Context context){

openHelper = new AppLockDBOpenHelper(context);

}

/**

* 增加一条信息

*/

public void add(String packname ){

SQLiteDatabase db = openHelper.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 = openHelper.getWritableDatabase();

db.delete("applock", "packname=?", new String[]{packname});

db.close();

}

/**

* 查询一条信息是否存在

*/

public boolean find(String packname){

boolean result = false;

SQLiteDatabase db = openHelper.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;

}

}

2、小锁上加上ID,设置点击事件

A:list_applock_item里面,小锁图标加上ID:iv_status B:初始化并且设置点击事件,并实例化AppLockDao

holder.iv_status.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

//从当前界面移除Item

appInfos.remove(position);

//把移除的Item对象对应的包名加到数据库里面

dao.add(appInfo.getPackageName());

//通知页面刷新

notifyDataSetChanged();

}

});

3、区分未加锁和已经加锁区分--未加锁的实现;

A:定义两个集合

//未加锁

private List unlockappInfos ;

//已加锁

private List lockedappInfos ;

B:数据初始化--数据区分开来

appInfos = AppInfoProvider.getAllAppInfos(this);

unlockappInfos = new ArrayList();

lockedappInfos = new ArrayList();

for(AppInfo appInfo : appInfos){

if(dao.find(appInfo.getPackageName())){

lockedappInfos.add(appInfo);

}else{

unlockappInfos.add(appInfo);

}

}

C:在适配器定义字段区分未加锁已加锁,在构造方法里传参数

/**

* true未加锁,false已加锁

*/

private boolean unlockflag = true;

public AppLockAdapter(boolean unlockflag) {

this.unlockflag = unlockflag;

}

D:在getCount()方法修改成如下:

public int getCount() {

if(unlockflag){

tv_unlock_count.setText("未加锁软件:"+unlockappInfos.size()+"个");

return unlockappInfos.size();

}else{

tv_locked_count.setText("已加锁软件:"+lockedappInfos.size()+"个");

return lockedappInfos.size();

}

}

E:在getView()处理

AppInfo appInfo = null;

if(unlockflag){

appInfo = unlockappInfos.get(position);

}else{

appInfo = lockedappInfos.get(position);

}

F:点击事件修改

if(unlockflag){

//从当前界面移除Item

unlockappInfos.remove(position);

//把移除的Item对象对应的包名加到数据库里面

dao.add(appInfo.getPackageName());

}

//通知页面刷新

notifyDataSetChanged();

4、已加锁的实现

A:初始化已加锁的适配器

lv_unlock.setAdapter(new AppLockAdapter(true));//未加锁

lv_locked.setAdapter(new AppLockAdapter(false));//已加锁

B:已加锁的点击事件

if(unlockflag){

//从当前界面移除Item

unlockappInfos.remove(position);

//把移除的Item对象对应的包名加到数据库里面

dao.add(appInfo.getPackageName());

}else{

lockedappInfos.remove(position);

dao.delete(appInfo.getPackageName());

}

运行看看演示效果

C:解决移除了,界面没有变化的问题

处理集合数据:

if(unlockflag){

//从当前界面移除Item

unlockappInfos.remove(position);

//把移除的Item对象对应的包名加到数据库里面

dao.add(appInfo.getPackageName());

lockedappInfos.add(appInfo);

}else{

lockedappInfos.remove(position);

dao.delete(appInfo.getPackageName());

unlockappInfos.add(appInfo);

}

//通知页面刷新

notifyDataSetChanged();

适配器定义成成员变量

unLockAdapter = new AppLockAdapter(true);

lockedAdapter = new AppLockAdapter(false);

lv_unlock.setAdapter(unLockAdapter);//已加锁

lv_locked.setAdapter(lockedAdapter);//未加锁

更新适配器

//通知页面刷新

// notifyDataSetChanged();

unLockAdapter.notifyDataSetChanged();

lockedAdapter.notifyDataSetChanged();

5、设置状态,如果是为加锁的话设置未加锁图片,如果是已加锁设置为加锁状态;

在getView()方法里

if(unlockflag){

holder.iv_status.setImageResource(R.drawable.lock);

appInfo = unlockappInfos.get(position);

}else{

appInfo = lockedappInfos.get(position);

holder.iv_status.setImageResource(R.drawable.unlock); }

84_程序锁动画效果的实现_20

1、设置Item的动画效果

在未加锁地方,加锁右移动画

TranslateAnimation ta = new TranslateAnimation(

Animation.RELATIVE_TO_SELF, 0,

Animation.RELATIVE_TO_SELF, 1.0f,

Animation.RELATIVE_TO_SELF, 0,

Animation.RELATIVE_TO_SELF, 0);

ta.setDuration(500);

view.startAnimation(ta);

左移动画

TranslateAnimation ta = new TranslateAnimation(

Animation.RELATIVE_TO_SELF, 0,

Animation.RELATIVE_TO_SELF, -1.0f,

Animation.RELATIVE_TO_SELF, 0,

Animation.RELATIVE_TO_SELF, 0);

ta.setDuration(500);

2、解决动画移动问题

导的原因,动画没有开始播放,界面就刷新了。

动画播放需要时间的,动画没有播就变成了新的View对象。就播了新的View对象,

让动画播放完后,再去更新页面;

如何等待呢?

动画播放是不能放在子线程的。

view.startAnimation(ta);//通知动画开始播放

动画播放是每隔一段时间在主线程更新View,产生的动画效果;

//让主线程等待500毫米

postDelayed方法说明:

Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses. The runnable will be run on the thread to which this handler is attached (附属的).

使Runnable r添加到消息队列,是运行在指定时间的流逝之后。可运行的线程将运行在handler 附属线程。

//若干秒后在主线程执行逻辑

new Handler().postDelayed(new Runnable() {

@Override

public void run() {

//会在主线程执行

// 从当前界面移除Item

unlockappInfos.remove(position);

// 把移除的Item对象对应的包名加到数据库里面

dao.add(appInfo.getPackageName());

lockedappInfos.add(appInfo);

// 通知页面刷新

// notifyDataSetChanged();

unLockAdapter.notifyDataSetChanged();

lockedAdapter.notifyDataSetChanged();

}

}, 500);

完整代码:

if (unlockflag) {

TranslateAnimation ta = new TranslateAnimation(

Animation.RELATIVE_TO_SELF, 0,

Animation.RELATIVE_TO_SELF, 1.0f,

Animation.RELATIVE_TO_SELF, 0,

Animation.RELATIVE_TO_SELF, 0);

ta.setDuration(500);

view.startAnimation(ta);

//若干秒后在主线程执行逻辑

new Handler().postDelayed(new Runnable() {

@Override

public void run() {

//会在主线程执行

// 从当前界面移除Item

unlockappInfos.remove(position);

// 把移除的Item对象对应的包名加到数据库里面

dao.add(appInfo.getPackageName());

lockedappInfos.add(appInfo);

// 通知页面刷新

// notifyDataSetChanged();

unLockAdapter.notifyDataSetChanged();

lockedAdapter.notifyDataSetChanged();

}

}, 500);

} else {

holder.iv_status.setImageResource(R.drawable.unlock);

TranslateAnimation ta = new TranslateAnimation(

Animation.RELATIVE_TO_SELF, 0,

Animation.RELATIVE_TO_SELF, -1.0f,

Animation.RELATIVE_TO_SELF, 0,

Animation.RELATIVE_TO_SELF, 0);

ta.setDuration(500);

view.startAnimation(ta);

//若干秒后在主线程执行逻辑

new Handler().postDelayed(new Runnable() {

@Override

public void run() {

//会在主线程执行

lockedappInfos.remove(position);

dao.delete(appInfo.getPackageName());

unlockappInfos.add(appInfo);

// 通知页面刷新

// notifyDataSetChanged();

unLockAdapter.notifyDataSetChanged();

lockedAdapter.notifyDataSetChanged();

}

}, 500);

}

85_程序锁的原理_23

1、举例生活中:家里或者公司门口请一个保安。进来之前出事一下证件,如果认识的话,看一下脸就行了。请保安成本比较高。这时候就买了一条狗。我们叫这狗叫:看门狗

职责:监听手机的信息;

2、在服务包下创建新类WatchDogService 在功能清单文件配置,并实现onCreate()、onDestroy()方法

A:定义ActivityManager并实例化它

private ActivityManager am;

B:在onCreate()创建新线程,线程里循环监视当前运行的进程;

类的成员变量

private boolean flag = false;

new Thread(){

public void run() {

flag = true;

while (flag) {

//巡逻运行当前运行的应用程序

}

};

}.start();

C:得到任务占最前面任务栈信息,也是当前要开启的程序

回顾知识:返回一个集合,当前运行的任务栈

Return a list of the tasks that are currently running, with the most recent being first and older ones after in order. Note that "running" does not mean any of the task's code is currently loaded or activity -- the task may have been frozen by the system, so that it can be restarted in its previous state when next brought to the

foreground.

返回一个列表正在运行的任务,与最近的第一和旧后为。请注意,“跑”并不意味着任何任务的代码是当前加载的任务或活动——可能是由系统冻结,以便它可以重新启动在以前的状态下进入前台;

代码如下

new Thread(){

public void run() {

flag = true;

while (flag) {

//巡逻运行当前运行的应用程序

//得到最近打开的任务栈信息,最近打开的应用程序

RunningTaskInfo taskInfo = am.getRunningTasks(1).get(0);

String packName = taskInfo.topActivity.getPackageName();

System.out.println("==packName="+packName);

try {

Thread.sleep(100);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

}.start();

需要加上权限

android:name="android.permission.GET_TASKS"/>

D:在设置中心SettingActivity增加一条目,控制程序锁服务开启和关闭

android:id="@+id/siv_applock"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

itheima:desc_off="程序锁已经关闭"

itheima:desc_on="程序锁已经开启"

itheima:title="设置程序锁">

点击事件代码实现

//设置程序锁

siv_applock = (SettingItemView) findViewById(R.id.siv_applock);

watchDogIntent = new Intent(this,WatchDogService.class);

boolean isWatchDogRunning = ServiceUtils.isServiceRunning(this, "com.itheima.mobilesafe.service.WatchDogService");

if(isWatchDogRunning){

siv_applock.setChecked(true);

}else{

siv_applock.setChecked(false);

}

siv_applock.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

if(siv_applock.isChecked()){

siv_applock.setChecked(false);

stopService(watchDogIntent);

}else{

siv_applock.setChecked(true);

startService(watchDogIntent);

}

}

});

运行演示看效果,打开其他软件看看日志。

3、判断哪些应用需要保护

A:在WatchDogService里的创建AppLockDao类

private AppLockDao dao;

B:在onCreate()方法里实例化

dao = new AppLockDao(this);

C:查找数据库,那些程序需要加密,需要保护

if(dao.find(packName)){

//需要保护的的应用程序,弹出密码输入框

}

D:创建新的Activity界面EnterPwdActivity,并实现布局文件,在功能清单文件注册;

E:启动输入密码界面,在看门狗服务的onCreate()创建意图watchIntent = new Intent(this, EnterPwdActivity.class); watchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

在判断是需要保护的启动输入密码界面

if(dao.find(packName)){

//需要保护的的应用程序,弹出密码输入框

startActivity(watchIntent);

}

运行演示,看一下效果,和腾讯的对比;

86_程序锁的简单实现_32

1、在EnterPwdActivity里重写onBackPressed()方法,并进入手机桌面;

当按返回键调用的方法;

Called when the activity has detected the user's press of the back key. The default implementation simply finishes the current activity, but you can override this to do whatever you want.

当活动已检测到后退键的用户的新闻。默认的实现简单地完成当前的活动,但是你可以重写此来做你想做的事。

@Override

public void onBackPressed() {

//进入手机桌面

Intent intent = new Intent();

//

// intent.setAction("android.intent.action.MAIN");

intent.addCategory("android.intent.category.HOME");

startActivity(intent);

}

2、完善输入密码布局文件

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:id="@+id/tv_appname"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="你要打开的应用:"/>

android:id="@+id/iv_appicon"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:src="@drawable/app"/>

android:id="@+id/et_password"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:hint="请输入密码"

android:inputType="textPassword"/>

android:onClick="enter"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="确定" />

3、初始化控件

private TextView tv_appname;

private ImageView iv_appicon;

private EditText et_password;

4、在WatchDogService里传包名信息

watchIntent.putExtra("packname", packName);

5、在EnterPwdActivity获取包名

Intent intent = getIntent();

String packname = intent.getStringExtra("packname");

6、设置Icon和名字

PackageManager pm = getPackageManager();

相关主题
文本预览
相关文档 最新文档