/**
* 通過反射調用的方法,接聽電話,該方法只在android 2.3之前的系統上有效。
*
* @param context
*/
private static void answerRingingCallWithReflect(Context context) {
try {
Object telephonyObject = getTelephonyObject(context);
if (null != telephonyObject) {
Class telephonyClass = telephonyObject.getClass();
Method endCallMethod = telephonyClass
.getMethod("answerRingingCall");
endCallMethod.setAccessible(true);
endCallMethod.invoke(telephonyObject);
// ITelephony iTelephony = (ITelephony) telephonyObject;
// iTelephony.answerRingingCall();
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
/**
* 偽造一個有線耳機插入,並按接聽鍵的廣播,讓系統開始接聽電話。
*
* @param context
*/
private static void answerRingingCallWithBroadcast(Context context) {
try {
Runtime runtime = Runtime.getRuntime();
runtime.exec("input keyevent " +KeyEvent.KEYCODE_HEADSETHOOK);
} catch (Exception e) {
AudioManager audioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
// 判斷是否插上了耳機
if (!audioManager.isWiredHeadsetOn()) {
// 4.1以上系統限制了部分權限, 使用三星4.1版本測試提示警告:Permission Denial: not allowed to
// send broadcast android.intent.action.HEADSET_PLUG from pid=1324,
// uid=10017
// 這里需要注意一點,發送廣播時加了權限“android.permission.CALL_PRIVLEGED”,則接受該廣播時也需要增加該權限。但是4.1以上版本貌似這個權限只能系統應用才可以得到。測試的時候,自定義的接收器無法接受到此廣播,后來去掉了這個權限,設為NULL便可以監聽到了。
if (android.os.Build.VERSION.SDK_INT >= 15) {
Intent meidaButtonIntent = new Intent(
Intent.ACTION_MEDIA_BUTTON);
KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK);
meidaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
context.sendOrderedBroadcast(meidaButtonIntent, null);
} else {
// 以下適用於Android2.3及2.3以上的版本上 ,但測試發現4.1系統上不管用。
Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG);
localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
localIntent1.putExtra("state", 1);
localIntent1.putExtra("microphone", 1);
localIntent1.putExtra("name", "Headset");
context.sendOrderedBroadcast(localIntent1,
"android.permission.CALL_PRIVILEGED");
Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON);
KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_HEADSETHOOK);
localIntent2.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent1);
context.sendOrderedBroadcast(localIntent2,
"android.permission.CALL_PRIVILEGED");
Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON);
KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK);
localIntent3.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent2);
context.sendOrderedBroadcast(localIntent3,
"android.permission.CALL_PRIVILEGED");
Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG);
localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
localIntent4.putExtra("state", 0);
localIntent4.putExtra("microphone", 1);
localIntent4.putExtra("name", "Headset");
context.sendOrderedBroadcast(localIntent4,
"android.permission.CALL_PRIVILEGED");
}
} else {
Intent meidaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK);
meidaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
context.sendOrderedBroadcast(meidaButtonIntent, null);
}
}
}
/**
* <br/>
* 概述:接電話 <br/>
*
* @param context
*/
public static void answerRingingCall(Context context) {
if (isGingerbreadOrlater()) {
answerRingingCallWithBroadcast(context);
} else {
answerRingingCallWithReflect(context);
}
}
由於谷歌官方在2016年的十月份給5.1以上的設備更新了安全補丁,導致了以上接電話的方法不能使用了(參考https://stackoverflow.com/questions/40673922/regd-support-of-answer-call-in-android-nougat/41356688#41356688),
目前只有一種方法可以測試通過,就是通過讀取通知的權限來實現(參考https://stackoverflow.com/questions/41542245/programmatically-accept-call-in-nougat https://stackoverflow.com/a/43254844/7204388 )。
但我也遇到了問題,讀取通知是根據文字來獲取對應的pendingIntent,然后再發送通知,但是有的來電話界面並沒有對應的文字,所以是不能獲取到對應的intent的。如果你有更好的解決方法,請聯系我714094450