攔截電話需要權限
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
清除來電記錄需要權限
<uses-permission
android:name="android.permission.READ_CALL_LOG"></uses-permission>
<uses-permission
android:name="android.permission.WRITE_CALL_LOG"></uses-permission>
CallSafeService.java需要aidl來實作endCall()方法,内容觀察者修改來電中黑名單的電話給删除,業務邏輯方法
package com.ldw.safe.service;
import java.lang.reflect.Method;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import com.android.internal.telephony.ITelephony;
import com.ldw.safe.db.dao.BlackNumberDao;
public class CallSafeService extends Service {
private BlackNumberDao dao;
private TelephonyManager tm;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
super.onCreate();
dao = new BlackNumberDao(this);
//攔截電話
//擷取到TelephonyManager對象
tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
//建立電話監聽的對象
MyPhoneStateListener listener = new MyPhoneStateListener();
//監聽電話的狀态
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
//初始化短信的廣播,攔截短信
InnerReceiver innerReceiver = new InnerReceiver();
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
intentFilter.setPriority(Integer.MAX_VALUE);
registerReceiver(innerReceiver, intentFilter);
}
private class MyPhoneStateListener extends PhoneStateListener{
//電話狀态改變的監聽
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
//TelephonyManager#CALL_STATE_IDLE 電話閑置
//TelephonyManager#CALL_STATE_RINGING 電話鈴響的狀态
//TelephonyManager#CALL_STATE_OFFHOOK 電話接通
switch (state){
//電話鈴響的狀态
case TelephonyManager.CALL_STATE_RINGING:
//擷取來電的号碼的攔截模式
String mode = dao.findNumber(incomingNumber);
/**
* 黑名單攔截模式
* 1 全部攔截 電話攔截 + 短信攔截
* 2 電話攔截
* 3 短信攔截
*/
if(mode.equals("1")|| mode.equals("2")){
System.out.println("挂斷黑名單電話号碼");
//利用内容觀察者,清楚打進來的電話
Uri uri = Uri.parse("content://call_log/calls");
getContentResolver().registerContentObserver(uri,true,new MyContentObserver(new Handler(),incomingNumber));
//挂斷電話
endCall();
}
break;
}
}
}
private class MyContentObserver extends ContentObserver{
String incomingNumber;
/**
* Creates a content observer.
*
* @param handler The handler to run {@link #onChange} on, or null if none.
* @param incomingNumber
*/
public MyContentObserver(Handler handler, String incomingNumber) {
super(handler);
this.incomingNumber = incomingNumber;
}
//當資料改變的時候調用的方法
@Override
public void onChange(boolean selfChange) {
getContentResolver().unregisterContentObserver(this);
//删除電話号碼
deleteCallLog(incomingNumber);
super.onChange(selfChange);
}
}
//删掉電話号碼
private void deleteCallLog(String incomingNumber) {
Uri uri = Uri.parse("content://call_log/calls");
//删除表中的電話号碼
getContentResolver().delete(uri,"number=?",new String[]{incomingNumber});
}
//初始化短信的廣播,攔截短信
private class InnerReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("短信來了");
Object[] objects = (Object[]) intent.getExtras().get("pdus");
for (Object object : objects) {// 短信最多140位元組,
// 超出的話,會分為多條短信發送,是以是一個數組,因為我們的短信指令很短,是以for循環隻執行一次
SmsMessage message = SmsMessage.createFromPdu((byte[]) object);
String originatingAddress = message.getOriginatingAddress();// 短信來源号碼
String messageBody = message.getMessageBody();// 短信内容
//通過短信的電話号碼查詢攔截的模式
String mode = dao.findNumber(originatingAddress);
/**
* 黑名單攔截模式
* 1 全部攔截 電話攔截 + 短信攔截
* 2 電話攔截
* 3 短信攔截
*/
if(mode.equals("1")){
abortBroadcast();
}else if(mode.equals("3")){
abortBroadcast();
}
//智能攔截模式 發票 你的頭發漂亮 分詞
if(messageBody.contains("fapiao")){
abortBroadcast();
}
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
/*
* 挂掉電話
*/
public void endCall() {
try {
//通過類加載器加載ServiceManager
Class<?> clazz = getClassLoader().loadClass("android.os.ServiceManager");
//通過反射得到目前的方法
Method method = clazz.getDeclaredMethod("getService", String.class);
IBinder iBinder = (IBinder) method.invoke(null, TELEPHONY_SERVICE);
//利用aidl擷取到endcalll方法
ITelephony iTelephony = ITelephony.Stub.asInterface(iBinder);
iTelephony.endCall();
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用aidl的步驟
1.再main下面建立一個aidl檔案夾。

2.
再aidl目錄下面建立一個包名的檔案夾再将aidl檔案拷貝到相關的目錄下,NeighboringCellInfo也需要引入進來