手机杀毒的原理是利用手机里应用的MD5和已发现的病毒库的MD5进行比较,如果两者相同,则说明检测的软件有病毒
1.1.xml文件布局
这里首先分析常见的杀毒软件的布局,一个动画旋转的类似雷达扫描的旋转动画,和一个进度条,还有不断滚动的文字:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="手机杀毒"
style="@style/TitelTheme" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:background="@drawable/main_circle_bg_scan"
android:id="@+id/imv_scan"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_gravity="center"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_gravity="center"
android:id="@+id/tv_scan"
android:text="扫描完成"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar
android:progressDrawable="@drawable/progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:id="@+id/pb_scan"
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:id="@+id/ll_add_text"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
</ScrollView>
</LinearLayout>
2.在activity中找到相应的控件:
private void initUI() {
im_scan= (ImageView) findViewById(R.id.imv_scan);
tv_scan= (TextView) findViewById(R.id.tv_scan);
progressBar= (ProgressBar) findViewById(R.id.pb_scan);
ll_add_text= (LinearLayout) findViewById(R.id.ll_add_text);
}
3.初始化数据:
1.antivirus.db病毒数据库,复制到assets文件夹下,并把文件复制到files文件夹下:复制工具类代码如下:
/**
* 初始化地址数据库
* @param dbname 数据库名称
*/
private void initAdressDB(String dbname) {
File filesDir = getFilesDir();
File file = new File(filesDir, dbname);
InputStream open=null;
FileOutputStream fos=null;
if (file.exists()){
return;
}
try {
open = getAssets().open(dbname);
fos=new FileOutputStream(file);
byte[] bytes = new byte[1024];
int temp=-1;
while ((temp=open.read(bytes))!=-1){
fos.write(bytes,0,temp);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fos.close();
open.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.在进入界面调用此方法
private void initDB() {
initAdressDB("antivirus.db");
}
3.建立读取数据库的类:
public static String path="data/data/xiangcuntiandi.mobailsafe/files/antivirus.db";
public static ArrayList<String> getVirusList(){
SQLiteDatabase sqLiteDatabase = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
Cursor cursor = sqLiteDatabase.query("datable", new String[]{"md5"}, null, null, null, null, null, null);
ArrayList<String> list = new ArrayList<>();
while (cursor.moveToNext()){
String md5 = cursor.getString(0);
list.add(md5);
}
cursor.close();
sqLiteDatabase.close();
return list;
4.在activity中调用此方法:由于读取数据库是耗时操作,因此需要放在子线程中进行:并且读取本地的软件的Md5值,与库中的进行比较:
new Thread(){
@Override
public void run() {
//读取数据库所有的md5值放到集合中
ArrayList<String> virusList = VirusDao.getVirusList();
//包管理器:
PackageManager packageManager = getPackageManager();
//获取包的集合
List<PackageInfo> installedPackages = packageManager.getInstalledPackages(PackageManager.GET_SIGNATURES + PackageManager.GET_UNINSTALLED_PACKAGES);
//病毒集合
mViraScanInfos = new ArrayList<>();
//非病毒集合
mScanInfos = new ArrayList<>();
progressBar.setMax(installedPackages.size());
for (PackageInfo installedPackage : installedPackages) {
ScanInfo scanInfo=new ScanInfo();
Signature[] signatures = installedPackage.signatures;
Signature signature = signatures[0];
String s = signature.toCharsString();
String s1 = MD5Utils.md5(s);
Log.e("at22",s1);
if (virusList.contains(s1)){
//记录病毒
scanInfo.isVirus=true;
mViraScanInfos.add(scanInfo);
}else {
//非病毒
scanInfo.isVirus=false;
}
scanInfo.packageName=installedPackage.packageName;
scanInfo.name = installedPackage.applicationInfo.loadLabel(packageManager).toString();
mScanInfos.add(scanInfo);
index++;
progressBar.setProgress(index);
//在子线程中发送消息更新UI
try {
Thread.sleep(50+new Random().nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg = Message.obtain();
msg.what=SCANING;
msg.obj=scanInfo;
mHandler.sendMessage(msg);
}
//结束标志
Message msg = Message.obtain();
msg.what=SCANINGFINISH;
mHandler.sendMessage(msg);
}
}.start();
5.旋转动画;
private void initAnimation() {
rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(1000);
rotateAnimation.setRepeatCount(RotateAnimation.INFINITE);
rotateAnimation.setFillAfter(true);
im_scan.startAnimation(rotateAnimation);
}
6.主线程中更新UI
private Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case SCANING:
ScanInfo info= (ScanInfo) msg.obj;
tv_scan.setText(info.name);
TextView textView=new TextView(getApplicationContext());
if (info.isVirus){
textView.setTextColor(Color.RED);
textView.setText("发现病毒"+info.packageName);
}else {
textView.setTextColor(Color.BLACK);
textView.setText("扫描安全"+info.packageName);
}
//把view加到 LinearLayout中
ll_add_text.addView(textView,0);
break;
case SCANINGFINISH:
tv_scan.setText("扫描完成");
im_scan.clearAnimation();
unInStallVi();
break;
}
}
};