手机卫士涉及的知识点总结(二)

可扩展的ListView(ExpandableListView控件)

public class QuerryUsualNumber extends Activity {

    private ExpandableListView exl_listview;
    private SQLiteDatabase db;
    private TextView tv;
    private MyExpandableAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        db=SQLiteDatabase.openDatabase("/data/data/com.cca.mobilephone/files/commonnum.db", null, SQLiteDatabase.OPEN_READONLY);

        setContentView(R.layout.activity_querryusualnumber);

        exl_listview = (ExpandableListView) findViewById(R.id.exl_listview);
        adapter = new MyExpandableAdapter();
        //设置适配器
        exl_listview.setAdapter(adapter);

        //孩子被点击的监听器
        exl_listview.setOnChildClickListener(new OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                    int groupPosition, int childPosition, long id) {
                //点击条目获得数据库返回的数据,并分割提取号码进行拨号                    
                String data=UsualNumberDao.getChildrenNameByPosition(db, groupPosition, childPosition);
                String datas[]=data.split("\n");
                String name=datas[0];

                String number=datas[1];
                Toast.makeText(getApplicationContext(), groupPosition+"--"+childPosition+":"+name+":"+number, 0).show();

                //点击之后进行拨打指定号码的电话
                Intent intent =new Intent();
                intent.setAction(Intent.ACTION_CALL);
                intent.setData(Uri.parse("tel:"+number));
                startActivity(intent);

                return true;
            }
        });
}
适配器
private class MyExpandableAdapter extends BaseExpandableListAdapter{

    /**
     * 获取分组的个数
     */
    @Override
    public int getGroupCount() {
        return UsualNumberDao.getGroupCount(db);
    }
    /**
     * 获取每个分组的孩子的个数
     */
    @Override
    public int getChildrenCount(int groupPosition) {
        return UsualNumberDao.getChildGroupCount(db,groupPosition);
    }
    @Override
    public Object getGroup(int groupPosition) {
        return null;
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return null;
    }
    @Override
    public long getGroupId(int groupPosition) {
        return 0;
    }
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return 0;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }
    /**
     * 返回每个分组的view对象
     */
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent) {
        //TextView tv;
        if(convertView==null){
        tv=new TextView(QuerryUsualNumber.this);
        }else{
            tv=(TextView) convertView;
        }
        tv.setTextSize(25);
        tv.setTextColor(Color.RED);
        tv.setText("      "+UsualNumberDao.getNameByGroupCountposition(db,groupPosition));
        return tv;
    }
    @Override
    public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {

        if(convertView==null){
        tv=new TextView(QuerryUsualNumber.this);
        }else{
            tv=(TextView) convertView;
        }   
        tv.setTextSize(20);
        tv.setTextColor(Color.BLACK);
        tv.setText(" "+UsualNumberDao.getChildrenNameByPosition(db,groupPosition, childPosition));
        return tv;
    }
    @Override
    public boolean isChildSelectable(int groupPosition,
            int childPosition) {

        return true;
    }
}
@Override
protected void onDestroy() {
    super.onDestroy();
    db.close();

}

接口回调解耦的应用(用短信备份加进度条对话框来举例)

/**
 * 短信备份
 * 
 * @param view
 */
public void SMSBackUp(View view) {
    /**
     * 直接弹出一个进度条对话框
     */
    final ProgressDialog pb = new ProgressDialog(this);
    pb.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    pb.setMessage("正在备份......");

    pb.show();// show出来才能看得见
    new Thread() {
        public void run() {

            boolean result = SMSTool.SmsBackup(
                    new SMSTool.SmsBackupCallBack() {
                        /**
                         * 接口里面的方法
                         */
                        @Override
                        public void callBackprogress(int progress) {
                            pb.setProgress(progress);
                        }

                        /**
                         * 接口里面的方法
                         */
                        @Override
                        public void callBackMax(int max) {
                            pb.setMax(max);
                        }
                    }, ToolActivity.this, "back.xml");
            if (result) {
                ToastUtils.show(ToolActivity.this, "备份成功");
            } else {
                ToastUtils.show(ToolActivity.this, "备份失败");

            }
            pb.dismiss();// 是否备份成功对话框都消失
        };
    }.start();

}
短信备份的逻辑:
    /**
 * 短信备份的工具类
 * 
 * @author Administrator
 * 
 */
