92_杀毒软件的原理_34

1、什么是病毒?

电脑上的一个特殊的程序;

2、计算机第一个病毒?

搜索:计算机第一个病毒;

当时人们只是为了研究某个技术是否可行。没事干的时候开发的。

目的:技术研究或者没事干

这段时期主要是dos上,打出一下日志。

3、蠕虫病毒,威金病毒。

熊猫烧香,威金病毒的一种,感染电脑上的很多文件;exe文件被感染,html文件被感染。

主要目的:证明技术有多牛。

写这种病毒的人越来越少了

4、木马?

盗窃信息,盗号、窃取隐私、偷钱,玩了一个游戏,买了很多装备,监听你的键盘输入,下次进入的话,装备全部没了。

主要目的:挣钱,产生利益;

现在主流的病毒;

前段比特币网站被入侵,损失270多万美元;

5、灰鸽子

主要特征,控制别人电脑,为我所用。比如挖金矿游戏挣钱的,控制几十万台机器为你干活。

总会比银河处理器快的多。

特点是:不知情情况下安装下的。

所有的病毒,都是执行后才有危害,如果病毒下载了,没有安装运行,是没有危害的。

6、什么是杀毒软件

定位出特殊的程序,把程序的文件给删除。

Kv300

介绍王江民

Kill -virus

Kv300 干掉300个病毒

开发kv300后很多人用盗版的。

江民炸弹

硬盘分区表:mbr

记录,硬盘分了多少个区,起始柱面和结束柱面是什么;

7、病毒怎么找到?-收集病毒的样本。

电信 网络运营商主节点 部署服务器集群(蜜罐)

一组没有防火墙 没有安全软件 没有补丁,服务器一些功能主动联网

下载一下软件运行。这样情况下,特别容易中病毒。

工作原理相当于:苍蝇纸

8、360互联网云安全计划

所有的用户都是你的蜜罐;

收集的数据量就大大提高了;

国内安全厂商,有些没有职业道德。

收集一些个人隐私,或者商业机密的文件也收集过去。

百度,要求一级代理二级代理不能用什么什么浏览器,什么什么安全软件,

上传害怕重要数据;

淘宝不许用QQ,只能用旺旺;害怕收集机密文件;

目前卡巴斯基病毒库已经有了2千多万病毒

传统杀毒软件的缺陷: 病毒数据库越来越大;

只能查杀已知的病毒,不能查杀未知病毒;

360免杀

写了一个木马,在加一个壳,加壳后360就识别不了了。

前段时间,网上说一个学生300块钱买了木马病毒,盗了一个游戏公司账号-梦三国

120万 游戏账号。

9.主动防御

检查软件

1.检查开启启动项

2.检查注册表;

3.检查进程列表

病毒特征:

1、开启启动

2、隐藏自身

3、监视键盘hook

4、联网发邮件smtp

把它拦截掉

看门狗,不断扫描,启动项,键盘监听;

启发式扫描

虚拟机-相当于精简版的系统

10、杀毒引擎

优化后的数据库查询算法

2000万

100万 1秒扫描一个 30年

11、Android上的杀毒软件

大多数停留在基于数据库方式杀毒

lbe主动防御方式杀毒。

查看金山手机卫士病毒库

93_杀毒的页面&自定ProgressBar_27

1、演示一下金山杀毒的效果,并讲解大概实现方式;

2、创建新页面AntiVirusActivity并在功能清单文件注册,创建布局文件activity_anti_virus.xml,标题为病毒查杀;

AntiVirus杀毒软件

3、雷达效果,布局文件实现,并且代码实现;

A:布局文件

<LinearLayout

android:layout_width="match_parent"

android:layout_height="80dip"

android:orientation="horizontal" >

<FrameLayout

android:layout_width="80dip"

android:layout_height="80dip" >

<ImageView

android:layout_width="80dip"

android:layout_height="80dip"

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

<ImageView

android:id="@+id/iv_scan"

android:layout_width="80dip"

android:layout_height="80dip"

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

</FrameLayout>

<LinearLayout

android:layout_width="match_parent"

android:layout_height="80dip"

android:gravity="center"

android:orientation="vertical" >

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="扫描状态"

android:textColor="#000000"

android:textSize="18sp" />

<ProgressBar

android:id="@+id/progressBar1"

style="?android:attr/progressBarStyleHorizontal"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_marginLeft="10dip"

android:layout_marginRight="10dip" />

</LinearLayout>

</LinearLayout>

B:代码实现,旋转动画

iv_scan = (ImageView) findViewById(R.id.iv_scan);

RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

ra.setDuration(1000);

//不停的旋转

ra.setRepeatCount(RotateAnimation.INFINITE);

