短信拦截:开启服务并在里面注册一个广播接收者
1
2
3
|
开启服务:
Intent intent=
new
Intent(SettingActivity.
this
,CallSmsSafeService.
class
);
startService(intent);
|
//服务里面代码动态注册一个广播接收者
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
|
public
class
CallSmsSafeService
extends
Service {
private
BlackNumberDao dao;
private
InnerReceiver receiver;
@Override
public
IBinder onBind(Intent intent) {
return
null
;
}
@Override
public
void
onCreate() {
dao=
new
BlackNumberDao(
this
);
//动态注册
receiver=
new
InnerReceiver();
IntentFilter filter=
new
IntentFilter();
//设置关心短信到来的动作
filter.addAction(
"android.provider.Telephony.SMS_RECEIVED"
);
filter.setPriority(Integer.MAX_VALUE);
//代码注册广播接收者
registerReceiver(receiver, filter);
System.out.println(
"黑名单短信拦截开启了!!!!!"
);
super
.onCreate();
}
@Override
public
void
onDestroy() {
super
.onDestroy();
unregisterReceiver(receiver);
receiver=
null
;
}
//内部类广播接收者
private
class
InnerReceiver
extends
BroadcastReceiver{
@Override
public
void
onReceive(Context context, Intent intent) {
//拦截短信
Object[] objs=(Object[]) intent.getExtras().get(
"pdus"
);
for
(Object obj:objs){
SmsMessage smsMessage=SmsMessage.createFromPdu((
byte
[])obj);
String address=smsMessage.getOriginatingAddress();
String result=dao.find(address);
if
(
"2"
.equals(result)||
"3"
.equals(result)){
System.out.println(
"黑名单短信拦截模式。。。"
);
abortBroadcast();
}
//智能拦截
String body=smsMessage.getMessageBody();
if
(body.contains(
"天使"
)){
//分词算法
SmsManager.getDefault().sendTextMessage(
"13531829360"
,
null
,
"帮你拦截了天使客一条消息"
,
null
,
null
);
abortBroadcast();
}
}
}
}
}
|
服务断电就会自动停止,用sp存储不会保存状态,读取系统的的运行信息,调用系统的活动和服务管理者ActivityManager可以判断服务是否正在后台运行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/**
* 判断系统的服务是否在后台运行
* context:上下文
* StringName: 服务的全路经名
*/
public
static
boolean
isServiceRunning(Context context,String StringName){
ActivityManager am=(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<runningserviceinfo> infos=am.getRunningServices(
100
);
for
(RunningServiceInfo info:infos){
String className=info.service.getClassName();
if
(StringName.equals(className)){
return
true
;
}
}
return
false
;
}
</runningserviceinfo>
|
分词算法:
开源算法:
luncence
利用反射原理挂断电话
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/**
* 挂断电话的方法,利用反射
*/
public
void
endCall() {
try
{
Class clazz=CallSmsSafeService.
class
.getClassLoader().loadClass(
"android.os.ServiceManager"
);
Method method=clazz.getDeclaredMethod(
"getService"
, String.
class
);
IBinder ibinder=(IBinder) method.invoke(
null
, TELEPHONY_SERVICE);
ITelephony iTelephony=ITelephony.Stub.asInterface(ibinder);
iTelephony.endCall();
}
catch
(Exception e) {
e.printStackTrace();
}
}
|
删除通话的记录(内容观察者)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
//监视呼叫记录的的数据库,看什么时候生成了,
//就把它删除
getContentResolver().registerContentObserver(uri,
true
,
new
ContentObserver(
new
Handler()) {
@Override
public
void
onChange(
boolean
selfChange) {
super
.onChange(selfChange);
deleteCallLog(incomingNumber);
}
});
/**
* 删除拨号记录
* @param incomingNumber
*/
public
void
deleteCallLog(String incomingNumber) {
ContentResolver resolver=getContentResolver();
resolver.delete(uri,
"number=?"
,
new
String[]{incomingNumber});
}
|
电话的拦截功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/**
* 定义电话管理的服务
*/
private
TelephonyManager tm;
private
MyPhoneStateListener listener;
/**
* 实例化电话管理的服务
*/
tm=(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
//注册电话的监听器
listener=
new
MyPhoneStateListener();
//监听电话的状态的改变
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
|
监听器的注册
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
|
class
MyPhoneStateListener
extends
PhoneStateListener{
@Override
public
void
onCallStateChanged(
int
state, String incomingNumber) {
super
.onCallStateChanged(state, incomingNumber);
switch
(state){
case
TelephonyManager.CALL_STATE_IDLE:
//空闲状态
break
;
case
TelephonyManager.CALL_STATE_RINGING:
//响铃状态
String mode=dao.find(incomingNumber);
if
(mode.equals(
"1"
)||mode.equals(
"3"
)){
System.out.println(
"挂断电话"
);
}
break
;
case
TelephonyManager.CALL_STATE_OFFHOOK:
//接听状态
break
;
}
}
}
|
ActivityManager:获取进程和服务的管理
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
|
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE) ;
//获得系统运行的进程
List appList1 = mActivityManager
.getRunningAppProcesses();
for
(RunningAppProcessInfo running : appList1) {
System.out.println(running.processName);
}
System.out.println(
"================"
);
//获得当前正在运行的service
List appList2 = mActivityManager
.getRunningServices(
100
);
for
(ActivityManager.RunningServiceInfo running : appList2) {
System.out.println(running.service.getClassName());
}
System.out.println(
"================"
);
//获得当前正在运行的activity
List appList3 = mActivityManager
.getRunningTasks(
1000
);
for
(ActivityManager.RunningTaskInfo running : appList3) {
System.out.println(running.baseActivity.getClassName());
}
System.out.println(
"================"
);
//获得最近运行的应用
List appList4 = mActivityManager
.getRecentTasks(
100
,
1
);
for
(ActivityManager.RecentTaskInfo running : appList4) {
System.out.println(running.origActivity.getClassName());
}
</activitymanager.recenttaskinfo></activitymanager.runningtaskinfo></activitymanager.runningserviceinfo></activitymanager.runningappprocessinfo>
|
判断某个进程或服务是否在后台进行的工具类:
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
|
package
com.cca.mobilephone.Utils;
import
java.util.List;
import
android.app.ActivityManager;
import
android.app.ActivityManager.RunningServiceInfo;
import
android.content.Context;
public
class
ServicerUtils {
/**
* 判断系统的服务是否在后台运行
*/
public
static
boolean
isServiceRunning(Context context,String StringName){
ActivityManager am=(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<runningserviceinfo> infos=am.getRunningServices(
1000
);
for
(ActivityManager.RunningServiceInfo info:infos){
String className=info.service.getClassName();
System.out.println(className);
if
(StringName.equals(className)){
System.out.println(className);
return
true
;
}
}
return
false
;
}
</runningserviceinfo>
|
}
数据库的增删改查
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
|
package
com.cca.mobilephone.db.dao;
import
java.util.ArrayList;
import
java.util.List;
import
android.content.ContentValues;
import
android.content.Context;
import
android.database.Cursor;
import
android.database.sqlite.SQLiteDatabase;
import
com.cca.mobilephone.db.BlackNumberOpenHeloper;
import
com.cca.mobilephone.domain.BlackNumberInfo;
public
class
BlackNumberDao {
private
BlackNumberOpenHeloper openhelper;
/**
* 数据库的构造函数
* @param context
*/
public
BlackNumberDao(Context context) {
super
();
openhelper=
new
BlackNumberOpenHeloper(context);
}
/**
* 往数据库中增加号码
* @param phone 增加的电话号码
* @param mode 模式
* @return
*/
public
boolean
add(String phone,String mode){
SQLiteDatabase db=openhelper.getWritableDatabase();
ContentValues values=
new
ContentValues();
values.put(
"phone"
, phone);
values.put(
"mode"
, mode);
long
id=db.insert(
"blacknumberinfo"
,
null
, values);
db.close();
if
(id!=-
1
){
return
true
;
}
else
{
return
false
;
}
}
/**
* 修改黑名单的拦截模式
* @param phone 要修改的黑名单号码
* @param newmode 新的拦截模式
* @return 修改是否成功
*/
public
boolean
update(String phone,String newmode){
SQLiteDatabase db=openhelper.getWritableDatabase();
ContentValues values=
new
ContentValues();
values.put(
"mode"
, newmode);
int
rowcount=db.update(
"blacknumberinfo"
, values,
"phone=?"
,
new
String[]{phone});
db.close();
if
(rowcount==
0
){
return
false
;
}
else
{
return
true
;
}
}
/**
* 查找黑名单号码的拦截模式
* @param phone 要查找的电话号码
* @return 返回拦截的模式
*/
public
String find(String phone){
String mode=
null
;
SQLiteDatabase db=openhelper.getReadableDatabase();
Cursor cursor=db.query(
"blacknumberinfo"
,
null
,
"phone=?"
,
new
String[]{phone},
null
,
null
,
null
);
if
(cursor.moveToNext()){
mode=cursor.getString(cursor.getColumnIndex(
"mode"
));;
}
cursor.close();
db.close();
return
mode;
}
/**
* 删除黑名单号码
* @param phone 要删除的号码
* @return 是否删除成功
*/
public
boolean
delete(String phone){
SQLiteDatabase db=openhelper.getWritableDatabase();
int
rowcount=db.delete(
"blacknumberinfo"
,
"phone=?"
,
new
String[]{phone});
db.close();
if
(rowcount==
0
){
return
false
;
}{
return
true
;
}
}
/**
* 返回全部的黑名单信息
* @return
*/
public
List<blacknumberinfo> findAll(){
SQLiteDatabase db=openhelper.getReadableDatabase();
Cursor cursor=db.query(
"blacknumberinfo"
,
null
,
null
,
null
,
null
,
null
,
"_id desc"
);
List<blacknumberinfo> infos=
new
ArrayList<blacknumberinfo>();
while
(cursor.moveToNext()){
String phone=cursor.getString(cursor.getColumnIndex(
"phone"
));
String mode=cursor.getString(cursor.getColumnIndex(
"mode"
));
BlackNumberInfo info=
new
BlackNumberInfo();
info.setPhone(phone);
info.setMode(mode);
infos.add(info);
}
cursor.close();
db.close();
return
infos;
}
</blacknumberinfo></blacknumberinfo></blacknumberinfo>
|
分批加载
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
|
/**
* 分批加载返回的黑名单信息
* @return
*/
public
List<blacknumberinfo> findPart(
int
startIndex,
int
maxCount){
SQLiteDatabase db=openhelper.getReadableDatabase();
Cursor cursor=db.rawQuery(
"select _id,phone,mode from blacknumberinfo order by _id desc limit ? offset ?"
,
new
String[]{
String.valueOf(maxCount),String.valueOf(startIndex)
});
List<blacknumberinfo> infos=
new
ArrayList<blacknumberinfo>();
while
(cursor.moveToNext()){
String phone=cursor.getString(cursor.getColumnIndex(
"phone"
));
String mode=cursor.getString(cursor.getColumnIndex(
"mode"
));
BlackNumberInfo info=
new
BlackNumberInfo();
info.setPhone(phone);
info.setMode(mode);
infos.add(info);
}
cursor.close();
db.close();
return
infos;
}
</blacknumberinfo></blacknumberinfo></blacknumberinfo>
|
分页加载解决内存溢出
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
|
/**
* 分页加载返回的黑名单信息
* @return
*/
public
List<blacknumberinfo> findPagper(
int
pagper){
SQLiteDatabase db=openhelper.getReadableDatabase();
Cursor cursor=db.rawQuery(
"select _id,phone,mode from blacknumberinfo order by _id desc limit ? offset ?"
,
new
String[]{
String.valueOf(
10
),String.valueOf(pagper*
10
)
});
List<blacknumberinfo> infos=
new
ArrayList<blacknumberinfo>();
while
(cursor.moveToNext()){
String phone=cursor.getString(cursor.getColumnIndex(
"phone"
));
String mode=cursor.getString(cursor.getColumnIndex(
"mode"
));
BlackNumberInfo info=
new
BlackNumberInfo();
info.setPhone(phone);
info.setMode(mode);
infos.add(info);
}
cursor.close();
db.close();
return
infos;
}
/**
* 获取全部总条目
* @return
*/
public
int
getTotalCount(){
SQLiteDatabase db=openhelper.getReadableDatabase();
Cursor cursor=db.rawQuery(
"select count(*) from blacknumberinfo "
,
null
);
cursor.moveToNext();
int
total=cursor.getInt(
0
);
cursor.close();
db.close();
return
total;
}
}
</blacknumberinfo></blacknumberinfo></blacknumberinfo>
|
复制资产目录下的文件到android系统下
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
|
/**
* 拷贝资产目录下的数据库到Android系统下
*/
private
void
copyDB(
final
String name) {
/*
* 数据库多时可能耗时
*/
new
Thread(){
public
void
run() {
File file=
new
File(getFilesDir(),name);
if
(file.exists()&&file.length()>
0
){
System.out.println(
"数据库已经加载过,无需在加载!"
);
}
else
{
try
{
InputStream is=getAssets().open(name);
FileOutputStream fos=
new
FileOutputStream(file);
byte
[] buffer=
new
byte
[
1024
];
int
len=-
1
;
while
((len=is.read(buffer))!=-
1
){
fos.write(buffer,
0
, len);
}
is.close();
fos.close();
}
catch
(Exception e) {
e.printStackTrace();
}
}
};
}.start();
}
|
自定义吐司
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
|
/**
* 自定义吐司
* @param address
*/
public
void
showToast(String address) {
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
View view = View.inflate(getApplicationContext(), R.layout.item_toast,
null
);
//设置背景,字体等自定义属性
int
which=getSharedPreferences(
"config"
,
0
).getInt(
"which"
,
0
);
int
bgs[]={R.drawable.btn_gray_normal,R.drawable.btn_green_normal,R.drawable.btn_gray_pressed,R.drawable.call_show_bg,R.drawable.btn_disabled};
view.setBackgroundResource(bgs[which]);
TextView tv_address=(TextView) view.findViewById(R.id.tv_address);
tv_address.setText(address);
//设置参数params
WindowManager.LayoutParams params =
new
WindowManager.LayoutParams();
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.format = PixelFormat.TRANSLUCENT;
params.type = WindowManager.LayoutParams.TYPE_TOAST;
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
wm.addView(view, params);
}
|
及时退出吐司的显示用:wm.removeView(view);
控件的拖拽效果
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
|
ImageView imgview= (ImageView) findViewById(R.id.imageview);
imgview.setOnTouchListener(
new
OnTouchListener() {
int
startx;
int
starty;
@Override
public
boolean
onTouch(View v, MotionEvent event) {
switch
(event.getAction()){
case
MotionEvent.ACTION_DOWN:
//手指第一次触摸控件时调用
//获取控件在屏幕上的坐标
startx=(
int
) event.getRawX();
starty=(
int
) event.getRawY();
break
;
case
MotionEvent.ACTION_MOVE:
//手指在控件上移动的事件
//手指移动后的偏移量
int
newx=(
int
) event.getRawX();
int
newy=(
int
) event.getRawY();
int
dx=newx-startx;
int
dy=newy-starty;
//移动后的控件新坐标
imgview.layout(imgview.getLeft()+dx, imgview.getTop()+dy,
imgview.getRight()+dx, imgview.getBottom()+dy);
//移动后重新初始化控件坐标
startx=(
int
) event.getRawX();
starty=(
int
) event.getRawY();
System.out.println(
"移动了控件"
+startx+
"---"
+starty);
break
;
case
MotionEvent.ACTION_UP:
//手指离开控件的一瞬间
break
;
}
return
true
;
}
});
|
简单双击效果实现
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
|
btn=(Button) findViewById(R.id.btn);
btn.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
if
(firsttime>
0
){
secondtime=System.currentTimeMillis();
if
((secondtime-firsttime)<
500
){
Toast.makeText(getApplicationContext(),
"双击了"
,
0
).show();
firsttime=
0
;
}
else
{
firsttime=
0
;
}
return
;
}
firsttime=System.currentTimeMillis();
new
Thread(){
public
void
run() {
try
{
Thread.sleep(
500
);
firsttime=
0
;
}
catch
(InterruptedException e) {
e.printStackTrace();
}
};
}.start();
}
});
|
多次点击事件实现
1
2
3
4
5
6
7
8
9
10
11
12
|
//定义了多长的数组就是多次点击,3就是连续3击
private
long
[] mHits=
new
long
[
3
];
/**
*四个参数:源数组,从第几个开始拷贝,目标数组,从第几个开始拷贝,拷贝的长度
*
*/
System.arraycopy(mHits,
1
, mHits,
0
, mHits.length-
1
);
mHits[mHits.length-
1
] = SystemClock.uptimeMillis();
if
(mHits[
0
] >= (SystemClock.uptimeMillis()-
500
)) {
Toast.makeText(getApplicationContext(),
"多次击了"
,
0
).show();
}
|
自定义吐司加上拖拽的效果图显示
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
|
/**
* 自定义吐司
* @param address
*/
public
void
showToast(String address) {
wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
view = View.inflate(getApplicationContext(), R.layout.item_toast,
null
);
view.setOnTouchListener(
new
OnTouchListener() {
int
startx ;
int
starty ;
@SuppressWarnings
(
"deprecation"
)
@Override
public
boolean
onTouch(View v, MotionEvent event) {
switch
(event.getAction()){
case
MotionEvent.ACTION_DOWN:
//手指触摸
//获取自定义吐司坐标
startx=(
int
) event.getRawX();
starty=(
int
) event.getRawY();
break
;
case
MotionEvent.ACTION_UP:
//手指离开
//存储控件的位置坐标
SharedPreferences sp = getSharedPreferences(
"config"
, MODE_PRIVATE);
Editor edit=sp.edit();
edit.putInt(
"lastx"
, params.x);
edit.putInt(
"lasty"
, params.y);
edit.commit();
break
;
case
MotionEvent.ACTION_MOVE:
//手指移动
//获取偏移量
int
newx=(
int
) event.getRawX();
int
newy=(
int
) event.getRawY();
int
dx=newx-startx;
int
dy=newy-starty;
params.x +=dx;
params.y +=dy;
//判断view控件是否移出屏幕范围
if
(params.x>(wm.getDefaultDisplay().getWidth()-view.getWidth())){
params.x=wm.getDefaultDisplay().getWidth()-view.getWidth();
}
if
(params.y>(wm.getDefaultDisplay().getHeight()-view.getHeight())){
params.x=wm.getDefaultDisplay().getHeight()-view.getHeight();
}
wm.updateViewLayout(view, params);
//重新初始化控件坐标
startx=(
int
) event.getRawX();
starty=(
int
) event.getRawY();
break
;
}
return
true
;
}
});
//设置背景颜色
int
which=getSharedPreferences(
"config"
,
0
).getInt(
"which"
,
0
);
int
bgs[]={R.drawable.btn_gray_normal,R.drawable.btn_green_normal,R.drawable.btn_gray_pressed,R.drawable.call_show_bg,R.drawable.btn_disabled};
view.setBackgroundResource(bgs[which]);
TextView tv_address=(TextView) view.findViewById(R.id.tv_address);
tv_address.setText(address);
params =
new
WindowManager.LayoutParams();
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.format = PixelFormat.TRANSLUCENT;
//左上对齐
params.gravity=Gravity.LEFT+Gravity.TOP;
SharedPreferences sp=getSharedPreferences(
"config"
, MODE_PRIVATE);
params.x=sp.getInt(
"lastx"
,
0
);
params.y=sp.getInt(
"lasty"
,
0
);
params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
wm.addView(view, params);
}
|