【0075】【项目实战】-【手机安全卫士】-【15】高级工具-杀毒模块
1.杀毒模块效果演示
【说明】效果演示

【布局分析】下面信息不断的跳动的是listView控件,信息不断的刷新显示,填充信息是呈逆序;


、
【竖直方向的滚动】信息不能够完全显示,需要滚动显示;

2.布局实现
【页面的跳转】在主页面跳转到杀毒的页面;


【布局的加载】

【动画的合成】两张图片的动画合成;

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 <TextView 7 style="@style/TitleStyle" 8 android:text="手机杀毒"/> 9 <LinearLayout 10 android:orientation="horizontal" 11 android:layout_width="match_parent" 12 android:layout_height="wrap_content"> 13 <RelativeLayout 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content"> 16 <ImageView 17 android:background="@drawable/ic_scanner_malware" //杀毒图片 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content"/> 20 <ImageView 21 android:id="@+id/iv_scanning" 22 android:background="@drawable/act_scanning_03" //杀毒图片 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content"/> 25 </RelativeLayout>
【进度条的构建】
【说明】默认的进度条的是黄色的,现在需要改为绿色的;
【效果】是三种状态;





【下面listView的布局】需要将listView包裹在ScrollView中;

【布局源码】/mobilesafe74/res/layout/activity_anit_virus.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 <TextView 7 style="@style/TitleStyle" 8 android:text="手机杀毒"/> 9 <LinearLayout 10 android:orientation="horizontal" 11 android:layout_width="match_parent" 12 android:layout_height="wrap_content"> 13 <RelativeLayout 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content"> 16 <ImageView 17 android:background="@drawable/ic_scanner_malware" 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content"/> 20 <ImageView 21 android:id="@+id/iv_scanning" 22 android:background="@drawable/act_scanning_03" 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content"/> 25 </RelativeLayout> 26 <LinearLayout 27 android:orientation="vertical" 28 android:gravity="center" 29 android:layout_width="match_parent" 30 android:layout_height="match_parent"> 31 <TextView 32 android:id="@+id/tv_name" 33 android:text="正在扫描应用" 34 android:layout_width="wrap_content" 35 android:layout_height="wrap_content"/> 36 <!-- 自定义进度条图片(三种类型) --> 37 <ProgressBar 38 android:id="@+id/pb_bar" 39 android:progressDrawable="@drawable/progress_bg" 40 style="@android:style/Widget.ProgressBar.Horizontal" 41 android:layout_width="match_parent" 42 android:layout_height="wrap_content"/> 43 </LinearLayout> 44 </LinearLayout> 45 <!-- ScrollView只能有一个直接子节点 --> 46 <ScrollView 47 android:layout_width="match_parent" 48 android:layout_height="wrap_content"> 49 <!-- 将所有的TextView都包裹在内部(将TextView从头部做插入),以满足scrollView有一个子节点 --> 50 <LinearLayout 51 android:id="@+id/ll_add_text" 52 android:orientation="vertical" 53 android:layout_width="wrap_content" 54 android:layout_height="wrap_content"> 55 </LinearLayout> 56 </ScrollView> 57 </LinearLayout>
【效果】

3.病毒数据库查询过程
【说明】数据的文件是借助第三方的数据库,一般是需要收费的;

【说明】在数据库的表中,重要的一项是程序发布时候生成的签名文件的md5;

【病毒查杀的原理】将本地的应用于病毒数据库中记录的内容进行比较,如果存在一致的内容,则标记该内容为病毒;

【数据库的拷贝】将数据库文件拷贝到data/data/包名/File文件下;


【说明】读取数据库的MD5值放到集合list中备用;

4.初始化旋转动画
【说明】扫描旋转的效果是:围绕着中心点进行旋转;