iv_scan.startAnimation(ra);

4、修改进度条样式效果

A:参照系统样式文件;

开发环境\platforms\android-16\data\res\values\styles.xml,搜索ProgressBar-->progress_medium_white--->spinner_white_48(图片)

indeterminate Only

不确定的只是

水平方向进度条Widget.ProgressBar.Horizontal

搜索:progress_horizontal讲解里面的结构;

layer-list 层;

B:把progress_horizontal拷贝该资源到drawble目录下,并修改成;并且把金山进程图片也拷贝到drawble目录下,progress_horizontal.xml修改成如下:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@android:id/background" android:drawable="@drawable/security_progress_bg">

</item>

<item android:id="@android:id/secondaryProgress" android:drawable="@drawable/security_progress">

</item>

<item android:id="@android:id/progress" android:drawable="@drawable/security_progress">

</item>

</layer-list>

C:布局使用

<ProgressBar

android:id="@+id/progressBar1"

style="?android:attr/progressBarStyleHorizontal"

android:progressDrawable="@drawable/progress_horizontal"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_marginLeft="10dip"

android:layout_marginRight="10dip" />

D:代码设置进度

progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);

progressBar1.setMax(100);

new Thread(){

public void run() {

for(int i = 0;i<100;i++){

progressBar1.setProgress(i);

try {

Thread.sleep(30);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

}.start();

运行演示,看效果。

94_获取应用程序的签名_20

1、获取应用程序的特征码-签名信息

PackageManager pm = getPackageManager();

//获取所有应用程序 包括卸载的但没有卸载干净(保留有数据的应用)

List<PackageInfo> packInfos = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES+PackageManager.GET_SIGNATURES);

for(PackageInfo packageInfo:packInfos){

System.out.println(packageInfo.applicationInfo.loadLabel(pm));

System.out.println(packageInfo.signatures[0].toCharsString());

System.out.println("---");

}

A List of PackageInfo objects, one for each package that is installed on the device. In the unlikely case of there being no installed packages, an empty list is returned. If flag GET_UNINSTALLED_PACKAGES is set, a list of all applications including those deleted with DONT_DELETE_DATA (partially installed apps with data directory) will be returned.

一列packageInfo对象,每一个包,安装在装置。在不可能的情况下,没有安装的软件包,则返回一个空列表。如果国旗get_uninstalled_packages设置,一个列表中的所有应用程序包括删除dont_delete_data(部分安装的应用程序将返回的数据目录)。

2、应用程序签名回顾

应用程序签名:

自动更新覆盖安装,包一致,签名一致。

签名实际上是识别一个应用程序开发者的唯一标识,检查应用的完整性的;

做实验:

用任意一个APK,拷贝到桌面上。用解压工具打开

看一下meta-inf:保存应用程序的签名信息;

A:演示正常装软件:

列出设备命令:adb devices

安装到5554模拟器:

C:\Users\Administrator>adb -s emulator-5554 install C:\Users\Administrator\Deskt

op\小火箭.apk

B :修改里面图标

C:提示安装失败

INSTALL_PARSE_FAILED_NO_CERTIFICATES : 安装解析失败没有证书;

修改图,签名就发生了变化。和原来的就对不上了。能否和原来签名一样呢?因为不知道签名密码,无法做成一样的。

apk包的签名被存储在文件META-INF\CERT.RSA中

其他两个文件时校验apk的完整性的。

3、查看签名信息

高亮相同字符串:表是同一个签名文件,也就是同一个谷歌团队开发的。

查看我们自己开发的软件的签名信息--不同电脑的默认签名是不一样的;

开发病毒的时候,签名如果用同一个签名的话,不管如何升级,很快就知道了是同一个公司开发的病毒。

4、查杀病毒的原理

得到签名信息,加密md5信息,病毒库查询,是否是病毒。

由于签名信息太长不便于计算,把它加密成md5值

PackageManager pm = getPackageManager();

//获取所有应用程序 包括卸载的但没有卸载干净(保留有数据的应用)

List<PackageInfo> packInfos = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES+PackageManager.GET_SIGNATURES);

for(PackageInfo packageInfo:packInfos){

System.out.println(packageInfo.applicationInfo.loadLabel(pm));

String md5 = MD5Utils.md5Password(packageInfo.signatures[0].toCharsString());

System.out.println(md5);

System.out.println("-查询这个md5是否在病毒库存在-----");

}

知识拓展:

检查应用程序签名,应用场景,比如机顶盒厂商,只想安装自己开发或者合作的软件,这个时候安装的时候,校验一下是不是自己公司的签名;如果是就安装,否则就不让安装。

95_手机杀毒的完成&横竖屏切换的生命周期_40

1、拷贝金山手机卫士病毒数据库antivirus.db到工程资源目录下

2、基于AddressDao修改成AntivirusDao,并且修改里面文件的路径;

代码修改成如下:

SQL语句:select * from datable where md5 = "2b29d68c53187079c1dc0ac47fdcb578"

select desc from datable where md5 = "2b29d68c53187079c1dc0ac47fdcb578"

public class AntivirusDao {

private static String path = "data/data/com.itheima.mobilesafe/files/antivirus.db";

/**

* 查询是否是病毒

*

* @param md5签名信息的md5值

* @return 是返回病毒的描述信息;不是病毒返回null;

*/

public static String isVirus(String md5) {

String result = null;

SQLiteDatabase db = SQLiteDatabase.openDatabase(path, null,

SQLiteDatabase.OPEN_READONLY);

Cursor cursor = db.rawQuery("select desc from datable where md5 = ?",

new String[] { md5 });

while (cursor.moveToNext()) {

result = cursor.getString(0);

}

cursor.close();

db.close();

return result;

}

}

在SplashActivity 把数据库拷贝

copyDB("antivirus.db");

3、扫描病毒代码

for(PackageInfo packageInfo:packInfos){

System.out.println(packageInfo.applicationInfo.loadLabel(pm));

String md5 = MD5Utils.md5Password(packageInfo.signatures[0].toCharsString());

String result = AntivirusDao.isVirus(md5);

if(result != null){

System.out.println("发现病毒");

}else{

System.out.println("扫描安全");

}

}

运行演示看效果;

4、更改病毒扫描时的状态

A:实例化状态TextView和线程布局

tv_scan_status = (TextView) findViewById(R.id.tv_scan_status);

ll_container = (LinearLayout) findViewById(R.id.ll_container);

tv_scan_status.setText("正在初始化杀毒引擎...");

B:扫描病毒代码,放入子线程并休眠2秒,便于显示状态效果;

new Thread() {

public void run() {

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

PackageManager pm = getPackageManager();

// 获取所有应用程序 包括卸载的但没有卸载干净(保留有数据的应用)

List<PackageInfo> packInfos = pm

.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES

+ PackageManager.GET_SIGNATURES);

progressBar1.setMax(packInfos.size());

int progress = 0;

Random random = new Random();

for (PackageInfo packageInfo : packInfos) {

System.out.println(packageInfo.applicationInfo

.loadLabel(pm));

String md5 = MD5Utils.md5Password(packageInfo.signatures[0]

.toCharsString());

String result = AntivirusDao.isVirus(md5);

if (result != null) {

System.out.println("发现病毒");

} else {

System.out.println("扫描安全");

}

progress++;

progressBar1.setProgress(progress);

try {

Thread.sleep(50 + random.nextInt(50));

} catch (InterruptedException e) {

e.printStackTrace();

}

}

};

}.start();

