由于安卓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