手机卫士2

本文介绍如何通过调整Android应用的启动模式来解决任务栈的问题,并演示了如何利用AsyncTask进行后台任务处理,同时展示了流量统计和手机杀毒功能的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 横竖屏切换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值