由於安卓6.0以後改變了系統API,對於敏感權限做了很多修改之前通過監聽系統廣播添加action 爲
android.intent.action.PHONE_STATE等方法已經不再實用,經過測試發現用aidl反射調用系統api可以
1、編寫一個類 extends PhoneStateListener
private static int lastCallState = TelephonyManager.CALL_STATE_IDLE;
/**
* 監聽來電狀態
*/
public class PhoneCallListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int currentCallState, String incomingNumber) {
if (currentCallState == TelephonyManager.CALL_STATE_IDLE) {// 空閒
//TODO
} else if (currentCallState == TelephonyManager.CALL_STATE_RINGING) {// 響鈴
//TODO
} else if (currentCallState == TelephonyManager.CALL_STATE_OFFHOOK) {// 接聽
//TODO
}
//未接來電數量統計
if (lastCallState == TelephonyManager.CALL_STATE_RINGING &&
currentCallState == TelephonyManager.CALL_STATE_IDLE) {
Log.i("test", "onReceive: " + readMissCall());
}
lastCallState = currentCallState;
super.onCallStateChanged(currentCallState, incomingNumber);
}
}
private int readMissCall() {
int result = 0;
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
return -1;
}
Cursor cursor = MainActivity.this.getContentResolver().query(CallLog.Calls.CONTENT_URI, new String[]{
CallLog.Calls.TYPE
}, " type=? and new=?", new String[]{
CallLog.Calls.MISSED_TYPE + "", "1"
}, "date desc");
if (cursor != null) {
result = cursor.getCount();
cursor.close();
}
return result;
}
2、獲取TelephonyManager,添加Listener
private PhoneCallListener callListener;
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
callListener = new PhoneCallListener();
telephonyManager.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
擴展:
可以實現自動拒接電話,黑名單功能
需要用aidl
按照系統iTelephony.aidl文件的路徑,新建一個相同文件,其接口內方法只需要寫endCall()
,注意路徑必須要完全相同:
package com.android.internal.telephony;
interface ITelephony {
boolean endCall();
}
public static void endPhone(Context context) {
TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
Method method = null;
try {
method = TelephonyManager.class.getDeclaredMethod("getITelephony");
method.setAccessible(true);
ITelephony telephony = (ITelephony) method.invoke(telephonyManager);
telephony.endCall();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
電話響起時候調用 endPhone