5、更新扫描结果显示

A:定位扫描信息类ScanInfo

class ScanInfo{

boolean isVirus;

String desc;

String appName;

}

B:创建Handler

private Handler handler = new Handler(){

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case SCANING:

ScanInfo scanInfo = (ScanInfo) msg.obj;

tv_scan_status.setText("正在扫描:"+scanInfo.appName);

TextView textView = new TextView(AntiVirusActivity.this);

if(scanInfo.isVirus){

textView.setText("发现病毒:"+scanInfo.appName);

textView.setTextColor(Color.RED);

}else{

textView.setText("扫描安全:"+scanInfo.appName);

textView.setTextColor(Color.BLACK);

}

//至上而下的效果

ll_container.addView(textView, 0);

break;

case SCAN_FINISH:

//取消动画

iv_scan.clearAnimation();

tv_scan_status.setText("扫描完毕");

break;

}

};

};

new Thread() {

public void run() {

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

PackageManager pm = getPackageManager();

// 获取所有应用程序 包括卸载的但没有卸载干净(保留有数据的应用)

List<PackageInfo> packInfos = pm

.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES

+ PackageManager.GET_SIGNATURES);

progressBar1.setMax(packInfos.size());

int progress = 0;

Random random = new Random();

for (PackageInfo packageInfo : packInfos) {

//扫描信息

ScanInfo scanInfo = new ScanInfo();

scanInfo.appName = packageInfo.applicationInfo

.loadLabel(pm).toString();

String md5 = MD5Utils.md5Password(packageInfo.signatures[0]

.toCharsString());

String result = AntivirusDao.isVirus(md5);

if (result != null) {

scanInfo.isVirus = true;

scanInfo.des = result;

System.out.println("发现病毒");

} else {

System.out.println("扫描安全");

scanInfo.isVirus = false;

scanInfo.des = null;

}

Message message = Message.obtain();

message.what = SCANING;

message.obj = scanInfo;

handler.sendMessage(message);

progress++;

progressBar1.setProgress(progress);

try {

Thread.sleep(50 + random.nextInt(50));

} catch (InterruptedException e) {

e.printStackTrace();

}

}

//扫描完成

Message message = Message.obtain();

message.what = SCAN_FINISH;

handler.sendMessage(message);

};

}.start();

}

