且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Android--手机卫士涉及的知识点总结(六)

更新时间:2022-03-11 18:16:05

内容观察者

数据库中大声发个消息

?
1
2
context.getContentResolver().notifyChange(Uri,null);

注册一个内容观察者:

?
1
2
3
observer=new ApplockDBObserver(new Handler());
getContentResolver().registerContentObserver(uri,true,observer);

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    /**
 * 定义内容观察者内部类
 * @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();
    }
}

目录

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
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 List<cacheholder>cache;
    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<cacheholder>();
        //开子线程扫描程序缓存
        new Thread(){
            public void run() {
                pb.setMax(100);
 
             int progress=0;
            //1、扫描应用程序全部的包名
            List<packageinfo>infos=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 ;
         }
     }
 }
}
</packageinfo></cacheholder></cacheholder>

自定义进度条

在drawable下建立一个progress_horizontal.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!--?xml version="1.0" encoding="utf-8"?-->
 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    //整个进度条背景
    <item android:drawable="@drawable/security_progress_bg" android:id="@android:id/background">
 
    </item>
 
    <item android:drawable="@drawable/security_progress" android:id="@android:id/secondaryProgress">
        //缓存到的背景
    </item>
 
    <item android:drawable="@drawable/security_progress" android:id="@android:id/progress">
     //当前背景
    </item>
 
</layer-list>

设置进度条的属性引用它

?
1
android:progressDrawable="@drawable/progress_horizontal"

这样就自定义好了进度条

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

share.xml下

在share节点下

?
1
2
3
4
5
6
7
8
android:shape="rectangle"  //圆角矩形
<corners android:radius="5dp"> //弧度
<gradient android:="" endcolor="#22ffff00" startcolor="#ff0000">
<padding android:bottom="5dp" android:left="5dp" android:right="5dp" android:top="5dp">
<solid android:color="#0000ff" android:width="1dp"//固定颜色不可和渐变色一起使用
 
<stroke android:color="#000000" android:dashgap="2dip" android:dashwidth="5dp" android:width="1dp">
</stroke></solid></padding></gradient></corners>

清理缓存

?
1
2
3
4
5
6
//打开应用程序信息,手动清除
    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);

全部清理缓存

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
  * 清理全部的缓存空间
  * @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 ;
         }
     }
 }
<h2 id="手机杀毒的方式">手机杀毒的方式

1、最原始的查杀方式

基于文件的的特征码(缺点:只能查杀已知的病毒,不能查杀未知的病毒)

2、基于程序的行为去查杀(主动防御)

替换系统的API(看雪论坛

3、人工智能(学习模式+数据库)

字符串与字符串之间的距离

手机杀毒的实现

数据库的实现:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    package com.cca.mobilephone.db.dao;
 
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
/**
 * 病毒数据库
 * @author Administrator
 *
 */
public class AntiVriusDao {
    /**
     * 在数据库中查找程序特征码是否存在,存在就是病毒软件,不存在就不是
     * @param md5
     * @return
     */
    public static String isVriusdb(String md5){
 
        SQLiteDatabase db=SQLiteDatabase.openDatabase("/data/data/com.cca.mobilephone/files/antivirus.db",
                                    null, SQLiteDatabase.OPEN_READONLY);
        Cursor cursor=db.rawQuery("select desc from datable where md5=?", new String[]{md5});
        String desc=null;
        if(cursor.moveToNext()){
             desc=cursor.getString(0);
        }
        db.close();
        cursor.close();
        return desc;
    }
}

ui布局·:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    <!--?xml version="1.0" encoding="utf-8"?-->
<linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
 
    <linearlayout android:layout_height="wrap_content" android:layout_margintop="3dp" android:layout_width="match_parent" android:orientation="horizontal">
 
        <framelayout android:layout_height="wrap_content" android:layout_width="wrap_content">
 
            <imageview android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/ic_scanner_malware">
 
            <imageview android:id="@+id/img_rotate" android:layout_gravity="center" android:layout_height="60dp" android:layout_width="60dp" android:src="@drawable/act_scanning_03">
        </imageview></imageview></framelayout>
 
        <relativelayout android:layout_gravity="center" android:layout_height="wrap_content" android:layout_width="match_parent">
 
            <textview android:gravity="center_horizontal" android:id="@+id/tv_now_querry" android:layout_height="wrap_content" android:layout_margintop="6dp" android:layout_width="match_parent" android:text="正在查杀...">
 
            <progressbar android:id="@+id/verits_pb" android:layout_below="@id/tv_now_querry" android:layout_height="wrap_content" android:layout_marginleft="15dp" android:layout_marginright="15dp" android:layout_margintop="4dp" android:layout_width="match_parent" android:progressdrawable="@drawable/progress_horizontal">
        </progressbar></textview></relativelayout>
    </linearlayout>
   <linearlayout android:id="@+id/ll_add_text" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical">
 
   </linearlayout>
 
</linearlayout>

代码的实现:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
public class AntiVirusActivity extends Activity {
 
