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

来源:互联网 发布:java wait超时 编辑:程序博客网 时间:2024/04/29 23:49

短信拦截:开启服务并在里面注册一个广播接收者

?
1
2
3
开启服务:
Intent intent=newIntent(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
publicclass CallSmsSafeService extendsService {
    privateBlackNumberDao dao;
    privateInnerReceiver receiver;
    @Override
    publicIBinder onBind(Intent intent) {
        returnnull;
    }
    @Override
    publicvoid onCreate() {
        dao=newBlackNumberDao(this);
    //动态注册
        receiver=newInnerReceiver();
        IntentFilter filter=newIntentFilter();
        //设置关心短信到来的动作
        filter.addAction("android.provider.Telephony.SMS_RECEIVED");
        filter.setPriority(Integer.MAX_VALUE);
        //代码注册广播接收者
        registerReceiver(receiver, filter);
        System.out.println("黑名单短信拦截开启了!!!!!");
        super.onCreate();
 
    }
 
    @Override
    publicvoid onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
        receiver=null;
    }
    //内部类广播接收者
    privateclass InnerReceiver extendsBroadcastReceiver{
        @Override
        publicvoid 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: 服务的全路经名
 */
publicstatic 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)){
                returntrue;
            }
    }
    returnfalse;
}
</runningserviceinfo>

分词算法:
开源算法:
luncence

利用反射原理挂断电话

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 * 挂断电话的方法,利用反射
 */
publicvoid 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
//监视呼叫记录的的数据库,看什么时候生成了,
//就把它删除
Uri uri=Uri.parse("content://call_log/calls");
getContentResolver().registerContentObserver(uri,true,newContentObserver(newHandler()) {
 
    @Override
    publicvoid onChange(booleanselfChange) {
        super.onChange(selfChange);
        deleteCallLog(incomingNumber);
    }
});
 
 
/**
 * 删除拨号记录
 * @param incomingNumber
 */
publicvoid deleteCallLog(String incomingNumber) {
 
    ContentResolver resolver=getContentResolver();
    Uri uri=Uri.parse("content://call_log/calls");
    resolver.delete(uri,"number=?",newString[]{incomingNumber});
}
<h2 id="打断点看内存查源码">打断点、看内存、查源码

电话的拦截功能:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    /**
 * 定义电话管理的服务
 */