C:模拟病毒,看是否有变色效果。

安装提前准备的两个假病毒和替换病毒数据库。

运行演示看效果

D:解决无法拖动查看扫描情况问题;

<ScrollView

android:layout_width="fill_parent"

android:layout_height="fill_parent" >

<LinearLayout

android:id="@+id/ll_container"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

</LinearLayout>

</ScrollView>

E:创建病毒集合

/**

* 病毒查询的集合

*/

private List<ScanInfo> virusInfos;

if (result != null) {

scanInfo.isVirus = true;

scanInfo.des = result;

System.out.println("发现病毒");

virusInfos.add(scanInfo);

} else {

System.out.println("扫描安全");

scanInfo.isVirus = false;

scanInfo.des = null;

}

F:发现病毒后,提示用户删除病毒。

扫描信息增加包字段;

case SCAN_FINISH:

//取消动画

iv_scan.clearAnimation();

tv_scan_status.setText("扫描完毕");

if(virusInfos.size()>0){

AlertDialog.Builder builder = new Builder(AntiVirusActivity.this);

builder.setTitle("警告!!");

builder.setMessage("发现病毒:"+virusInfos.size()+"个,手机已经十分危险,赶快杀毒!!!");

builder.setNegativeButton("下次再说", null);

builder.setPositiveButton("立即清除", new OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

for(ScanInfo scanInfo : virusInfos){

Intent intent = new Intent();

intent.setAction(Intent.ACTION_DELETE);

intent.setData(Uri.parse("package:"+scanInfo.packName));

startActivity(intent);

}

}

});

builder.show();

}else{

Toast.makeText(getApplicationContext(), "你的手机很安全了,继续加油哦!", 0).show();

}

break;

6、处理横竖屏切换

A:演示金山手机卫士

B:在功能清单文件配置

<activity android:name="com.itheima.mobilesafe.AntiVirusActivity"

android:configChanges="orientation|screenSize|keyboardHidden"/>

96_缓存应用&获取应用程序的缓存大小_41

1、看看金山手机卫士的缓存清理功能;并单独创建工程“缓存应用”

在onCreate方法代码如下:

try {

//data/data/包名/cache

File file = new File(getCacheDir(),"haha.txt");

FileOutputStream fos = new FileOutputStream(file);

fos.write("hahahahdddd".getBytes());

fos.close();

}  catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

运行到安装有金山手机卫士的模拟器上,然后再次查看金山的垃圾清理功能。

2、获取应用程序的缓存;

查看软件管理的信息大小, 页面;

A:创建新工程“获取应用的缓存”

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent" >

<EditText

android:id="@+id/et_packname"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:hint="请输入要查询的包名" />

<Button

android:onClick="click"

android:text="查询"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

<TextView

android:id="@+id/tv_result"

android:text="查询结果"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

</LinearLayout>

B:处理点击事件-参数设置工程的代码

进入程序详细列表界面如图:

搜索:Cache或者缓存

找到:cache_size_label字段--->

找到布局文件installed_app_details.xml-->

cache_size_text-->搜索那个Java代码用到它--->

getSizeStr(cacheSize)-->cacheSize---->SizeInfo-->

entry.cacheSize = stats.cacheSize-->PackageStats-->

谁调用了mStatsObserver--->

mPm.getPackageSizeInfo(mCurComputingSizePkg, mStatsObserver);

远程服务代理对象

3、获取应用程序的缓存的代码实现

A:初始化布局view的、得到包名、处理点击事件

//点击事件-得到某应用的缓存大小

public void click(View view){

String packName = et_packname.getText().toString().trim();

if(TextUtils.isEmpty(packName)){

Toast.makeText(this, "包名不能为空", 1).show();

return;

}else{

PackageManager pm = getPackageManager();

//pm.getPackageSizeInfo//该方法被隐藏了,需要用反射拿到

}

}

getPackageSizeInfo方法注释:

Retrieve the size information for a package.

Since this may take a little while, the result will

be posted back to the given observer.  The calling context