public class SMSTool {

/**
 * 接口回调,定义一些抽象方法
 * 
 * @author Administrator
 * 
 */
public interface SmsBackupCallBack {
    /**
     * 接口回调
     * 
     * @param max  最大值
     *           
     */
    public abstract void callBackMax(int max);

    /**
     * 接口回调
     * 
     * @param progress
     */
    public abstract void callBackprogress(int progress);

}

/**
 * 短信备份的业务逻辑--------解析XML
 * 
 * @param context   上下文
 *          
 * @param filename 存进的文件名
 *            
 * @return
 */
public static boolean SmsBackup(SmsBackupCallBack callBack,
        Context context, String filename) {

    try {
        ContentResolver resolver = context.getContentResolver();
        Uri uri = Uri.parse("content://sms/");
        Cursor cursor = resolver.query(uri, new String[] { "address",
                "date", "body", "type" }, null, null, null);
        File file = new File(Environment.getExternalStorageDirectory(),
                filename);
        FileOutputStream fos = new FileOutputStream(file);
        XmlSerializer serialer = Xml.newSerializer();
        // 设置序列化参数
        serialer.setOutput(fos, "utf-8");

        serialer.startDocument("utf-8", true);
        serialer.startTag(null, "info");
        cursor.moveToNext();
        int max = cursor.getCount();
        int progress = 0;

        //接口方法
        callBack.callBackMax(max);

        while (cursor.moveToNext()) {
            // cursor.moveToNext();
            serialer.startTag(null, "sms");

            serialer.startTag(null, "address");
            String address = cursor.getString(0);
            serialer.text(address);
            serialer.endTag(null, "address");

            serialer.startTag(null, "date");
            String date = cursor.getString(1);
            serialer.text(date);
            serialer.endTag(null, "date");

            serialer.startTag(null, "body");
            String body = cursor.getString(2);
            serialer.text(body);
            serialer.endTag(null, "body");

            serialer.startTag(null, "type");
            String type = cursor.getString(3);
            serialer.text(type);
            serialer.endTag(null, "type");

            serialer.endTag(null, "sms");
            progress++;

            //接口的方法
            callBack.callBackprogress(progress);

        }
        cursor.close();
        serialer.startTag(null, "info");
        serialer.endDocument();
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }

}
}
  • 短信备份常见错误

1、 org.kxml2.io.KXmlSerializer.text(KXmlSerializer.java:536)

这是因为短信的内容中存在着搜狗输入法的一些表情,无法识别,只要把带有表情符号的短信删除掉就可以成功备份

2、 java.io.FileNotFoundException:
/storage/emulated/0/backup.xml: 07-22 10:56:50.440: W/System.err(305): at
open failed: EACCES (Permission denied)

没有权限齐全,短信的读写,sd卡、内存卡的读写权限等

listview的优化:四大原则

1、时间换空间

(牺牲时间换取空间,流的读写)

2、空间换时间

(把文件的路径存进数据库,以后查询就快很多,Android下的图库应用检索)

3、时间换时间

(开机启动速度的优化)

4、空间换空间

把内存换成硬盘,或者把硬盘换成内存

获取手机中所有应用程序的关键信息以List

