138.s1-防毒功能的實現

augfun發表於2017-04-24

防毒的原理是首先擁有一個病毒庫,病毒庫是一個資料庫,每個病毒會有md5值,通過遍歷病毒庫,檢視是否有病毒的md5,因此首先需要把assert目錄下面的病毒庫拷貝到file資料夾才能處理

殺病毒的介面activity_antivirous.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" >
    
    <TextView 
        style="@style/TitleStyle"
        android:text="病毒查殺"
        />
    <LinearLayout 
        android:layout_width="match_parent"
    	android:layout_height="wrap_content"
    	android:orientation="horizontal"
    	android:layout_marginTop="10dp"
        >
        <FrameLayout 
        android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
        	>
		    <ImageView 
		        android:layout_width="wrap_content"
		    	android:layout_height="wrap_content"
		    	android:layout_marginLeft="5dp"
		    	android:layout_marginRight="5dp"
		    	android:background="@drawable/ic_scanner_malware"
		        />
		    <ImageView 
		        android:id="@+id/iv_scanning"
		        android:layout_width="wrap_content"
		    	android:layout_height="wrap_content"
		    	android:layout_marginLeft="5dp"
		    	android:layout_marginRight="5dp"
		    	android:background="@drawable/act_scanning_03"
		        />
	    </FrameLayout>
		<LinearLayout 
			android:layout_width="match_parent"
	    	android:layout_height="wrap_content" 
	    	android:layout_marginTop="10dp"
	    	android:orientation="vertical"
		    >
		    <TextView 
		        android:id="@+id/tv_init_virus"
		        android:layout_width="match_parent"
	    		android:layout_height="wrap_content"
	    		android:gravity="center_horizontal"
	    		android:textColor="@color/black"
	    		android:text="初始化防毒引擎"
		        />
		    <ProgressBar 
		        android:id="@+id/progressBarVirous"
		        style="?android:attr/progressBarStyleHorizontal"
		        android:layout_width="match_parent"
	    		android:layout_height="wrap_content"
	    		android:layout_marginLeft="5dp" 
	    		android:layout_marginRight="10dp"
		        />
		</LinearLayout>
    </LinearLayout>
    
    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <LinearLayout
            android:id="@+id/ll_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >
        </LinearLayout>
    </ScrollView>
   
</LinearLayout>

獲取檔案的md5值MD5Utils.java

package com.ldw.safe.utils;