1 private void initAnimation() { 2 RotateAnimation rotateAnimation = new RotateAnimation( 3 0, 360, 4 Animation.RELATIVE_TO_SELF, 0.5f, 5 Animation.RELATIVE_TO_SELF, 0.5f); 6 rotateAnimation.setDuration(1000); 7 //指定动画一直旋转 8 // rotateAnimation.setRepeatMode(RotateAnimation.INFINITE); 9 rotateAnimation.setRepeatCount(RotateAnimation.INFINITE); 10 //保持动画执行结束后的状态 11 rotateAnimation.setFillAfter(true); 12 //一直执行动画 13 iv_scanning.startAnimation(rotateAnimation); 14 } 15 16 private void initUI() { 17 iv_scanning = (ImageView) findViewById(R.id.iv_scanning); 18 tv_name = (TextView) findViewById(R.id.tv_name); 19 pb_bar = (ProgressBar) findViewById(R.id.pb_bar); 20 ll_add_text = (LinearLayout) findViewById(R.id.ll_add_text); 21 }
5.遍历所有的应用,判断应用是否为病毒
【说明1】将所有的扫描的次数作为进度条的总数;





【说明2】更新UI-发送消息,需要更新1:显示的文字(正在扫描或者是扫描完成)更新2:下半部分的listView的数据的更新;

【说明】扫描一次发送一次消息,速度很快;

【增加睡眠时间】在进度增加的时间不能是匀速,用户会觉的扫描大点的应用就会耗时长;使用了随机数;

【说明】发送扫描完成的消息;

【源码】病毒查杀的源码;
1 private void checkVirus() { 2 new Thread(){ 3 public void run() { 4 //获取数据库中所有的病毒的md5码 5 List<String> virusList = VirusDao.getVirusList(); 6 //获取手机上面的所有应用程序签名文件的md5码 7 //1.获取包管理者对象 8 PackageManager pm = getPackageManager(); 9 //2.获取所有应用程序签名文件(PackageManager.GET_SIGNATURES 已安装应用的签名文件+) 10 //PackageManager.GET_UNINSTALLED_PACKAGES 卸载完了的应用,残余的文件 11 List<PackageInfo> packageInfoList = pm.getInstalledPackages( 12 PackageManager.GET_SIGNATURES + PackageManager.GET_UNINSTALLED_PACKAGES); 13 //创建记录病毒的集合 14 15 mVirusScanInfoList = new ArrayList<ScanInfo>(); 16 17 //记录所有应用的集合 18 List<ScanInfo> scanInfoList = new ArrayList<ScanInfo>(); 19 20 //设置进度条的最大值 21 pb_bar.setMax(packageInfoList.size()); 22 23 //3.遍历应用集合 24 for (PackageInfo packageInfo : packageInfoList) { 25 ScanInfo scanInfo = new ScanInfo(); 26 //获取签名文件的数组 27 Signature[] signatures = packageInfo.signatures; 28 //获取签名文件数组的第一位,然后进行md5,将此md5和数据库中的md5比对 29 Signature signature = signatures[0]; 30 String string = signature.toCharsString(); 31 //32位字符串,16进制字符(0-f) 32 String encoder = Md5Util.encoder(string); 33 //4,比对应用是否为病毒 34 if(virusList.contains(encoder)){ 35 //5.记录病毒 36 scanInfo.isVirus = true; 37 mVirusScanInfoList.add(scanInfo); 38 }else{ 39 scanInfo.isVirus = false; 40 } 41 //6,维护对象的包名,以及应用名称 42 scanInfo.packageName = packageInfo.packageName; 43 scanInfo.name = packageInfo.applicationInfo.loadLabel(pm).toString(); 44 scanInfoList.add(scanInfo); 45 //7.在扫描的过程中,需要更新进度条 46 index++; 47 pb_bar.setProgress(index); 48 49 try { 50 Thread.sleep(50+new Random().nextInt(100)); 51 } catch (InterruptedException e) { 52 e.printStackTrace(); 53 } 54 55 //8.在子线程中发送消息,告知主线程更新UI(1:顶部扫描应用的名称2:扫描过程中往线性布局中添加view) 56 Message msg = Message.obtain(); 57 msg.what = SCANING; 58 msg.obj = scanInfo; 59 mHandler.sendMessage(msg); 60 } 61 Message msg = Message.obtain(); 62 msg.what = SCAN_FINISH; 63 mHandler.sendMessage(msg); 64 }; 65 }.start(); 66 } 67 68 class ScanInfo{ 69 public boolean isVirus; //标注是否为病毒; 70 public String packageName; //应用卸载的时候需要使用到包名; 71 public String name; //应用的名称; 72 }
【针对消息的处理】针对不同的消息进行处理;
1 private Handler mHandler = new Handler(){ 2 public void handleMessage(android.os.Message msg) { 3 switch (msg.what) { 4 case SCANING: 5 //1,显示正在扫描应用的名称 6 ScanInfo info = (ScanInfo)msg.obj; 7 tv_name.setText(info.name); 8 //2,在线性布局中添加一个正在扫描应用的TextView 9 TextView textView = new TextView(getApplicationContext()); 10 if(info.isVirus){ 11 //是病毒 12 textView.setTextColor(Color.RED); 13 textView.setText("发现病毒:"+info.name); 14 }else{ 15 //不是病毒 16 textView.setTextColor(Color.BLACK); 17 textView.setText("扫描安全:"+info.name); 18 } 19 ll_add_text.addView(textView, 0); 20 break; 21 case SCAN_FINISH: 22 tv_name.setText("扫描完成"); 23 //停止真正执行的旋转动画 24 iv_scanning.clearAnimation(); 25 //告知用户卸载包含了病毒的应用 26 unInstallVirus(); 27 break; 28 } 29 }; 30 };
【病毒程序的卸载】使用意图卸载;
1 protected void unInstallVirus() { 2 for(ScanInfo scanInfo:mVirusScanInfoList){ 3 String packageName = scanInfo.packageName; 4 //源码 5 Intent intent = new Intent("android.intent.action.DELETE"); 6 intent.addCategory("android.intent.category.DEFAULT"); 7 intent.setData(Uri.parse("package:"+packageName)); 8 startActivity(intent); 9 } 10 }
【效果】

【BUG】动画只转一圈【原因】api调用错误

【病毒测试】在数据库的列表中添加一个手机中已经安装的程序的包名的md5值;
浙公网安备 33010602011771号