should have the {@link  android.Manifest.permission#GET_PACKAGE_SIZE} permission.

包的大小信息检索。

因为这可能需要一段时间,结果将回发到给定的观察者。调用上下文

应该有{”链接的Android。# get_package_size }许可权限清单。

B:用反射得到PackageManager里所有方法

PackageManager pm = getPackageManager();

Method[] methods = PackageManager.class.getMethods();

for(Method method : methods){

System.out.println(method.getName());

}

运行演示,看日志有没有我们想要的方法。

C:IPackageStatsObserver.Stub()自定义

拷贝IPackageStatsObserver.aidl文件到android.content.pm包下

报错后拷贝PackageStats.aidl文件到android.content.pm包下

private class MyObserver extends IPackageStatsObserver.Stub{

@Override

public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)

throws RemoteException {

long cacheSize = pStats.cacheSize ;

long dataSize = pStats.dataSize ;

long codeSize = pStats.codeSize ;

String result = "缓存:"+Formatter.formatFileSize(getApplicationContext(), cacheSize)+"\n"+

"数据:"+Formatter.formatFileSize(getApplicationContext(), dataSize)+"\n"+

"代码:"+Formatter.formatFileSize(getApplicationContext(), codeSize);

System.out.println(result);

tv_result.setText(result);

}

}

D:执行方法

PackageManager pm = getPackageManager();

Method[] methods = PackageManager.class.getMethods();

for(Method method : methods){

if("getPackageSizeInfo".equals(method.getName())){

//谁去执行,参数,包名、和回调对象

method.invoke(pm, packName,new MyObserver());

return;

}

}

需要加权限:

<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>

E:解决无法显示结果问题

private Handler handler = new Handler(){

public void handleMessage(android.os.Message msg) {

String result = (String) msg.obj;

tv_result.setText(result);

};

};

发消息到主线程更新

// tv_result.setText(result);

Message msg = Message.obtain();

msg.obj = result;

handler.sendMessage(msg);

97_清理全部应用程序的缓存&freeStorageAndNotify_44

1、基于做的Demo添加到缓存清理,创建新页面CleanCacheActivity在功能清单文件并写页面、主页面能跳转;

2、布局文件,基于通讯卫士页面activity_callsms_safe.xml修改成activity_clean_cache.xml

修改标题

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

<RelativeLayout

android:layout_width="match_parent"

android:layout_height="wrap_content" >

<TextView

android:id="@+id/textView1"

android:layout_width="fill_parent"

android:layout_height="55dip"

android:background="#8866ff00"

android:gravity="left|center_vertical"

android:text="缓存清理"

android:textColor="#000000"

android:textSize="20sp" />

<Button

style="?android:attr/buttonStyleSmall"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentRight="true"

android:layout_centerVertical="true"

android:onClick="addBlackNumber"

android:text="立即清理" />

</RelativeLayout>

<ProgressBar

android:id="@+id/progressBar1"

style="?android:attr/progressBarStyleHorizontal"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:progressDrawable="@drawable/progress_horizontal" />

<TextView

android:text="正在扫描.."

android:id="@+id/tv_status"

android:layout_width="fill_parent"

android:layout_height="wrap_content" />

<LinearLayout

android:id="@+id/ll_container"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="vertical" >

</LinearLayout>

</LinearLayout>

3、初始化View

progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);

tv_status = (TextView) findViewById(R.id.tv_status);

ll_container = (LinearLayout) findViewById(R.id.ll_container);

4、扫描得到所有安装在系统的应用的缓存信息

A:在onCreate创建子线程

new Thread(){

public void run() {

};

}.start();

B:得到包管理器和安装包信息并遍历

PackageManager pm = getPackageManager();

List<PackageInfo> packInfos = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);

for(PackageInfo packInfo : packInfos){

String packName = packInfo.packageName;

}

C:用反射得到某个包的缓存信息;

拷贝之前代码aidl文件

修改代码

private class MyObserver extends IPackageStatsObserver.Stub {

@Override

public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)

throws RemoteException {

long cacheSize = pStats.cacheSize;

if (cacheSize > 0) {

System.out.println("当前程序:"

+ pStats.packageName

+ "有缓存:"

+ Formatter.formatFileSize(getApplicationContext(),

cacheSize));

}

}

}

D:设置扫描进度效果

PackageManager pm = getPackageManager();

List<PackageInfo> packInfos = pm

.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);

progressBar1.setMax(packInfos.size());

int progress = 0;

