内容观察者
数据库中大声发个消息
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"
?-->
//整个进度条背景
<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
;
}
}
}
|
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());
}
}
}
|
操作方法:直接到目录把 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窗口管理者