privateTelephonyManager tm;
privateMyPhoneStateListener listener;
 
    /**
     * 实例化电话管理的服务
     */
    tm=(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    //注册电话的监听器
    listener=newMyPhoneStateListener();
    //监听电话的状态的改变
    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
classMyPhoneStateListener extendsPhoneStateListener{
 
    @Override
    publicvoid onCallStateChanged(intstate, String incomingNumber) {
        super.onCallStateChanged(state, incomingNumber);
 
        switch(state){
        caseTelephonyManager.CALL_STATE_IDLE://空闲状态
            break;
 
        caseTelephonyManager.CALL_STATE_RINGING://响铃状态
 
            String mode=dao.find(incomingNumber);
            if(mode.equals("1")||mode.equals("3")){
                System.out.println("挂断电话");
 
            }
 
            break;
 
        caseTelephonyManager.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
packagecom.cca.mobilephone.Utils;
importjava.util.List;
importandroid.app.ActivityManager;
importandroid.app.ActivityManager.RunningServiceInfo;
importandroid.content.Context;
publicclass ServicerUtils {
 
/**
 * 判断系统的服务是否在后台运行
 */
publicstatic 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);
                returntrue;
            }
    }
    returnfalse;
}
</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
packagecom.cca.mobilephone.db.dao;
 
importjava.util.ArrayList;
importjava.util.List;
importandroid.content.ContentValues;
importandroid.content.Context;
importandroid.database.Cursor;
importandroid.database.sqlite.SQLiteDatabase;
 
importcom.cca.mobilephone.db.BlackNumberOpenHeloper;
importcom.cca.mobilephone.domain.BlackNumberInfo;
 
publicclass BlackNumberDao {
 
privateBlackNumberOpenHeloper openhelper;
 
/**
 * 数据库的构造函数
 * @param context
 */
publicBlackNumberDao(Context context) {
    super();
    openhelper=newBlackNumberOpenHeloper(context);
}
 
 
 
/**
 * 往数据库中增加号码
 * @param phone 增加的电话号码
 * @param mode  模式
 * @return
 */
publicboolean add(String phone,String mode){
    SQLiteDatabase db=openhelper.getWritableDatabase();    
    ContentValues values=newContentValues();
    values.put("phone", phone);
    values.put("mode", mode);
 
    longid=db.insert("blacknumberinfo",null, values);
    db.close();
    if(id!=-1){
        returntrue;
    }else{
    returnfalse;
    }
 
}
 
 
/**
 * 修改黑名单的拦截模式
 * @param phone 要修改的黑名单号码
 * @param newmode 新的拦截模式
 * @return 修改是否成功
 */
publicboolean update(String phone,String newmode){
 
    SQLiteDatabase db=openhelper.getWritableDatabase();
    ContentValues values=newContentValues();
    values.put("mode", newmode);
    introwcount=db.update("blacknumberinfo", values, "phone=?",newString[]{phone});
    db.close();
    if(rowcount==0){
        returnfalse;
    }else{
        returntrue;
    }
}
/**
 * 查找黑名单号码的拦截模式
 * @param phone 要查找的电话号码
 * @return  返回拦截的模式
 */
publicString find(String phone){
    String mode=null;
    SQLiteDatabase db=openhelper.getReadableDatabase();
    Cursor cursor=db.query("blacknumberinfo",null,"phone=?",newString[]{phone},null,null,null);
    if(cursor.moveToNext()){
        mode=cursor.getString(cursor.getColumnIndex("mode"));;
    }
    cursor.close();
    db.close();
    returnmode;
 
}
 
/**
 * 删除黑名单号码
 * @param phone  要删除的号码
 * @return  是否删除成功
 */
 
publicboolean delete(String phone){
    SQLiteDatabase db=openhelper.getWritableDatabase();
    introwcount=db.delete("blacknumberinfo","phone=?",newString[]{phone});
    db.close();
    if(rowcount==0){
        returnfalse;
    }{
        returntrue;
    }
}
/**
 * 返回全部的黑名单信息
 * @return
 */
publicList<blacknumberinfo> findAll(){
 
    SQLiteDatabase db=openhelper.getReadableDatabase();
    Cursor cursor=db.query("blacknumberinfo",null,null,null,null,null,"_id desc");
    List<blacknumberinfo> infos=newArrayList<blacknumberinfo>();
    while(cursor.moveToNext()){
        String phone=cursor.getString(cursor.getColumnIndex("phone"));
        String mode=cursor.getString(cursor.getColumnIndex("mode"));
        BlackNumberInfo info=newBlackNumberInfo();
        info.setPhone(phone);
        info.setMode(mode);
        infos.add(info);
    }
    cursor.close();
    db.close();
    returninfos;
}
</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
 */
publicList<blacknumberinfo> findPart(intstartIndex,intmaxCount){
 
    SQLiteDatabase db=openhelper.getReadableDatabase();
    Cursor cursor=db.rawQuery("select _id,phone,mode from blacknumberinfo order by _id desc limit ? offset ?",newString[]{
            String.valueOf(maxCount),String.valueOf(startIndex)
    });
 
    List<blacknumberinfo> infos=newArrayList<blacknumberinfo>();
    while(cursor.moveToNext()){
        String phone=cursor.getString(cursor.getColumnIndex("phone"));
        String mode=cursor.getString(cursor.getColumnIndex("mode"));
        BlackNumberInfo info=newBlackNumberInfo();
        info.setPhone(phone);
        info.setMode(mode);
        infos.add(info);
    }
    cursor.close();
    db.close();
    returninfos;
}
</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
 */
publicList<blacknumberinfo> findPagper(intpagper){
    SQLiteDatabase db=openhelper.getReadableDatabase();
    Cursor cursor=db.rawQuery("select _id,phone,mode from blacknumberinfo order by _id desc limit ? offset ?",newString[]{
            String.valueOf(10),String.valueOf(pagper*10)
    });
 
    List<blacknumberinfo> infos=newArrayList<blacknumberinfo>();
    while(cursor.moveToNext()){
        String phone=cursor.getString(cursor.getColumnIndex("phone"));
        String mode=cursor.getString(cursor.getColumnIndex("mode"));
        BlackNumberInfo info=newBlackNumberInfo();
        info.setPhone(phone);
        info.setMode(mode);
        infos.add(info);
    }
    cursor.close();
    db.close();
    returninfos;
}
 
 
 
/**
 * 获取全部总条目
 * @return
 */
 
publicint getTotalCount(){
 
    SQLiteDatabase db=openhelper.getReadableDatabase();
    Cursor cursor=db.rawQuery("select count(*) from blacknumberinfo ",null);
 
    cursor.moveToNext();
    inttotal=cursor.getInt(0);
    cursor.close();
    db.close();
    returntotal;
}
}
</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系统下
 */
privatevoid copyDB(finalString name) {
 
    /*
     * 数据库多时可能耗时
     */
    newThread(){
        publicvoid run() {
            File file=newFile(getFilesDir(),name);
            if(file.exists()&&file.length()>0){
            System.out.println("数据库已经加载过,无需在加载!");
            }else{
 
            try{
                InputStream is=getAssets().open(name);
                FileOutputStream fos=newFileOutputStream(file);
                byte[] buffer=newbyte[1024];
                intlen=-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
 */
publicvoid showToast(String address) {
    WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    View view = View.inflate(getApplicationContext(), R.layout.item_toast, null);
    //设置背景,字体等自定义属性
    intwhich=getSharedPreferences("config",0).getInt("which",0);
    intbgs[]={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 = newWindowManager.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(newOnTouchListener() {
        intstartx;
        intstarty;
        @Override
        publicboolean onTouch(View v, MotionEvent event) {
 
            switch(event.getAction()){
            caseMotionEvent.ACTION_DOWN://手指第一次触摸控件时调用
                //获取控件在屏幕上的坐标
                startx=(int) event.getRawX();
                starty=(int) event.getRawY();
                break;
 
            caseMotionEvent.ACTION_MOVE://手指在控件上移动的事件
                //手指移动后的偏移量
                intnewx=(int) event.getRawX();
                intnewy=(int) event.getRawY();
                intdx=newx-startx;
                intdy=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;
 
            caseMotionEvent.ACTION_UP://手指离开控件的一瞬间
 
                break;
            }
            returntrue;
 
 
        }
    });

简单双击效果实现

?
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(newOnClickListener() {
        @Override
        publicvoid 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();
            newThread(){
                publicvoid 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击   
privatelong[] mHits=newlong[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
 */
publicvoid showToast(String address) {
    wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    view = View.inflate(getApplicationContext(), R.layout.item_toast, null);
 
    view.setOnTouchListener(newOnTouchListener() {
        intstartx ;
        intstarty ;
 
        @SuppressWarnings("deprecation")
        @Override
        publicboolean onTouch(View v, MotionEvent event) {
 
            switch(event.getAction()){
            caseMotionEvent.ACTION_DOWN://手指触摸
                //获取自定义吐司坐标
                startx=(int) event.getRawX();
                starty=(int) event.getRawY();
 
                break;
            caseMotionEvent.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;
            caseMotionEvent.ACTION_MOVE://手指移动
                //获取偏移量
                intnewx=(int) event.getRawX();
                intnewy=(int) event.getRawY();
                intdx=newx-startx;
                intdy=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;
            }
 
            returntrue;
        }
    });
    //设置背景颜色
    intwhich=getSharedPreferences("config",0).getInt("which",0);
    intbgs[]={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 = newWindowManager.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);
 
}

2 0