金山手机卫士-清除缓存-手机杀毒-抽屉原理

学习到的内容:

     1)抽屉原理

     2)手机杀毒的原理

    3)杀毒UI界面实现【挺有意思的】

    4)利用反射获取应用程序缓存和应用程序大小

    5)清理缓存

 整个项目源代码:http://download.csdn.net/detail/itjavawfc/8383617

部分UI界面如下:

金山手机卫士-清除缓存-手机杀毒-抽屉原理_第1张图片          金山手机卫士-清除缓存-手机杀毒-抽屉原理_第2张图片              金山手机卫士-清除缓存-手机杀毒-抽屉原理_第3张图片


系统中获取各个应用程序流量的API方法:

public class TrafficManagerActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	//1.获取一个包管理器
		PackageManager pm=getPackageManager();
		//2.遍历手机系统 获取所有的应用程序UID
		List<ApplicationInfo> applicationInfos=pm.getInstalledApplications(0);
		for(ApplicationInfo applicationInfo:applicationInfos){
			int uid=applicationInfo.uid;
			long tx=TrafficStats.getUidTxBytes(uid);//发送上传的流量
			long rx=TrafficStats.getUidRxBytes(uid);//下载的流量Byte
			
		}
		TrafficStats.getMobileRxBytes(); //手机2g、3g网络下载流量综合
		TrafficStats.getMobileTxBytes(); //手机2g、3g网络上传流量综合
		
		TrafficStats.getTotalTxBytes();  //手机全部网络接口 包括wifi,3g、2g网络上传流量综合
		TrafficStats.getTotalTxBytes();  //手机全部网络接口 包括wifi,3g、2g网络下载流量综
		setContentView(R.layout.activity_traffic_manage);
		
	
	}
}

抽屉原理:看布局【三部分内容:1.整个布局就是一个SlidingDrawer布局(里面必须包含把手和内容布局的ID)    2.把手布局     3.内容布局】

<?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" >
    <SlidingDrawer
        android:orientation="horizontal"
        android:id="@+id/my_drawer"
        android:layout_width="fill_parent"
	    android:layout_height="fill_parent"
	    android:content="@+id/my_content"
        android:handle="@+id/my_handle"
         >
        <LinearLayout
        android:id="@id/my_handle"
        android:layout_width="wrap_content"
        android:orientation="vertical"
	    android:layout_height="fill_parent"
             >
  <!-- 把手布局 -->
   <ImageView 
        android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:src="@drawable/lock" 
            />
   </LinearLayout>
   <!-- 内容布局 -->
   <LinearLayout 
       android:background="#22000000"
       android:id="@id/my_content"
       android:layout_width="fill_parent"
	   android:layout_height="fill_parent"
	   android:gravity="center"
       >
       <TextView 
        android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:text="我是抽屉里面的内容"   
           />
   </LinearLayout>
</SlidingDrawer>
</LinearLayout>

手机杀毒原理:

传统杀毒软件的工作原理: 
扫描硬盘上的每个文件,分析这些文件特征码,
查看病毒文件的特征是否在病毒数据库存在。
校验文件的md5 sha1签名。
算法提权软件的关键信息。
遍历文件里面的字符串。http://


手机杀毒的步骤:1.获取每个程序的sha1或者md5码

                                 2.看数据库、云服务存储服务病毒库中有没有该md5码

给一个文件名,获得md5码

<strong> * 获取文件SHA1的值</strong>
	 * @param path 文件的全路径
	 */
	private String getFileSHA(String path){
		//获取一个文件的特征信息,签名信息
		File file=new File(path);
		//md5
		try {
			 // 拿到一个sha1转换器(同样,这里可以换成MD5)
			MessageDigest digest=MessageDigest.getInstance("sha1");
		    FileInputStream fis=new FileInputStream(file);
		    byte[] buffer=new byte[1024];
		    int len=-1;
		    // read的过程中进行sha1处理,直到读完文件
		    while((len=fis.read(buffer))!=-1){
		    	digest.update(buffer, 0, len);
		    }
		  byte[] result=digest.digest();
		  StringBuffer sb=new StringBuffer();
		  for(byte b:result){
			  //与运算
			  int number=b & 0xff;  //加盐
			  String str=Integer.toHexString(number);
			  if(str.length()==1){
				  sb.append("0");
			  }
			  sb.append(str);
		  }
		  return sb.toString();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "";
		}
		
	}
	