返回List集合对象

 public class AppManagerInfos {

    @SuppressWarnings("unused")
    public static List getAppManagerInfos(Context context) {

        List appinfos = new ArrayList();
        PackageManager pm = context.getPackageManager();
//获取安装在手机上的应用程序
        List infos = pm.getInstalledPackages(0);

        for (PackageInfo appInfo : infos) {
            AppInfo info = new AppInfo();
            // 获得包名
            String packagename = appInfo.packageName;
            info.setPakageName(packagename);
            // 获得应用名称
            String appname = appInfo.applicationInfo.loadLabel(pm).toString();
            info.setAppname(appname);
            // 获得应用图标
            Drawable icon = appInfo.applicationInfo.loadIcon(pm);
            info.setIcon(icon);
            // 获得应用app的绝对路径
            String path = appInfo.applicationInfo.sourceDir;
            info.setPath(path);
            // 获得应用app的大小
            File file = new File(path);
            long size = file.length();
            String sizedata = Formatter.formatFileSize(context, size);
            info.setSize(size);
            int flag = appInfo.applicationInfo.flags;
            if ((flag & ApplicationInfo.FLAG_SYSTEM) == 0) {
                // 用户应用
                info.setUserapp(true);
            } else {
                // 系统应用
                info.setUserapp(false);
            }
            if ((flag & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0) {
                // 存在手机内存
                info.setInRom(true);
            } else {
                // 存在sd内存卡
                info.setInRom(false);
            }
            appinfos.add(info);
        }
        return appinfos;
    }
}

把不同集合数据展示到ListView中

public class AppManagerActivity extends Activity {

private TextView tv_shji_byte;
private TextView tv_sd_byte;
private ListView lv_listview;
private LinearLayout ll_loading;
private List infos;
private List userapp;
private List systemapp;
private Handler handler = new Handler() {
    public void handleMessage(android.os.Message msg) {

        lv_listview.setAdapter(new MyAppManagerAdapter());
        ll_loading.setVisibility(View.INVISIBLE);
    };
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_app_manager);

    tv_shji_byte = (TextView) findViewById(R.id.tv_shji_byte);
    tv_sd_byte = (TextView) findViewById(R.id.tv_sd_byte);
    lv_listview = (ListView) findViewById(R.id.lv_listview);
    ll_loading = (LinearLayout) findViewById(R.id.ll_loading);

    userapp = new ArrayList();
    systemapp = new ArrayList();

    File datafile = Environment.getDataDirectory();
    long datasize = datafile.getFreeSpace();

    File sdfile = Environment.getExternalStorageDirectory();
    long sdsize = sdfile.getFreeSpace();

    tv_shji_byte.setText("手机可用内存"
            + Formatter.formatFileSize(this, datasize));
    tv_sd_byte.setText("sd卡可用内存" + Formatter.formatFileSize(this, sdsize));

    fillData();

}
/**
 * 填充数据
 */
private void fillData() {
    new Thread() {
        public void run() {
            infos = AppManagerInfos
                    .getAppManagerInfos(AppManagerActivity.this);
            for (AppInfo info : infos) {
                if (info.isUserapp()) {
                    // 用户程序
                    userapp.add(info);
                } else {
                    systemapp.add(info);
                    // 系统程序
                }
            }
            handler.sendEmptyMessage(0);
        };
    }.start();
}
private class MyAppManagerAdapter extends BaseAdapter {

    @Override
    public int getCount() {
        return userapp.size() + systemapp.size() + 2;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view;
        HoldView holder;
        if (convertView != null && convertView instanceof RelativeLayout) {
            view = convertView;
            holder = (HoldView) view.getTag();
        } else {
            holder = new HoldView();
            view = View.inflate(AppManagerActivity.this,
                    R.layout.item_app_manager, null);
            holder.app_name = (TextView) view.findViewById(R.id.app_name);
            holder.app_location = (TextView) view
                    .findViewById(R.id.app_location);
            holder.app_icon = (ImageView) view.findViewById(R.id.app_icom);
            holder.app_size = (TextView) view.findViewById(R.id.app_size);
            view.setTag(holder);
        }
        AppInfo info;
        if (position == 0) {// 显示textView用户程序
            TextView tv_user = new TextView(AppManagerActivity.this);
            tv_user.setTextSize(15);
            tv_user.setBackgroundColor(Color.GREEN);
            tv_user.setTextColor(Color.BLACK);
            tv_user.setText("用户程序" + userapp.size() + "个");
            return tv_user;
        } else if (position == userapp.size() + 1) {
            TextView tv_system = new TextView(AppManagerActivity.this);
            tv_system.setTextSize(15);
            tv_system.setBackgroundColor(Color.GREEN);
            tv_system.setTextColor(Color.BLACK);
            tv_system.setText("系统程序" + systemapp.size() + "个");
            return tv_system;

        } else if (position < userapp.size() + 1) {
            // 用户程序
            info = userapp.get(position - 1);
        } else {
            // 系统程序
            info = systemapp.get(position - 2 - userapp.size());
        }
        holder.app_name.setText(info.getAppname());
        holder.app_icon.setImageDrawable(info.getIcon());
        holder.app_size.setText(Formatter.formatFileSize(
                AppManagerActivity.this, info.getSize()) + "M");
        if (info.isInRom()) {
            holder.app_location.setText("手机内存");
        } else {
            holder.app_location.setText("sd卡储存");
        }
        return view;
    }
    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    private class HoldView {
        TextView app_name;
        TextView app_location;
        ImageView app_icon;
        TextView app_size;
    }
}

设置listview属性可使其快速滚动

 android:fastScrollEnabled="true"

在listview滚动时悬浮标识符

在帧布局中加入一个TextView


不过设置属性时需要和之前区分系统用户时的属性相同,背景色、字体、大小,这样才可以重合
TextView tv_biaoshi=(TextView) findViewById(R.id.tv_biaoshi);
/**
 * 给listview注册一个滚动监听器
 */
lv_listview.setOnScrollListener(new OnScrollListener() {
    /**
     * 当状态发生改变时执行此方法
     */
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {

    }
    /**
     * 当listview滚动时执行此方法
     */
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {

        if(firstVisibleItem>userapp.size()){
            tv_biaoshi.setText("系统程序"+systemapp.size()+"个");
        }else{
            tv_biaoshi.setText("用户程序"+userapp.size()+"个");
        }
    }
});

悬浮窗体的创建使用(轻量级的对话框,内存开销比对话框小,灵活)漂浮的容器,在activity上方

  //点击条目弹出悬浮窗体
        TextView convertView=new TextView(AppManagerActivity.this);
        convertView.setTextSize(15);
        convertView.setTextColor(Color.RED);
        convertView.setText(info.getPakageName());

        popupwindow = new PopupWindow(convertView, 300, 100);
        popupwindow.setBackgroundDrawable(new ColorDrawable(Color.GREEN));

        //获取点击的条目view对象到窗体的宽高(左上对齐)存在location中x、y
        int []location=new int[2];
        view.getLocationInWindow(location);
        popupwindow.showAtLocation(parent, Gravity.TOP+Gravity.LEFT, 80, location[1]);
不过一般都是自定义悬浮窗体
View convertView=View.inflate(getApplicationContext(), R.layout.item_app_popupwindow, null);

布局文件item.app.popupwindow.xml






    

    




    

    




    

    




    

    

保证窗体中只有一个悬浮窗体,每次弹出前执行判断;listview滚动时消失也执行此方法

public void dismissPopupwindow() {
    if(popupwindow!=null&& popupwindow.isShowing()){
        popupwindow.dismiss();
        popupwindow=null;
    }

动画的播放原理

确定一个变化的函数:
根据这个函数 动态计算在某个时间应该显示什么画面

Canvas Bitmap 要求界面的窗体必须有背景,所以悬浮窗体必须设置背景才能启动动画

}

一键分享

    //发送纯文本
    Intent intent=new Intent();
    intent.setAction(Intent.ACTION_SEND);
    intent.addCategory("android.intent.category.DEFAULT");
    intent.setType("text/plain");
    //intent.setType("image/*");//图片
    //intent.setType("video/*");//音频、视频
    //intent.setType("*/*");//所有类型
    intent.putExtra(Intent.EXTRA_TEXT, "请使用这款软件");
    startActivity(intent);

一键卸载

动态注册广播接收者

    innerReceiver=new InnerUninstallAppReceiver();
    IntentFilter filter=new IntentFilter();
    filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
    filter.addDataScheme("package");
    registerReceiver(innerReceiver, filter);


/**
 * 卸载软件程序后需要更新数据注册一个广播接收者
 */
private void uninstallapp() {

    if(info.isUserapp()){
        Intent intent=new Intent();
        intent.setAction(Intent.ACTION_DELETE);
        intent.setData(Uri.parse("package:"+info.getPakageName()));
        startActivity(intent);
        }else{
            ToastUtils.show(this, "应用程序需要root权限才能卸载");

    }
}
/**
 * 内部类,广播接收者,监听软件卸载的事件
 * @author Administrator
 *
 */
private class InnerUninstallAppReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {

        if(info.isUserapp()){
            userapp.remove(info);
        }else{
            systemapp.remove(info);
        }
        adapter.notifyDataSetChanged();
    }

}

