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= newRotateAnimation(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(图片)
indeterminateOnly
不确定的只是
水平方向进度条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-generatedcatch block
e.printStackTrace();
}
}
};
}.start();
运行演示,看效果。
94_获取应用程序的签名_20
1、获取应用程序的特征码-签名信息
PackageManager pm= getPackageManager();
//获取所有应用程序 包括卸载的但没有卸载干净(保留有数据的应用)
List<PackageInfo>packInfos = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES+PackageManager.GET_SIGNATURES);
for(PackageInfopackageInfo: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 eachpackage that is installed on the device. In the unlikely case of there being noinstalled packages, an empty list is returned. If flag GET_UNINSTALLED_PACKAGESis set, a list of all applications including those deleted withDONT_DELETE_DATA (partially installed apps with data directory) will bereturned.
一列packageInfo对象,每一个包,安装在装置。在不可能的情况下,没有安装的软件包,则返回一个空列表。如果国旗get_uninstalled_packages设置,一个列表中的所有应用程序包括删除dont_delete_data(部分安装的应用程序将返回的数据目录)。
2、应用程序签名回顾
应用程序签名:
自动更新覆盖安装,包一致,签名一致。
签名实际上是识别一个应用程序开发者的唯一标识,检查应用的完整性的;
做实验:
用任意一个APK,拷贝到桌面上。用解压工具打开
看一下meta-inf:保存应用程序的签名信息;
A:演示正常装软件:
列出设备命令:adbdevices
安装到5554模拟器:
C:\Users\Administrator>adb -semulator-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(PackageInfopackageInfo: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 StringisVirus(String md5) {
Stringresult = null;
SQLiteDatabasedb = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READONLY);
Cursorcursor = 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(PackageInfopackageInfo: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();
}
PackageManagerpm = getPackageManager();
// 获取所有应用程序 包括卸载的但没有卸载干净(保留有数据的应用)
List<PackageInfo>packInfos = pm
.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES
+PackageManager.GET_SIGNATURES);
progressBar1.setMax(packInfos.size());
int progress = 0;
Randomrandom = new Random();
for (PackageInfopackageInfo : 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;
Stringdesc;
StringappName;
}
B:创建Handler
private Handler handler = new Handler(){
public voidhandleMessage(android.os.Message msg) {
switch (msg.what) {
case SCANING:
ScanInfo scanInfo = (ScanInfo) msg.obj;
tv_scan_status.setText("正在扫描:"+scanInfo.appName);
TextView textView = newTextView(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();
}
PackageManagerpm = getPackageManager();
// 获取所有应用程序 包括卸载的但没有卸载干净(保留有数据的应用)
List<PackageInfo>packInfos = pm
.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES
+PackageManager.GET_SIGNATURES);
progressBar1.setMax(packInfos.size());
int progress = 0;
Randomrandom = new Random();
for (PackageInfopackageInfo : 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();
}
}
//扫描完成
Messagemessage = 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:创建病毒集合
/**
* 病毒查询的集合
*/
privateList<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 voidonClick(DialogInterface dialog, int which) {
for(ScanInfo scanInfo :virusInfos){
Intentintent = 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 = newFileOutputStream(file);
fos.write("hahahahdddd".getBytes());
fos.close();
} catch (Exception e) {
// TODO Auto-generatedcatch 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 sizeinformation for a package.
Since this may take alittle while, the result will
be posted back to thegiven 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 voidonGetStatsCompleted(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 voidhandleMessage(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(PackageInfopackInfo : packInfos){
String packName = packInfo.packageName;
}
C:用反射得到某个包的缓存信息;
拷贝之前代码aidl文件
修改代码
private class MyObserver extendsIPackageStatsObserver.Stub {
@Override
public voidonGetStatsCompleted(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 (PackageInfopackInfo : 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-generatedcatch block
e.printStackTrace();
}
progress ++;
progressBar1.setProgress(progress);
}
E:设置扫描状态,扫描到谁了
private Handler handler = new Handler(){
public voidhandleMessage(Message msg) {
switch (msg.what) {
case SCANING:
Stringname = (String) msg.obj;
tv_status.setText("正在扫描:"+name);
break;
}
};
};
for (PackageInfopackInfo : packInfos) {
String packName = packInfo.packageName;
try {
Methodmethod = 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-generatedcatch block
e.printStackTrace();
}
progress ++;
progressBar1.setProgress(progress);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
F:显示扫描结果
定义缓存信息类,发消息
class CacheInfo{
Drawableicon;
Stringname;
long size;
}
private class MyObserver extendsIPackageStatsObserver.Stub {
@Override
public voidonGetStatsCompleted(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-generatedcatch block
e.printStackTrace();
}
}
}
}
基于布局文件list_app_item.xml修改名字list_appcache.xml
Handler里面处理
caseSHOW_SCAN_INFO:
CacheInfocacheInfo = (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(LeastRecently 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,
* ifXX is less than YY, just return. if not free XX-YY number
* ofbytes if possible.
如何理解
假设
需要清理的是5M,系统总的可用空间是100MB,只会释放5MB空间,如果需要清理的是100MB ,系统的可用内存只有5MB,释放的就只有5MB的空间;如果请求的无限大,有多少就只能返回多少了。
B:实现点击事件
//点击事件-立即清除
public void cleanAll(Viewview){
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(StringpackageName, boolean succeeded)
throws RemoteException {
System.out.println("succeeded="+succeeded);
}
});
} catch (Exception e) {
// TODO Auto-generatedcatch 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 voidonRemoveCompleted(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 pushD:\workspace_test\MobileSafe\bin\MobileSafe.apk
/system/app/mobilesafe.apk
提示报错信息:
修改系统文件的权限-先进入:
修改系统文件的权限-改权限:
执行指令:mount -o remount ,rw /system/
这个时候再安装软件
C:\Users\Administrator>
adb pushD:\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(Filef : files){
String name = f.getName();
if(f.isDirectory()){
System.out.println(name);
//查询这个文件夹名称是否在数据库中存在,如果存在提示用户删除
}
}
在HomeActivity直接激活它;