MSG 12-15 通过activity启动模式解决任务栈bug
在这里插入代码片
MSG 12-16 不出现在最近任务列表中
<activity
android:name=".activity.AppGraLockActivity"
android:excludeFromRecents="true"
android:launchMode="singleInstance"></activity>
MSG 12-17 AsyncTask 的基本使用
class ApplockTask extends AsyncTask<Void,Void,Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//执行后台耗时操作
@Override
protected Void doInBackground(Void... voids) {
//1、获取所以已安装app
ArrayList<AppManagerInfo> installedApps = AppInfoProvider.getInstalledApps(AppLockActivity.this);
//2、判读是否已加锁,如果已加锁放在已加锁集合
mUnLockList = new ArrayList<>();
mLockList = new ArrayList<>();
for (AppManagerInfo installedApp : installedApps) {
if (dao.query(installedApp.packageName)) {
mLockList.add(installedApp);
} else {
mUnLockList.add(installedApp);
}
}
sort();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
unlockAdapter = new AppLockAdapter(false);
lvUnLock.setAdapter(unlockAdapter);
lockAdapter = new AppLockAdapter(true);
lvLock.setAdapter(lockAdapter);
}
}
new ApplockTask().execute();
MSG 12-18 AsyncTask 的高级使用
/**
* 第一个泛型类型和doInBackground相同
* 第二个泛型类型是进度
* 第三个泛型类型返回结果类型,和doInBackground返回结果类型一致,和onPostExecute参数类型一致
*/
class ApplockTask extends AsyncTask<Object,Integer,String> {
/**
* 预加载,显示进度条
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//执行后台耗时操作
@Override
protected String doInBackground(Object... voids) {
int progress = 0;
progress++;
publishProgress(progress);
return "hello nubia";//返回给onPostExecute
}
/**
* 和第二个泛型类型相同
* 更新进度
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String aVoid) {
super.onPostExecute(aVoid);
}
}
MSG 12-19 流量统计原理
//wifi+data
long totalRxBytes = TrafficStats.getTotalRxBytes();
long totalTxBytes = TrafficStats.getTotalTxBytes();
long mobileRxBytes = TrafficStats.getMobileRxBytes();
long mobileTxBytes = TrafficStats.getMobileTxBytes();
//某app接收和发送总流量
long uidRxBytes = TrafficStats.getUidRxBytes(1000);
long uidTxBytes = TrafficStats.getUidTxBytes(1000);
MSG 13-02 流量统计—初始化数据
@Override
protected Void doInBackground(Void... voids) {
//遍历所有app,获取图标,名称,流量
PackageManager pm = getPackageManager();
List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
mList = new ArrayList<>();
for (PackageInfo packageInfo : installedPackages) {
TrafficInfo trafficInfo = new TrafficInfo();
String packageName = packageInfo.packageName;
ApplicationInfo applicationInfo = packageInfo.applicationInfo;
String name = applicationInfo.loadLabel(pm).toString();
Drawable icon = applicationInfo.loadIcon(pm);
int uid = applicationInfo.uid;
long uidRxBytes = TrafficStats.getUidRxBytes(uid);
long uidTxBytes = TrafficStats.getUidTxBytes(uid);
trafficInfo.packageName=packageName;
trafficInfo.name=name;
trafficInfo.icon=icon;
trafficInfo.rev=uidRxBytes;
trafficInfo.send=uidTxBytes;
mList.add(trafficInfo);
}
return null;
}
MSG 13-03 RecyclerView的基本使用
package cn.nubia.mobilesecurityguard.activity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.net.TrafficStats;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import cn.nubia.mobilesecurityguard.R;
/**
* 流量统计
* 只要重启手机,流量清零
* 数据库保存上次流量,然后追加
*/
public class TrafficStatsActivity extends AppCompatActivity {
private ArrayList<TrafficInfo> mList;
private RecyclerView recycler;
private LinearLayout loading;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_traffic_stats);
initView();
initData();
}
private void initView() {
recycler = findViewById(R.id.recycler);
loading = findViewById(R.id.ll_loading);
}
private void initData() {
new TrafficTask().execute();
}
class TrafficTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
loading.setVisibility(View.VISIBLE);
}
@Override
protected Void doInBackground(Void... voids) {
//遍历所有app,获取图标,名称,流量
PackageManager pm = getPackageManager();
List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
mList = new ArrayList<>();
for (PackageInfo packageInfo : installedPackages) {
TrafficInfo trafficInfo = new TrafficInfo();
String packageName = packageInfo.packageName;
ApplicationInfo applicationInfo = packageInfo.applicationInfo;
String name = applicationInfo.loadLabel(pm).toString();
Drawable icon = applicationInfo.loadIcon(pm);
int uid = applicationInfo.uid;
long uidRxBytes = TrafficStats.getUidRxBytes(uid);
long uidTxBytes = TrafficStats.getUidTxBytes(uid);
trafficInfo.packageName = packageName;
trafficInfo.name = name;
trafficInfo.icon = icon;
trafficInfo.rev = uidRxBytes;
trafficInfo.send = uidTxBytes;
/* if (trafficInfo.rev > 0 || trafficInfo.send > 0) {
mList.add(trafficInfo);
}*/
mList.add(trafficInfo);
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Log.e("gordon", "list = " + mList.size() + "list.String = " + mList.toString());
recycler.setLayoutManager(new LinearLayoutManager(TrafficStatsActivity.this));
TrafficAdapter mAdapter = new TrafficAdapter();
recycler.setAdapter(mAdapter);
//添加分割线
recycler.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDraw(c, parent, state);
}
});
loading.setVisibility(View.GONE);
}
}
class TrafficInfo {
public String packageName;
public String name;
public Drawable icon;
public long rev;
public long send;
@Override
public String toString() {
return "TrafficInfo{" +
"packageName='" + packageName + '\'' +
", name='" + name + '\'' +
", icon=" + icon +
", rev=" + rev +
", send=" + send +
'}';
}
}
class TrafficAdapter extends RecyclerView.Adapter<TrafficHolder> {
@NonNull
@Override
public TrafficHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
//创建一个ViewHolder,初始化条目
View view = View.inflate(TrafficStatsActivity.this, R.layout.item_traffic_info, null);
TrafficHolder holder = new TrafficHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull TrafficHolder holder, final int position) {
//绑定ViewHolder,刷新数据
TrafficInfo info = mList.get(position);
holder.icon.setImageDrawable(info.icon);
holder.name.setText(info.name);
holder.rev.setText("接收:" + Formatter.formatFileSize(getApplicationContext(), info.rev));
holder.send.setText("发送:" + Formatter.formatFileSize(getApplicationContext(), info.send));
//给条目设置点击事件
View itemView = holder.itemView;
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("gordon", "条目:" + position);
}
});
}
@Override
public int getItemCount() {
return mList.size();
}
}
static class TrafficHolder extends RecyclerView.ViewHolder {
ImageView icon;
TextView name;
TextView rev;
TextView send;
public TrafficHolder(@NonNull View itemView) {
super(itemView);
icon = itemView.findViewById(R.id.iv_icon);
name = itemView.findViewById(R.id.tv_name);
rev = itemView.findViewById(R.id.tv_rev);
send = itemView.findViewById(R.id.tv_send);
}
}
/**
* 1.先声明一个TrafficHolder,继承RecyclerView.ViewHolder
* 2.写一个类TrafficAdapter,继承RecyclerView.Adapter,泛型是自定义TrafficHolder
* 3.onCreateViewHolder中创建一个TrafficHolder
*/
}
MSG 13-04 流量统计添加进度条
MSG 13-05 杀毒原理&病毒数据库封装
package cn.nubia.mobilesecurityguard.db.dao;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class VirusDao {
public static boolean isVirus(Context ctx, String md5) {
//读取数据库文件
String dbFilePath = ctx.getFilesDir().getAbsolutePath();
//以只读方式打开数据库,参1:数据库文件的本地路径
SQLiteDatabase database = SQLiteDatabase.openDatabase(dbFilePath + "/antivirus.db", null, SQLiteDatabase.OPEN_READONLY);
Cursor cursor = database.query("datable", null, "md5=?", new String[]{md5}, null, null, null);
boolean isVirus = false;
if (cursor != null) {
if (cursor.moveToFirst()) {
isVirus = true;
}
cursor.close();
}
database.close();
return isVirus;
}
}
MSG 13-06 扫描app判断是否是病毒
MSG 13-07 展示病毒扫描列表
package cn.nubia.mobilesecurityguard.activity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import cn.nubia.mobilesecurityguard.R;
import cn.nubia.mobilesecurityguard.db.dao.VirusDao;
import cn.nubia.mobilesecurityguard.utils.MD5Utils;
/**
* 手机杀毒
* <p>
* 原理
* 手机病毒
* <p>
* 杀毒原理:
* 1、获取所有已安装的app
* 2、对比
*/
public class AntVirusActivity extends AppCompatActivity {
private ArrayList<ScanInfo> virusList;
private ArrayList<ScanInfo> unVirusList;
private RecyclerView recyclerVirus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ant_virus);
initView();
startScanVirus();
}
private void initView() {
recyclerVirus = findViewById(R.id.recycler_virus);
}
private void startScanVirus() {
new VirusTask().execute();
}
class VirusTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
virusList = new ArrayList();
unVirusList = new ArrayList();
}
@Override
protected Void doInBackground(Void... voids) {
//遍历所有app,获取图标,名称,流量
PackageManager pm = getPackageManager();
List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
for (PackageInfo packageInfo : installedPackages) {
ScanInfo scanInfo = new ScanInfo();
String packageName = packageInfo.packageName;
scanInfo.packageName=packageName;
ApplicationInfo applicationInfo = packageInfo.applicationInfo;
String name = applicationInfo.loadLabel(pm).toString();
Drawable icon = applicationInfo.loadIcon(pm);
scanInfo.icon = icon;
scanInfo.name = name;
//获取当前apk文件的安装路径
String sourceDir = applicationInfo.sourceDir;
//计算文件的MD5
String fileMd5 = MD5Utils.getFileMd5(sourceDir);
//判读是否是病毒
boolean virus = VirusDao.isVirus(getApplicationContext(), fileMd5);
Log.e("gordon","virus:" + virus);
scanInfo.isVirus = virus;
if (virus) {
} else {
//unVirusList.add(scanInfo);
}
virusList.add(scanInfo);
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Log.e("gordon","virusList.toString:" + virusList.toString());
recyclerVirus.setLayoutManager(new LinearLayoutManager(AntVirusActivity.this));
recyclerVirus.setAdapter(new VirusAdapter());
}
}
class VirusAdapter extends RecyclerView.Adapter<VirusHolder> {
@NonNull
@Override
public VirusHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
View view = View.inflate(AntVirusActivity.this,R.layout.item_virus_info,null);
VirusHolder holder = new VirusHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull VirusHolder holder, int position) {
ScanInfo info = virusList.get(position);
holder.ivIcon.setImageDrawable(info.icon);
holder.tvName.setText(info.name);
if (info.isVirus) {
holder.tvSafe.setText("病毒");
holder.tvSafe.setTextColor(Color.RED);
} else {
holder.tvSafe.setText("安全");
holder.tvSafe.setTextColor(Color.GREEN);
}
}
@Override
public int getItemCount() {
return virusList.size();
}
}
static class VirusHolder extends RecyclerView.ViewHolder {
TextView tvSafe;
TextView tvName;
ImageView ivIcon;
public VirusHolder(@NonNull View itemView) {
super(itemView);
tvSafe = itemView.findViewById(R.id.tv_safe);
tvName = itemView.findViewById(R.id.tv_name);
ivIcon = itemView.findViewById(R.id.iv_icon);
}
}
class ScanInfo {
public String packageName;
public Drawable icon;
public String name;
public boolean isVirus;
@Override
public String toString() {
return "ScanInfo{" +
"packageName='" + packageName + '\'' +
", icon=" + icon +
", name='" + name + '\'' +
", isVirus=" + isVirus +
'}';
}
}
}
MSG 13-08 扫描过程中刷新RecyclerView
1、在onPreExecute 初始化并设置适配器
@Override
protected void onPreExecute() {
super.onPreExecute();
virusList = new ArrayList();
unVirusList = new ArrayList();
recyclerVirus.setLayoutManager(new LinearLayoutManager(AntVirusActivity.this));
virusAdapter = new VirusAdapter();
recyclerVirus.setAdapter(virusAdapter);
}
2、doInBackground 更新进度
@Override
protected Void doInBackground(Void... voids) {
//遍历所有app,获取图标,名称,流量
PackageManager pm = getPackageManager();
List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
for (PackageInfo packageInfo : installedPackages) {
ScanInfo scanInfo = new ScanInfo();
String packageName = packageInfo.packageName;
scanInfo.packageName=packageName;
ApplicationInfo applicationInfo = packageInfo.applicationInfo;
String name = applicationInfo.loadLabel(pm).toString();
Drawable icon = applicationInfo.loadIcon(pm);
scanInfo.icon = icon;
scanInfo.name = name;
//获取当前apk文件的安装路径
String sourceDir = applicationInfo.sourceDir;
//计算文件的MD5
String fileMd5 = MD5Utils.getFileMd5(sourceDir);
//判读是否是病毒
boolean virus = VirusDao.isVirus(getApplicationContext(), fileMd5);
Log.e("gordon","virus:" + virus);
scanInfo.isVirus = virus;
if (virus) {
virusList.add(0, scanInfo);
} else {
virusList.add(scanInfo);
}
publishProgress();//更新进度
SystemClock.sleep(100);
}
return null;
}
3、onProgressUpdate 刷新界面并滑动到最后条目
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
virusAdapter.notifyDataSetChanged();
//平滑移动到最后一个条目
recyclerVirus.smoothScrollToPosition(virusList.size()-1);
}
MSG 13-09 假冒病毒并测试
MSG 13-10 CircleProgress的使用
https://github.com/lzyzsd/CircleProgress
同步失败:
ERROR: Failed to resolve: com.github.lzyzsd:circleprogress:1.2.1
Show in Project Structure dialog
Affected Modules: app
下载源码包import
MSG 13-11 手机杀毒进度更新
MSG 13-12 展示扫描病毒结果
MSG 13-13 开门动画布局
MSG 13-14 获取布局所展示的截图
MSG 13-15 截取图片一半进行展示
MSG 13-16 开门动画实现
MSG 13-17 重新扫描实现
MSG 13-18 卸载病毒
MSG 13-19 启用&禁用扫描按钮
MSG 13-20 停止异步任务
*MSG 13-21 横竖屏切换