import java.io.File;
import java.io.FileInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Utils {

	/**
	 * md5加密,md5永遠是32位
	 * 
	 * @param password
	 * @return
	 */
	public static String encode(String password) {
		try {
			MessageDigest instance = MessageDigest.getInstance("MD5");//獲取MD5演算法物件
			byte[] digest = instance.digest(password.getBytes());//對字串加密,返回字元陣列

			StringBuffer sb = new StringBuffer();
			for (byte b : digest) {
				int i = b & 0xff;//取位元組的低8位有效值
				String hexString = Integer.toHexString(i);//將整數轉為16進位制

				if (hexString.length() < 2) {
					hexString = "0" + hexString;//如果只有1位就補零
				}

				sb.append(hexString);
			}

			return sb.toString();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			//沒有該演算法的時候,丟擲異常
		}

		return "";
	}

	/*
	 * 獲取到檔案的MD5值,檔案的特徵碼
	 */
	public static String getFileMd5(String sourceDir) {
		
		
		try {
			//建立一個流來讀取檔案
			File file = new File(sourceDir);
			FileInputStream fis = new FileInputStream(file);
			byte[] buffer = new byte[1024];
			int len = -1;
			
			MessageDigest messageDigest = MessageDigest.getInstance("md5");
			
			while((len = fis.read(buffer)) != -1){
				//獲取到數字摘要
				messageDigest.update(buffer, 0, len);
			}
			byte[] result = messageDigest.digest();
			
			StringBuffer sb = new StringBuffer();
			for (byte b : result) {
				int i = b & 0xff;//取位元組的低8位有效值
				String hexString = Integer.toHexString(i);//將整數轉為16進位制

				if (hexString.length() < 2) {
					hexString = "0" + hexString;//如果只有1位就補零
				}

				sb.append(hexString);
			}
			return sb.toString();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}

殺病毒的邏輯文AntiVirousActivity.java

package com.ldw.safe.Activity;

import java.util.List;

import android.app.Activity;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TextView;

import com.ldw.safe.R;
import com.ldw.safe.db.dao.AntiVirous;
import com.ldw.safe.utils.MD5Utils;

public class AntivirusActivity extends Activity {
	
	protected static final int BEGIN = 1;
	protected static final int SCANING = 2;
	protected static final int FINISH = 3;
	private Message message;
	private TextView tv_init_virus;
	private ProgressBar pb;
	private ImageView iv_scanning;
	private LinearLayout ll_content;
	private ScrollView scrollView;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        initUi();
        initData();
        }
	
	Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg){
			switch(msg.what){
			case BEGIN:
				tv_init_virus.setText("初始化八核引擎");
				break;

			case SCANING:
				// 病毒掃描中:
				//建立一個TextView,存放應用的名字使用scanInfo
				TextView child = new TextView(AntivirusActivity.this);

				ScanInfo scanInfo = (ScanInfo) msg.obj;
				// 如果為true表示有病毒
				if (scanInfo.desc) {
					child.setTextColor(Color.RED);
					child.setText(scanInfo.appName + "有病毒");

				} else {
					child.setTextColor(Color.BLACK);
					// 為false表示沒有病毒
					child.setText(scanInfo.appName + "掃描安全");

				}
				//更新下面的掃描的檔案
				ll_content.addView(child, 0);
				//自動滾動
				scrollView.post(new Runnable() {
					
					@Override
					public void run() {
						//一直往下面進行滾動
						scrollView.fullScroll(scrollView.FOCUS_DOWN);
						
					}
				});
	
				System.out.println(scanInfo.appName + "掃描安全");
				break;
			case FINISH:
				// 當掃描結束的時候。停止動畫
				iv_scanning.clearAnimation();
				break;
			}
		};
	};


	//初始化資料
	private void initData() {
		
		new Thread(){

			public void run(){
				
				message = Message.obtain();
				//掃描病毒開始
				message.what = BEGIN;
				
				//獲取到包管理器
				PackageManager packageManager = getPackageManager();
				// 獲取到所有安裝的應用程式
				List<PackageInfo> installedPackages = packageManager
						.getInstalledPackages(0);
				// 返回手機上面安裝了多少個應用程式
				int size = installedPackages.size();
				//設定進度條的最大值
				pb.setMax(size); 
				//初始化進度條狀態
				int progress = 0;
				
				for(PackageInfo packageInfo:installedPackages){
					
					ScanInfo scanInfo = new ScanInfo();
					
					// 獲取到當前手機上面的app的名字
					String appName = packageInfo.applicationInfo.loadLabel(
							packageManager).toString();
					//初始化scanInfo
					scanInfo.appName = appName;
					//獲取到應用的包名
					String packageName = packageInfo.applicationInfo.packageName;
					scanInfo.packageName = packageName;
					
					// 首先需要獲取到每個應用程式的目錄
					String sourceDir = packageInfo.applicationInfo.sourceDir;
					// 獲取到檔案的md5
					String md5 = MD5Utils.getFileMd5(sourceDir);
					// 判斷當前的檔案是否是病毒資料庫裡面
					String desc = AntiVirous.checkFileVirous(md5);
					
					// 如果當前的描述資訊等於null說明沒有病毒
					if (desc == null) {
						scanInfo.desc = false;
					} else {
						scanInfo.desc = true;
					}
					//進度條更新
					progress ++;
					//殺一次,休眠100
					SystemClock.sleep(100);
					pb.setProgress(progress);
					
					message =Message.obtain();
					//掃描病毒中
					message.what = SCANING;
					message.obj = scanInfo;
					
					handler.sendMessage(message);
				}
				
				message =Message.obtain();
				//掃描病毒後
				message.what = FINISH;
				handler.sendMessage(message);
			};
		}.start();
		
	}
	
	//掃描的資訊
	static class ScanInfo {
		boolean desc;
		String appName;
		String packageName;
	}

	//初始化UI
	private void initUi() {
		setContentView(R.layout.activity_antivirous);

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

		pb = (ProgressBar) findViewById(R.id.progressBarVirous);
		
		iv_scanning = (ImageView) findViewById(R.id.iv_scanning);
		
		ll_content = (LinearLayout) findViewById(R.id.ll_content);
		
		scrollView = (ScrollView) findViewById(R.id.scrollView);
		
		// 第一個參數列示開始的角度 第二個參數列示結束的角度 第三個參數列示參照自己 初始化旋轉動畫
		RotateAnimation rotateAnimation = new RotateAnimation(0, 360,
				Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
				0.5f);
		// 設定動畫的時間
		rotateAnimation.setDuration(5000);
		// 設定動畫無限迴圈
		rotateAnimation.setRepeatCount(Animation.INFINITE);
		// 開始動畫
		iv_scanning.startAnimation(rotateAnimation);
		
	}

}

工具類實現病毒的庫的遍歷(查殺病毒)AntiVirous.java

package com.ldw.safe.db.dao;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

/*
 * 殺病毒的dao,檢查當前的md5是否在病毒資料庫
 */
public class AntiVirous {

	
	public static String checkFileVirous(String md5){
		//返回定都的描述
		String desc = null;
		
		//資料庫的路徑,前面是data/data後面跟著包的名字,路徑必須要這樣寫
		final String path ="data/data/com.ldw.safe/files/antivirus.db";
		//讀取資料庫
		SQLiteDatabase database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
		
		//查詢當前傳過來的md5是否在病毒資料庫裡面
		Cursor cursor = database.rawQuery("select desc from datable where md5 = ?", new String[]{md5});
		//判斷當前的遊標是否可以移動
		if(cursor.moveToNext()){
			desc = cursor.getString(0);
		}
		cursor.close();
		return desc;
	}
	
	/*
	 * 新增病毒
	 */
	public static void addVirus(String md5,String desc){
		
	}
}

 

 

 

 

 

 

相關文章