一键启动软件

/**
 * 打开软件的功能
 */
public void openApp() {
    PackageManager pm=getPackageManager();
    Intent intent=pm.getLaunchIntentForPackage(info.getPakageName());
    if(intent!=null){
        startActivity(intent);
    }else{
        ToastUtils.show(this, "软件无法启动!");
    }

}

查看应用程序信息(也可卸载应用程序:系统的设置卸载界面)

    /**
 * 查看应用程序全部信息
 */
private void showApp() {
    //查找上层应用程序源码
  /* 
     
     */
    Intent intent =new Intent();
    intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
    intent.addCategory("android.intent.category.DEFAULT" );
    intent.setData(Uri.parse("package:"+info.getPakageName()));
    startActivity(intent);

}

获取手机所有正在运行的进程(返回的是List集合)

package com.cca.mobilephone.engine;
import java.util.ArrayList;
import java.util.List;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;

import com.cca.mobilephone.domain.ProcessInfo;

/**
 * 获取所有正在运行的进程信息
 * @author Administrator
 *
 */
public class TaskInfoProvifer {

public static List getRunningProcessInfo(Context context){
    List process=new ArrayList();
    ActivityManager am=(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    PackageManager pm=context.getPackageManager();

    //获取正在运行的进程集合
    Listprocessrunninginfoinfo=am.getRunningAppProcesses();
    //遍历集合
    for(RunningAppProcessInfo runninginfo:processrunninginfoinfo){
        ProcessInfo processinfo=new ProcessInfo();
        //进程包名
        String packageName=runninginfo.processName;
        processinfo.setPackageName(packageName);

        long menSize=am.getProcessMemoryInfo(new int[]{runninginfo.pid})[0].
                                                                    getTotalPrivateDirty()*1024;
        processinfo.setMenSize(menSize);
        try {
            PackageInfo packageinfo=pm.getPackageInfo(packageName, 0);
            //进程图标
            Drawable icon=packageinfo.applicationInfo.loadIcon(pm);
            processinfo.setIcon(icon);
            //进程名称
            String processName=packageinfo.applicationInfo.loadLabel(pm).toString();
            processinfo.setProcessName(processName);
            //
            if((packageinfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)!=0){
                //系统进程
                processinfo.setUserProcess(false);
            }else{
                //用户进程
                processinfo.setUserProcess(true);
            }
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        process.add(processinfo);
    }
    return process;
}

}

javabean类的信息

package com.cca.mobilephone.domain;
import android.graphics.drawable.Drawable;

/**
 * 进程包含的信息
 * @author Administrator
 *
 */
public class ProcessInfo {

private String packageName;
private String processName;
private Drawable icon;
private long menSize;
private boolean userProcess;
public String getPackageName() {
    return packageName;
}
public void setPackageName(String packageName) {
    this.packageName = packageName;
}
public String getProcessName() {
    return processName;
}
public void setProcessName(String processName) {
    this.processName = processName;
}
public Drawable getIcon() {
    return icon;
}
public void setIcon(Drawable icon) {
    this.icon = icon;
}
public long getMenSize() {
    return menSize;
}
public void setMenSize(long menSize) {
    this.menSize = menSize;
}
public boolean isUserProcess() {
    return userProcess;
}
public void setUserProcess(boolean userProcess) {
    this.userProcess = userProcess;
}

}

区分用户进程和系统进程(这是耗时操作)

List processinfo=TaskInfoProvifer.getRunningProcessInfo(getApplicationContext());
            userprocess=new ArrayList();
            systemprocess=new ArrayList();

            for(ProcessInfo process:processinfo){
                    if(process.isUserProcess()){
                        //用户程序
                        userprocess.add(process);
                    }else{
                        //系统程序
                        systemprocess.add(process);
                    }

            }
            //通知界面更新
            handler.sendEmptyMessage(0);

打开一个服务,内部注册一个广播接收者,监听锁屏清理进程

public class AutoKillService extends Service {

    private InnerScrrenOffReceiver receiver;
    private Timer timer;
    private TimerTask task;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        receiver=new InnerScrrenOffReceiver();
        IntentFilter filter=new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        registerReceiver(receiver, filter);

        /**
         * 常用定时器,可设置为定时清理的功能
         */
        timer=new Timer();
        task=new TimerTask() {

            @Override
            public void run() {
            //System.out.println("每1秒执行一次");

            //清理的逻辑
            }
        };
        timer.schedule(task,0, 1000);

    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        timer.cancel();
        task.cancel();
        unregisterReceiver(receiver);
        receiver=null;
    }

    private class InnerScrrenOffReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            //System.out.println("哈哈,屏幕锁屏了");
            ActivityManager am=(ActivityManager) getSystemService(ACTIVITY_SERVICE);
            List infos=  am.getRunningAppProcesses();
            for(RunningAppProcessInfo info:infos){
                //杀死后台进程
                am.killBackgroundProcesses(info.processName);

            }

        }
    }
}