for (PackageInfo packInfo : packInfos) {

String packName = packInfo.packageName;

try {

Method method = PackageManager.class.getMethod(

"getPackageSizeInfo", String.class,

IPackageStatsObserver.class);

method.invoke(pm,packName,new MyObserver());

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

progress ++;

progressBar1.setProgress(progress);

}

E:设置扫描状态,扫描到谁了

private Handler handler = new Handler(){

public void handleMessage(Message msg) {

switch (msg.what) {

case SCANING:

String name = (String) msg.obj;

tv_status.setText("正在扫描:"+name);

break;

}

};

};

for (PackageInfo packInfo : packInfos) {

String packName = packInfo.packageName;

try {

Method method = PackageManager.class.getMethod(

"getPackageSizeInfo", String.class,

IPackageStatsObserver.class);

method.invoke(pm, packName,new MyObserver());

Message msg = Message.obtain();

msg.obj= ackInfo.applicationInfo.loadLabel(pm).toString();

msg.what = SCANING;

handler.sendMessage(msg);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

progress ++;

progressBar1.setProgress(progress);

try {

Thread.sleep(50);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

F:显示扫描结果

定义缓存信息类,发消息

class CacheInfo{

Drawable icon;

String name;

long size;

}

private class MyObserver extends IPackageStatsObserver.Stub {

@Override

public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)

throws RemoteException {

long cacheSize = pStats.cacheSize + pStats.externalCacheSize;

if (cacheSize > 0) {

try {

CacheInfo cacheInfo = new CacheInfo();

cacheInfo.icon = pm.getApplicationInfo(pStats.packageName, 0).loadIcon(pm);

cacheInfo.name = pm.getApplicationInfo(pStats.packageName, 0).loadLabel(pm).toString();

cacheInfo.size = cacheSize;

Message msg = Message.obtain();

msg.what = SHOW_SCAN_INFO;

msg.obj = cacheInfo;

handler.sendMessage(msg);

} catch (NameNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

基于布局文件list_app_item.xml修改名字list_appcache.xml

Handler里面处理

case SHOW_SCAN_INFO:

CacheInfo cacheInfo = (CacheInfo) msg.obj;

View view = View.inflate(getApplicationContext(), R.layout.list_app_cache, null);

ImageView iv_icon = (ImageView) view.findViewById(R.id.iv_icon);

TextView tv_name = (TextView) view.findViewById(R.id.tv_name);

TextView tv_cache_size = (TextView) view.findViewById(R.id.tv_cache_size);

iv_icon.setImageDrawable(cacheInfo.icon);

tv_name.setText(cacheInfo.name);

tv_cache_size.setText("缓存大小:"+Formatter.formatFileSize(getApplicationContext(), cacheInfo.size));

ll_container.addView(view, 0);

break;

E:处理扫描完成

//扫描完成发消息

Message msg = Message.obtain();

msg.what = SCAN_FINISH;

handler.sendMessage(msg);

处理扫描完成

case SCAN_FINISH:

tv_status.setText("扫描完成");

break;

F:如果有缓存应用很多支持上下滚动

<ScrollView

android:layout_width="match_parent"

android:layout_height="match_parent" >

<LinearLayout

android:id="@+id/ll_container"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

</LinearLayout>

</ScrollView>

5:立即清除

A:查看PackageManager 方法freeStorageAndNotify

Free storage by deleting LRU sorted list of cache files across

* all applications. If the currently available free storage

* on the device is greater than or equal to the requested

* free storage, no cache files are cleared. If the currently

* available storage on the device is less than the requested

* free storage, some or all of the cache files across

* all applications are deleted (based on last accessed time)

* to increase the free storage space on the device to

* the requested value. There is no guarantee that clearing all

* the cache files from all applications will clear up

* enough storage to achieve the desired value.

* @param freeStorageSize The number of bytes of storage to be

* freed by the system. Say if freeStorageSize is XX,

* and the current free storage is YY,

* if XX is less than YY, just return. if not free XX-YY number

* of bytes if possible.

* @param observer call back used to notify when

* the operation is completed

通过删除LRU排序列表缓存文件在自由存储

*所有的应用程序。如果当前可用的免费存储空间

*在设备大于或等于要求

*免费存储,没有缓存文件的清除。如果目前

*在设备可用的存储是小于请求

*免费存储空间,一些或所有的缓存文件在

*所有的应用程序被删除(基于上次访问时间)

*增加到装置上的免费存储空间

*要求值。有没有保证,清除所有

*缓存文件从所有的应用程序将清除

*足够的存储空间来实现预期的价值。

* @param freestoragesize存储字节数为通过系统释放。如果说freestoragesize是XX,

*和目前的免费存储是YY,

*如果XX小于YY,刚刚返回。如果不是免费的xx-yy数

*操作完成

LRU(Least Recently Used)近期最少使用算法

工作原理

Map集合<Integer,文件目录> map

例如:

14:35: 操作了文件A

14:45: 操作了文件B

14:49: 操作了文件C

14:50: 操作了文件B

14:51: 操作了文件C

The number of bytes of storage to be

* freed by the system. Say if freeStorageSize is XX,

* and the current free storage is YY,

* if XX is less than YY, just return. if not free XX-YY number

* of bytes if possible.

如何理解

假设

需要清理的是5M,系统总的可用空间是100MB,只会释放5MB空间,如果需要清理的是100MB ,系统的可用内存只有5MB,释放的就只有5MB的空间;如果请求的无限大,有多少就只能返回多少了。

B:实现点击事件

//点击事件-立即清除

public void cleanAll(View view){

Method [] methodes = PackageManager.class.getMethods();

for(Method method : methodes){

if("freeStorageAndNotify".equals(method.getName())){

try {

method.invoke(pm, Integer.MAX_VALUE,new IPackageDataObserver.Stub() {

@Override

public void onRemoveCompleted(String packageName, boolean succeeded)

throws RemoteException {

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

}

});

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return;

}

}

}

拷贝IPackageDataObserver.aidl文件

加权限

<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>

98_清除一个应用的缓存&变为系统应用_25

1、查看金山手机卫士和腾讯手机管家,点击,进入某应用信息列表;

2、具体代码实现

A:添加图片按钮

<ImageView

android:id="@+id/iv_delete"

android:layout_width="40dip"

android:layout_height="40dip"

android:layout_alignParentRight="true"

android:layout_centerVertical="true"

android:background="@drawable/delete_button" />

B:设置点击事件

搜索设置页面:“Clear cache” 或者“清除缓存”

--->clear_cache_btn_text--->clear_cache_button--->

代码实现如下:

Method[] methods = PackageManager.class.getMethods();

for(Method  method : methods){

if("deleteApplicationCacheFiles".equals(method.getName())){

try {

method.invoke(pm, cacheInfo.packName,new IPackageDataObserver.Stub() {

@Override

public void onRemoveCompleted(String packageName, boolean succeeded)

throws RemoteException {

System.out.println("succeeded"+succeeded);

}

});

return;

} catch (Exception e) {

e.printStackTrace();

}

}

}

加权限

<uses-permission android:name="android.permission.DELETE_CACHE_FILES"/>

知识拓展:

加上权限后仍然报错

要想清除一个应用的缓存起作用,只需要把我们的应用变成系统应用。

如果变成系统应用?

和手机厂商合作

有root权限的手机直接安装到/system/app目录下

该功能就起作用了。

模拟器即使有root权限也装不到系统里面,因为模拟器,系统空间大小是固定的。

下面演示的时候需要用已经获得root权限的手机;

把手机卫士装到/system/app下命令:

C:\Users\Administrator>

adb push D:\workspace_test\MobileSafe\bin\MobileSafe.apk

/system/app/mobilesafe.apk

提示报错信息:

修改系统文件的权限-先进入:

修改系统文件的权限-改权限:

执行指令:mount -o remount ,rw /system/

这个时候再安装软件

C:\Users\Administrator>

adb push D:\workspace_test\MobileSafe\bin\MobileSafe.apk

/system/app/mobilesafe.apk

就可以安装到手机系统里面去了。

启动手机卫士,进入缓存清理,点击清理按钮就可以清理某一个应用程序的缓存了。

软件预装:其实就是装到/system/app目录和系统应用在一个目录下;或者说手机一出厂就装好的软件;

删除系统软件命令:

进入/system/app目录下:rm -r mobilesafe.apk;

99_跳转到某个系统应用界面清除缓存_7

1、看一下腾讯管家跳转到系统应用界面时的日志,并且对于Settings源代码说明意图;

2、代码实现:

//启动到某个系统应用页面

Intent intent = new Intent();

intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");

intent.addCategory(Intent.CATEGORY_DEFAULT);//有无没影响

intent.setData(Uri.parse("package:"+cacheInfo.packName));

startActivity(intent);

100_sd卡清理的原理_10

工作原理:把认识的文件删除就行了;

1、打开金山手机卫士的clearpath.db数据库,看看里面的内容;

A:在模拟题创建目录

列出模拟器命令:adb devices

进入金山手机卫士在的模拟器命令:

adb -s emulator-5556 shell

进入SD卡: cd /mnt/sdcard/

创建目录.QQ命令:

mkdir .QQ

创建目录book目录命令:

mkdir book

查看创建目录命令:ls -a

这个功能会带来问题,比如聊天了很多信息,有可以能被删除。

建议删除的时候,判断一下是否该软件存在,如果不存在才删除。

2、创建Sdcard清理页面CleanSDActivity,并在功能清单文件配置

在onCreate方法写伪代码:

File file = Environment.getExternalStorageDirectory();

File [] files = file.listFiles();

for(File f : files){

String name = f.getName();

if(f.isDirectory()){

System.out.println(name);

//查询这个文件夹名称是否在数据库中存在,如果存在提示用户删除

}

}

在HomeActivity直接激活它;

模仿360安全卫士项目笔记10相关推荐

  1. 模仿360安全卫士项目笔记9

    82_程序锁的UI_48 1.参照腾讯手机管家,看一看演示软件锁功能:设置密码,启动软件试试: 2.在高级工具里面添加"程序锁"enterApplock,添加点击事件. 3.创建新 ...

  2. 模仿360安全卫士项目笔记8

    72_得到手机的内存ram信息_41 1.参照金山手机卫士的进程管理 2.创建TaskManagerActvity并在功能清单文件注册. 布局文件基于软件管理界面修改一下.并且修改对应的文字和ID: ...

  3. 模仿360安全卫士项目笔记1

    01_项目介绍_20 演示项目功能: 1.对前面知识的综合应用,复习基础一遍. 2.熟悉代码,找到敲代码的感觉: 3.每天会有1000-1500行代码量:这几天下来一共就会有1万多行代码量. 4.大学 ...

  4. 模仿360安全卫士项目笔记5

    42_自定义土司显示归属地_26 演示:目前的土司的缺陷,比如:无法控制消失.界面丑 1.看Toast的源代码 2.查看toast布局文件的背景目录:\sdk\platforms\android-16 ...

  5. 模仿360安全卫士项目笔记3

    27_手机防盗的原理_30 手机防盗的前提就是绑定sim,如果不绑定没意义: 1.在Setup2Activity页面时,当点击下一个按钮是校验是否设置了sim绑定,没绑定的话不让进入: 2.在Sele ...

  6. 模仿360安全卫士项目笔记7

    61_ 短信备份的原理_30 1.查看金山手机卫士的短信备份功能. 短信备份的原理,是用内容提供者读取短信,然后保存. 2.在高级工具AtoolsActivity布局文件里添加短信备份,并处理点击事件 ...

  7. 模仿360安全卫士项目笔记4

    39_抖动和振动效果_32 1.进入模拟器的APIDemo展示点击输入框振动效果(views/animation/shake): //shake 动摇:摇动:震动:握手的意思 2.找系统sdk\sam ...

  8. 模仿360安全卫士项目笔记2

    14_自定义对话框_40 1.画图两个对话框的样子: 2.写大体逻辑代码: showLostFindDialog();//进入手机防盗的对话框: isSetupPwd();//判断是否设置过密码,用到 ...

  9. 炫彩界面库-模仿360安全卫士8.8,支持透明,换肤

    炫彩界面库-模仿360安全卫士8.8 此示例程序使用炫彩界面开发,采用贴图方式实现,控件透明,换肤. 代码下载地址:点击打开链接  代码在炫彩界面库下载包中.

最新文章

  1. OSS.Core基于Dapper封装(表达式解析+Emit)仓储层的构思及实现
  2. 浅谈Laravel中的设计模式(四) Contract 契约模式
  3. 总结ThinkPHP使用技巧经验分享(四)
  4. C#中RichTextBox文本居中显示
  5. 2020年,数据中心的绿色技术演进与创新
  6. 【若依(ruoyi)】Unknown column ‘create_time‘ in ‘order clause‘
  7. android实现计时器
  8. 在副业刚需的时代,如何掌握副业的正确姿势?
  9. h1、h2、h3标签及strong标签对页面seo的影响
  10. mysql8导出文件_windows下 Mysql 8.0.x 数据库简单的导出和导入!!!
  11. MySQL 基础 ———— 分组查询
  12. socket网络编程知识
  13. UNIX再学习 -- RS485 串口编程
  14. canvas压缩图片方法
  15. 计算机学会a类论文是sci吗,什么是SCI、EI、CCF、DASFAA
  16. COCO数据集转VOC之检测
  17. 计算机发展史观后感50字,《计算机:一部历史》读后感_1300字
  18. 从MSDN我告诉你下载镜像
  19. 王家族字辈(我的家族字辈)
  20. iPhone6 像素 分辨率

热门文章

  1. Future是什么?
  2. 软件工程----生命周期模型
  3. 最常用十大电子元器件-电子技术方案|电路图讲解
  4. [C陷阱]getchar的返回值是int而不是char
  5. iphone 越狱插件开发-- 环境搭建篇
  6. Google 的秘密- PageRank 彻底解说 中文版(二)
  7. 虚拟机进不去登陆界面一直转圈
  8. html 代码块压缩
  9. ALBRECHT密钻夹头SK30 2-14mm A92
  10. 怎么在命令行执行.py文件,py文件生成可执行文件