    private ImageView img_rotate;
    private LinearLayout ll_add_text;
    private ProgressBar verits_pb;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        setContentView(R.layout.activity_antivures);
        img_rotate=(ImageView) findViewById(R.id.img_rotate);
        ll_add_text=(LinearLayout) findViewById(R.id.ll_add_text);
        verits_pb=(ProgressBar) findViewById(R.id.verits_pb);
        /*
         * 旋转动画
         */
        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);
 
        //扫描手机应用程序
        scanVirus();
    }
 
    /**
     * 扫描手机应用程序,查找手机病毒程序
     */
    private void scanVirus() {
        /**
         * 遍历手机应用程序的信息,查询他的特征码在病毒数据库中是否存在
         */
        PackageManager pm=getPackageManager();
        List<packageinfo> pakageinfos=pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
        verits_pb.setMax(pakageinfos.size());
        int progress=0;
        for(PackageInfo info:pakageinfos){
            try {
                String apkpath=info.applicationInfo.sourceDir;
                File file=new File(apkpath);
                MessageDigest digest=MessageDigest.getInstance("md5");
                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);
                }
                progress++;
                verits_pb.setProgress(progress);
                String md5=sb.toString();
                /**
                 * 查找md5是否存在病毒数据库中
                 */
                final String desc=AntiVriusDao.isVriusdb(md5);
                final String appname=(String) info.applicationInfo.loadLabel(pm);
                runOnUiThread(new Runnable() {
 
                    @Override
                    public void run() {
                        TextView tv=new TextView(AntiVirusActivity.this);
                        if(desc!=null){
                            //发现病毒
                            tv.setTextColor(Color.RED);
                            tv.setText(appname+":发现病毒");
                        }else{
                            //扫描安全
                            tv.setTextColor(Color.GREEN);
                            tv.setText(appname+":扫描安全");
                        }
                        ll_add_text.addView(tv, 0);
                    }
                });
                Thread.sleep(50);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
</packageinfo>

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

?
1
2
3
getPackageManager().setComponentEnabledSetting(getComponentName(),
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);

围绕中心轴旋转

?
1
2
3
4
5
6
7
8
9
10
/*
 * 旋转动画
 */
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);

程序的签名

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

获取程序的校验码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
 * 获取程序的校验码
 */
//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);
}

创建应用程序的图标

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    /**
 *创建快捷图标
 */
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();
    }
 
}

消息的通知

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//消息的通知、先下兼容低版本
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);
 
}

对应用程序中的Log的控制,想打印什么类型的信息只要修改LOGLEVEL的值

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.cca.mobilephone.Utils;
 
import android.util.Log;
 
/**
 * 应用程序的Log的控制
 * @author Administrator
 *
 */
public class Logger {
 
    private static final int  VERBOSE=1;
    private static final int  DEBUG=2;
    private static final int  INFO=3;
    private static final int  WARN=4;
    private static final int  ERROR=5;
    private static  int  LOGLEVEL=4;
 
    public static void v(String tag,String msg){
        if(VERBOSE>LOGLEVEL){
            Log.v(tag, msg);
        }
    }
    public static void d(String tag,String msg){
        if(DEBUG>LOGLEVEL){
            Log.d(tag, msg);
        }
    }
    public static void i(String tag,String msg){
        if(INFO>LOGLEVEL){
            Log.i(tag, msg);
        }
    }
    public static void w(String tag,String msg){
        if(WARN>LOGLEVEL){
            Log.w(tag, msg);
        }
    }
    public static void e(String tag,String msg){
        if(ERROR>LOGLEVEL){
            Log.e(tag, msg);
        }
    }
}

应用程序的异常处理,捕获到异常信息存进指定的目录,可以上传至服务器中

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.cca.mobilephone.log;
 
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import android.app.Application;
import com.cca.mobilephone.Utils.Logger;
/**
 * 代表的就是当前手机卫士的应用程序
 * 《b》一定要注意在清单文件Application中配置,点Browser会自动匹配
 * @author Administrator
 *
 */
public class MobileSafeApplication extends Application {
 
    //开天地,老母子方法
    @Override
    public void onCreate() {
        super.onCreate();
        Thread.currentThread().setUncaughtExceptionHandler(new MyExceptionHandler());
    }
    /**
     * 捕获异常信息存进sd中,再上传至服务器中
     * @author Administrator
     *
     */
    private class MyExceptionHandler implements UncaughtExceptionHandler{
 
        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
            Logger.i("","发生了异常,被哥捕获到了。。。。。");
            //并不能把异常消化掉,只是在应用程序挂掉之前,来一个留遗嘱的时间
 
            try {
 
                    //获取手机适配的信息
                Field[] fields=Builder.class.getDeclaredFields();
                StringBuffer sb=new StringBuffer();
                for(Field field:fields){
                    String value=field.get(null).toString();
                    String name=field.getName();
                    sb.append(value);
                    sb.append(":");
                    sb.append(name);
                    sb.append("\n");
                }
 
                //输出异常信息
                FileOutputStream out=new FileOutputStream("/mnt/sdcard/error.log");
                //阻塞性方法,直接写到内存中,内存输出流
                StringWriter wr=new StringWriter();
                PrintWriter err=new PrintWriter(wr);//打印输出流,异步输出流
                ex.printStackTrace(err);
                String errorlog=wr.toString();
                out.write(errorlog.getBytes());
                out.flush();
                out.close();
 
            } catch (Exception e) {
                e.printStackTrace();
            }
 
            //ActivityManager 可以杀死别的进程,不能自杀,而专注于自杀是 android.os.Process
            android.os.Process.killProcess(android.os.Process.myPid());
        }
    }
}
<h2 id="应用程序的混淆加密四大组件自定义控件不可混淆">应用程序的混淆加密(四大组件、自定义控件不可混淆)

操作方法:直接到目录把 sdk/tools/proguard/proguard-android这个文件拷贝到工程目录下就可以导出apk文件了

混淆工作原理:

全局替换 :类名、变量名、方法名

想把什么给保留出来,只要增加一下类似的语句

?
1
-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窗口管理者