逆向小助手的使用:反编译获取素材资源文件,everything可快速查找

多层显示的帧布局,功能多多



    
    

    

        

        
    

    

杀死所有运行的进程

    ActivityManager am=(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List infos=am.getRunningAppProcesses();
    for(RunningAppProcessInfo info:infos){

        am.killBackgroundProcesses(info.processName);//参数为包名

    }

抽屉控件

(重下往上拉),也可指定拉升的高度
 

    

    
    
    
    

也可重右往左拉
  

界面的切换(一个界面不同的布局切换)

    
    

        

            

            
        

        

            

                

                
            

            

                

                
                
            

            

                

                
                
            
        

    

在Service中开启一个活动Activity 在Activity往Service中发送信息采用自定义广播,只有服务才能接收:

活动中:

    Intent intent=new Intent();
    intent.setAction("com.cca.mobilesafe.watchdog");
    intent.putExtra("packageNmae",packageName);

在服务中定义一个内部类广播接收者

private class InnerWatchDogReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {

        temppackageName = intent.getStringExtra("packageName");

    }
}
在onCreate方法中注册广播接收者:
//注册一个广播接收者
receiver=new InnerWatchDogReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction("com.cca.mobilephone.watchdog");
registerReceiver(receiver, filter);

内容观察者