扫描病毒的方法:这里面用到了内部类、Handler、Message【非常重要】、仿照源码的一个进度条

/*
 * 扫描病毒
 */
	private void scanVirus() {
		pm=getPackageManager();
		tv_scan_status.setText("正在初始化杀毒引擎.....");
	    new Thread(){
			public void run(){
	    		 List<PackageInfo> infos=pm.getInstalledPackages(0);
	    		 try {
					Thread.sleep(500);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
	    		 progressBar1.setMax(infos.size());
	    		 int progress=0;
	    		 for(PackageInfo info:infos){
	    			 //apk文件的完整的路径
	    		    String sourcedir=info.applicationInfo.sourceDir;
	    		    //得到.apk文件的sha1签名
	    			String sha1=getFileSHA(sourcedir);
	    			ScanInfo scaninfo=new ScanInfo();
	    			scaninfo.name=info.applicationInfo.loadLabel(pm).toString();
	    			scaninfo.packname=info.packageName;
	    		    //查询md5信息,是否在病毒数据库里面存着
	    			if(AntivirsuDao.isVirus(sha1)){
	    				 //发现病毒
	    				scaninfo.isvirus=true;
	    			}else{
	    				//扫描安全
	    				scaninfo.isvirus=false;
	    			}
	    			
	    			Message msg=Message.obtain();
	    			msg.obj=scaninfo;
					msg.what=SCANING;
	    			handler.sendMessage(msg);
	    			
	    			try {
						Thread.sleep(300);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
	    			progress++;
	    			progressBar1.setProgress(progress);
	    			
	    		 }
	    		 Message msg=Message.obtain();
	    		 msg.what=FINISH;
	    		 handler.sendMessage(msg);
	    	}
	    }.start();
	}


自定义ProgressBar的实现:style="@style/my_pb_style"

<style name="my_pb_style" parent="@android:style/Widget.ProgressBar.Horizontal">
                <item name="android:progressDrawable">@drawable/progress_horizontal</item>
    </style>

draw里面一个文件:

<?xml version="1.0" encoding="utf-8"?>
<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>

在数据库中查找是否存在签名后的md5码或者sha1码

/**
 * 病毒数据库查询业务类
 * @author Administrator
 *
 */
public class AntivirsuDao {
	/*
	 * 查询一个md5是否在病毒数据库里面存在
	 */
	 public static boolean isVirus(String md5){
		 String path="/data/data/com.example.mobilesafe/files/antivirus.db";
		boolean result = false;
		//打开病毒数据库文件
		SQLiteDatabase db = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
		Cursor cursor = db.rawQuery("select * from datable where md5=?", new String[]{md5});
		if(cursor.moveToNext()){
			result = true;
		}
		cursor.close();
		db.close();
		return result;
	}
}

Handler接收消息并更新界面:【这个基本技能必须熟练】

  private Handler handler=new Handler(){
		@Override
		public void handleMessage(Message msg) {
			//super.handleMessage(msg);
			switch(msg.what){
			case SCANING:
				ScanInfo scanInfo=(ScanInfo) msg.obj;
				tv_scan_status.setText("正在扫描:"+scanInfo.name);
				TextView tv=new TextView(getApplicationContext());
			    if(scanInfo.isvirus){
			    	tv.setTextColor(Color.RED);
			    	tv.setText("发现病毒:"+scanInfo.name);
			    }else{
			    	tv.setTextColor(Color.BLACK);
			    	tv.setText("扫描安全:"+scanInfo.name);
			    }
				ll_container.addView(tv,0);
				//把一个控件上的动画清除掉
				iv_scan.clearAnimation();
				break;
				
			case FINISH:
				tv_scan_status.setText("扫描完毕");
				
				break;
			}
		}
    	
    };
这个方法非常有意思: ll_container.addView(tv,0);

LinearLayout不断的加入:text,而且是一个接着一个加入


定义了一个动画:一直旋转,增强立体感。

 RotateAnimation ra=new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
	    ra.setDuration(1000);
	    ra.setRepeatCount(Animation.INFINITE);
	    iv_scan.startAnimation(ra);
	    progressBar1=(ProgressBar) findViewById(R.id.progressBar1);


缓存清理:做了两方面内容,1扫描缓存区的所有内容   2.清除所有缓存【按照源码,一步一来写下来】

     注意项:1.使用到了AIDL

                     2.获得缓存相关信息必须通过反射强制得到相关的方法后执行【回顾反射机制,反射执行原理】

                    3.内部类使用的局部变量必须声明为final型

                   4.单个程序的缓存是无法清除的,只有系统自己才有这个权限,就算加了权限仍然不可用:【实现清除缓存原理是:利用Android内存漏洞,设置其缓存已全部用完,系统就会执行清除所有缓存的操作】

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

代码如下:

public class CleanCacheActivity extends Activity {
	private ProgressBar pb;
	private TextView tv_scan_status;
	private PackageManager pm;
	private LinearLayout ll_container;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_clean_cache);
		pb=(ProgressBar) findViewById(R.id.pb);
		tv_scan_status=(TextView) findViewById(R.id.tv_scan_status);
		ll_container=(LinearLayout) findViewById(R.id.ll_container);
		scanCache();
	}
	private void scanCache() {

		pm=getPackageManager();
		new Thread(){
			public void run(){
				Method[] methods=PackageManager.class.getMethods();
				Method getPackageSizeInfoMethod = null;
				for(Method method:methods){
			      if("getPackageSizeInfo".equals(method.getName())){
			    	  getPackageSizeInfoMethod=method;
			      }
				}
				List<PackageInfo> packInfos=pm.getInstalledPackages(0);
				pb.setMax(packInfos.size());
				int progress=0;
				
				for(PackageInfo packInfo:packInfos){
					try {
						getPackageSizeInfoMethod.invoke(pm, packInfo.packageName,new MyDataObserver());
						Thread.sleep(50);
					} catch (Exception e) {
						e.printStackTrace();
					}
					progress++;
					pb.setProgress(progress);
				}
				runOnUiThread(new Runnable(){
					@Override
					public void run() {
						tv_scan_status.setText("扫描完毕.....");
					}
				});
			};
		}.start();
	}
	
	private class MyDataObserver extends IPackageStatsObserver.Stub{
		@Override
		public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
				throws RemoteException {

		final	long cache=pStats.cacheSize;
		final	long code=pStats.codeSize;
	    final	long data=pStats.dataSize;
			final String packname=pStats.packageName;
			final ApplicationInfo appInfo;
			
			try {
				appInfo=pm.getApplicationInfo(packname, 0);
				   runOnUiThread(new Runnable(){
					public void run() {   //SmartcardService
						tv_scan_status.setText("正在扫描:"+appInfo.loadLabel(pm));
						if(appInfo.loadLabel(pm).equals("SmartcardService")){
							tv_scan_status.setText("扫描完毕.....");
						}
						if(cache>0){
							View view=View.inflate(getApplicationContext(),R.layout.list_item_cacheinfo,null);
							TextView tv_cache=(TextView) view.findViewById(R.id.tv_cache_size);
							tv_cache.setText("缓存大小:"+Formatter.formatFileSize(getApplicationContext(), cache));
							TextView tv_name=(TextView) view.findViewById(R.id.tv_app_name);
							tv_name.setText(appInfo.loadLabel(pm));
							
							//清理全部缓存
							ImageView iv_delete=(ImageView) view.findViewById(R.id.iv_delete);
							iv_delete.setOnClickListener(new OnClickListener() {
								
								@Override
								public void onClick(View v) {
                                 try {
                                	 //拿到方法的字节码
									Method method=PackageManager.class.getMethod("deleteApplicationCacheFiles", String.class,IPackageDataObserver.class);
								    method.invoke(pm, packname,new MypackDataObserver());
                                  } catch (Exception e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							  }
							});
							ll_container.addView(view,0);
						}
					}
				   });
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	private class MypackDataObserver extends IPackageDataObserver.Stub{

		@Override
		public void onRemoveCompleted(String packageName, boolean succeeded)
				throws RemoteException {
		}
	}
	/*
	 * 清理手机的全部缓存
	 * 
	 */
	public void clearAll(View view){
		Method[] methods = PackageManager.class.getMethods();
		for(Method method:methods){
			if("freeStorageAndNotify".equals(method.getName())){
				try {
					method.invoke(pm, Integer.MAX_VALUE,new MypackDataObserver());
				} catch (Exception e) {
					e.printStackTrace();
				}
				return;
			}
		}
	}
}
         

你可能感兴趣的:(清除缓存,手机杀毒,抽屉原理)