黑马52期学后总结笔记(十)

来源:互联网 发布:诸葛恪 淘宝 编辑:程序博客网 时间:2024/05/21 10:32


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-listxmlns: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:创建新工程“获取应用的缓存”

布局文件:

<LinearLayoutxmlns: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 extendsIPackageStatsObserver.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,newMyObserver());

                    return;

                }

        }

 

 

需要加权限:

  <uses-permissionandroid: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"?>

<LinearLayoutxmlns: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,newIPackageDataObserver.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-permissionandroid: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

                                        publicvoidonRemoveCompleted(String packageName,boolean succeeded)

                                                throws RemoteException {

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

                                        }

                                    });

                                    return;

                                } catch (Exception e) {

                                    e.printStackTrace();

                                }

                            }

        }

                       

                  

 

 

加权限

 <uses-permissionandroid: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直接激活它;

 

 

 

 

 

0 0
原创粉丝点击