数据库中大声发个消息

Uri uri=Uri.parse("content://com.cca.mobilesafe.applockdb");
context.getContentResolver().notifyChange(Uri,null);

注册一个内容观察者:

Uri uri=Uri.parse("content://com.cca.mobilesafe.applockdb");
observer=new ApplockDBObserver(new Handler());
getContentResolver().registerContentObserver(uri,true,observer);

定义一个内容观察者内部类

    /**
 * 定义内容观察者内部类
 * @author Administrator
 *
 */
private class AppClockDaoObserver extends ContentObserver{
    public AppClockDaoObserver(Handler handler) {
        super(handler);
    }
    //观察到数据库内容发生变化
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        packname = dao.findAll();
    }
}

目录

getFilesDir(); //data/data/<包名>/files 文件目录
getCacheDir(); //data/data/<包名>/cache 缓存目录

扫描手机获取所有程序员的缓存

public class CleanCacheActivity extends Activity {

    protected static final int SCAN_STOP = 1;
    public static final int SEND_SCAN = 2;
    private ProgressBar pb;
    private TextView tv_scan_cache;
    private FrameLayout fl_scan_states;
    private PackageManager pm;
    private ListView lv_scan_listview;
    private Listcache;
    private MyAdapter adapter;
    /**
     * 消息机制
     */
    private Handler handler=new Handler(){
        public void handleMessage(android.os.Message msg) {
            switch(msg.what){
            case SCAN_STOP://扫描结束

                Toast.makeText(getApplicationContext(), "扫描完毕", 0).show();
                fl_scan_states.setVisibility(View.GONE);
                if(cache.size()>0){
                //设置适配器
                    adapter=new MyAdapter();
                lv_scan_listview.setAdapter(adapter);
                }else{
                     ToastUtils.show(CleanCacheActivity.this, "恭喜你,你的手机100分");
                }
                break;
            case SEND_SCAN://正在扫描


            String appname=(String) msg.obj;
            tv_scan_cache.setText("正在清理:"+appname);
            break;
            }
        };
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_clean_cache);
        //初始化数据
        pb=(ProgressBar) findViewById(R.id.pb);
        tv_scan_cache=(TextView) findViewById(R.id.tv_scan_cache);
        fl_scan_states=(FrameLayout) findViewById(R.id.fl_scan_states);
        lv_scan_listview=(ListView) findViewById(R.id.lv_scan_listview);
        pm=getPackageManager();
        //扫描缓存
        scanCache();


    }
    /**
     * 扫描手机应用分别获取缓存信息
     */
    private void scanCache() {
        fl_scan_states.setVisibility(View.VISIBLE);
        cache=new ArrayList();
        //开子线程扫描程序缓存
        new Thread(){
            public void run() {
                pb.setMax(100);

             int progress=0;
            //1、扫描应用程序全部的包名
            Listinfos=pm.getInstalledPackages(0);
            for(PackageInfo info:infos){
                try {
                    //获取每个程序的包名
                    String packagename=info.packageName;
                    //利用反射获取指定的方法名
                    Method method=PackageManager.class.getMethod("getPackageSizeInfo", String.class,IPackageStatsObserver.class);

                    method.invoke(pm,packagename,new MyObserver());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //进度条的设置
                progress++;
                pb.setProgress(progress);
                try {
                    sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //2、通知界面更新
            Message msg=Message.obtain();
            msg.what=SCAN_STOP;
            handler.sendMessage(msg);
        };
    }.start();
}
private class MyObserver extends IPackageStatsObserver.Stub{
    @Override
    public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
            throws RemoteException {
            try {
            //把扫描到的包名发送回主界面更新
                Message  msg=Message.obtain();
                msg.what=SEND_SCAN;
                String appname=pm.getPackageInfo(pStats.packageName, 0).
                        applicationInfo.loadLabel(pm).toString();
                msg.obj=appname;
                handler.sendMessage(msg);
                //主有有缓存大小的程序才需要存进集合中
                if(pStats.cacheSize>0){
                    CacheHolder holder=new CacheHolder();
                    holder. cachesize=pStats.cacheSize;//缓存大小
                    holder. packName=pStats.packageName;//代码大小
                    holder. icon=pm.getPackageInfo(holder. packName, 0).applicationInfo.loadIcon(pm);
                    holder. appName=appname;
                    cache.add(holder);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
}

private class CacheHolder{
    long cachesize;
    String packName;
    Drawable icon;
    String appName;
}
/**
 * listview的适配器
 * @author Administrator
 *
 */
private class MyAdapter extends BaseAdapter{
    @Override
    public int getCount() {
        return cache.size();
    }
    @Override
    public Object getItem(int position) {
        return null;
    }
    @Override
    public long getItemId(int position) {
        return 0;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view;
        ViewHolder holder;
        //服用历史缓存对象,优化listview
        if(convertView!=null){
            view=convertView;
            holder=(ViewHolder) view.getTag();
        }else{
            holder=new ViewHolder();
            view=View.inflate(getApplicationContext(), R.layout.item_cache_listview, null);
            holder.icon=(ImageView) view.findViewById(R.id.img_icon);
            holder.apname=(TextView) view.findViewById(R.id.tv_appname);
            holder.cachesize=(TextView) view.findViewById(R.id.tv_cachesize);
            holder.clearcache=(ImageView) view.findViewById(R.id.img_clear_button);
            view.setTag(holder);
        }
        final CacheHolder cacheholder=cache.get(position);
        holder.icon.setImageDrawable(cacheholder.icon);
        holder.apname.setText(cacheholder.appName);
        holder.cachesize.setText("缓存大小"+Formatter.formatFileSize(getApplicationContext(), cacheholder.cachesize));
        holder.clearcache.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                //打开应用程序信息
                Intent intent =new Intent();
                intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                intent.addCategory("android.intent.category.DEFAULT" );
                intent.setData(Uri.parse("package:"+cacheholder.packName));
                startActivity(intent);

            }
        });
        if(cacheholder.cachesize==0){
            cache.remove(cacheholder);
            adapter.notifyDataSetChanged();
        }
        return view;
    }
}
private class ViewHolder{
    ImageView icon;
    TextView apname;
    TextView cachesize;
    ImageView clearcache;
}
 class ClearCacheObserver extends IPackageDataObserver.Stub {
        public void onRemoveCompleted(final String packageName, final boolean succeeded) {
           ToastUtils.show(CleanCacheActivity.this, "清除状态"+succeeded);
         }
     }
 /**
  * 清理全部的缓存空间
  * @param view
  */
 public void AllClearCache(View view){
     Method[] methods=PackageManager.class.getMethods();
     for(Method method:methods){
         if("freeStorageAndNotify".equals(method.getName())){
             try {
                method.invoke(pm, Long.MAX_VALUE*1024,new ClearCacheObserver());
            } catch (Exception e) {
                e.printStackTrace();
            }
             scanCache();
             return ;
         }
     }
 }
}

自定义进度条

在drawable下建立一个progress_horizontal.xml




    //整个进度条背景
    

    

    
        //缓存到的背景
    

    
     //当前背景
    


设置进度条的属性引用它
    android:progressDrawable="@drawable/progress_horizontal"

这样就自定义好了进度条

具体的配置也可配置一下节点

share.xml下

在share节点下

android:shape="rectangle"  //圆角矩形
 //弧度


  //固定颜色不可和渐变色一起使用


清理缓存

//打开应用程序信息,手动清除
    Intent intent =new Intent();
    intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
    intent.addCategory("android.intent.category.DEFAULT" );
    intent.setData(Uri.parse("package:"+cacheholder.packName));
    startActivity(intent);

全部清理缓存

/**
  * 清理全部的缓存空间
  * @param view
  */
 public void AllClearCache(View view){
     Method[] methods=PackageManager.class.getMethods();
     for(Method method:methods){
         if("freeStorageAndNotify".equals(method.getName())){
             try {
                method.invoke(pm, Long.MAX_VALUE*1024,new ClearCacheObserver());
            } catch (Exception e) {
                e.printStackTrace();
            }
             scanCache();
             return ;
         }
     }
 }

隐藏应用程序的图标(不被用户发觉)

getPackageManager().setComponentEnabledSetting(getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

围绕中心轴旋转
/* * 旋转动画 */

RotateAnimation ra=new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 
ra.setDuration(2000); 
ra.setRepeatCount(Animation.INFINITE); 
img_rotate.startAnimation(ra);

程序的签名

/**
 * 获取应用程序的签名信息、使用MD5加密,要加上标志位PackageManager.GET_SIGNATURES ,系统默认不解析 TODO
 */
System.out.println("程序名"+info.applicationInfo.loadLabel(pm));
System.out.println("签名:"+MD5Utils.encode(info.signatures[0].toCharsString()));

获取程序的校验码

    /**
     * 获取程序的校验码
     */
    //apk的路径
    String apkpath=info.applicationInfo.sourceDir;
    File file=new File(apkpath);
    MessageDigest digest=MessageDigest.getInstance("md5"); 

    //这里使用MD5 也可以使用  "sha-1"  获取

    FileInputStream fis=new FileInputStream(file);
    byte[] buffer=new byte[1024];
    int len=0;
    while((len=fis.read(buffer))!=-1){
        digest.update(buffer, 0, len);
    }
    byte [] result=digest.digest();
    StringBuffer sb=new StringBuffer();
    for(byte b:result){
        String str=Integer.toHexString(b&0xff);
        if(str.length()==1){
            sb.append("0");
        }
        sb.append(str);
    }

创建应用程序的图标

    /**
 *创建快捷图标
 */
private void createShortCut() {
    SharedPreferences sp=getSharedPreferences("config", MODE_PRIVATE);
    boolean shortcut=sp.getBoolean("shortcut", false);
    if(!shortcut){
        //快捷方式的图片
    //快捷方式的名称
    //快捷方式干什么事情
    //快捷图标其实是显示在桌面的,让桌面帮我们创建快捷图标
    //给桌面发送消息
    Intent intent=new Intent(); //发送广播的意图
    intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
    //设置数据
    intent.putExtra(Intent.EXTRA_SHORTCUT_NAME,"破荒卫士" );
    intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));

    //快捷方式开启对应的意图
    Intent shortcutIntent=new Intent();
    shortcutIntent.setAction("com.cca.mobilesafe.home");
    shortcutIntent.addCategory(Intent.CATEGORY_DEFAULT);
    intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
    //发送创建快捷方式的广播
    sendBroadcast(intent);
    Editor edit=sp.edit();
    edit.putBoolean("shortcut", true);
    edit.commit();
    }

}

消息的通知

//消息的通知、先下兼容低版本
private void createNotification() {
    //获取通知管理者
    NotificationManager nm=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    Notification notification=new Notification(R.drawable.ic_launcher, "破荒手机卫士正在保护你的手机!", System.currentTimeMillis());
    //设置通知的标志
    notification.flags=Notification.FLAG_NO_CLEAR;
    //意图打开主界面
    Intent intent=new Intent();
    intent.setAction("com.cca.mobilesafe.home");
    intent.addCategory(Intent.CATEGORY_DEFAULT);

    PendingIntent contentIntent= PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    notification.setLatestEventInfo(this, "破荒手机卫士", "正在保护你的手机", contentIntent);
    nm.notify(0, notification);

}

应用程序的混淆加密(四大组件、自定义控件不可混淆)

操作方法:直接到目录把 sdk/tools/proguard/proguard-android这个文件拷贝到工程目录下就可以导出apk文件了
混淆工作原理:
全局替换 :类名、变量名、方法名
想把什么给保留出来,只要增加一下类似的语句
-keep class com.cca.mobilesafe.domain.AppInfo

介绍广告
1、内付费互联网公司2、软件付费3、免费软件+广告
cpm:千次有效展现cpc:点击cpa:完整有效点击cpd:下载
广告主
代理公司(有米、百度联盟)
小程序员
常见系统的管理器:

TelephonyManager:电话管理的服务
SmsManager :信息的管理服务
DevicesManager :设备的超级管理者
ActivityManager:活动管理器:获取进程和服务的管理器,相当于window系统的任务管理器,获取的是动态信息
PackageManager:获取各种包的信息(版本、应用程序图标、包信息等)相当于window系统的软件管理,获取的是静态的信息
AppWidgetManager 桌面小控件
NotificationManager 通知的管理
LocationManager 位置提供者
WindowManager窗口管理者

你可能感兴趣的:(手机卫士涉及的知识点总结(二))