我正在写一个Android应用程序,我需要接听来电,做一些工作,然后结束通话.
在所有谷歌搜索之后,我可以找到两种不同的方法来实现这一点,这两种方法都不适用于Android的最新版本,特别是在4.1,Jelly Bean之后.
I.)使用广播接收器中的Java Reflection为“android.intent.action.PHONE_STATE”访问“com.android.internal.telephony.ITelephony”.下面的示例代码可以在数百个相关帖子中找到:
public class PhoneCallReceiver extends BroadcastReceiver {
Context context = null;
private static final String TAG = "Phone call";
private ITelephony telephonyService;
@Override
public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals("android.intent.action.PHONE_STATE"))
return;
Log.v(TAG, "Receving....");
TelephonyManager telephony = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Log.v(TAG, "Get getTeleService...");
Class c = Class.forName(telephony.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(telephony);
telephonyService.silenceRinger();
Log.v(TAG, "Answering Call now...");
telephonyService.answerRingingCall();
Log.v(TAG, "Call answered...");
//telephonyService.endCall();
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG,
"FATAL ERROR: could not connect to telephony subsystem");
Log.e(TAG, "Exception object: " + e);
}
}
}
这段代码的问题在于
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
此方法需要工作,并且此权限已被定义为android v 2.3中的“仅适用于系统应用程序”.简而言之,普通用户应用程序无法再在清单文件中定义此权限.
II.)另一种方法是模拟推动Headset钩子,这使Android接听电话.这是通过广播“Intent.ACTION_MEDIA_BUTTON”来完成的,如下面的代码所示.
public class PhoneCallReceiver extends BroadcastReceiver {
Context context = null;
private static final String TAG = "Phone call";
@Override
public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals("android.intent.action.PHONE_STATE"))
return;
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
Intent answer = new Intent(Intent.ACTION_MEDIA_BUTTON);
answer.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
context.sendOrderedBroadcast(answer, null);
Log.d(TAG, "Answered incoming call from: " + number);
}
return;
}
}
此方法适用于Android 4.1,之后android限制用户应用程序广播“Intent.ACTION_MEDIA_BUTTON”.
所以我的结论是,目前我们无法在Android 4.1或更高版本中实现这一目标.
有没有其他人找到这个问题的任何其他解决方案或解决方法?
解决方法:
这适用于从Android 2.2到4.0,现在将try catch添加到最后一行后,它适用于4.1.2和4.2坦率地说,不知道它是如何工作的,但它适用于我.
Log.d(tag, "InSecond Method Ans Call");
// froyo and beyond trigger on buttonUp instead of buttonDown
Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);
buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");
Intent headSetUnPluggedintent = new Intent(Intent.ACTION_HEADSET_PLUG);
headSetUnPluggedintent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
headSetUnPluggedintent.putExtra("state", 0);
headSetUnPluggedintent.putExtra("name", "Headset");
try {
sendOrderedBroadcast(headSetUnPluggedintent, null);
} catch (Exception e) {
e.printStackTrace();
}
这对我在Android 4.1.2中工作以及我在4.2上测试过
这仍然是一个处理的异常.
编辑结束通话
希望这有助于所有寻找答案和结束通话的整体解决方案的人.
/**
* Reject button click listener will reject the incoming call.
*/
private class RejectCallOnClickListener implements OnClickListener {
@Override
public void onClick(View v) {
Log.d(tag, "OnRejectButton: " + "Reject OnClick");
ignoreCall();
exitCleanly();
}
}
/**
* ignore incoming calls
*/
private void ignoreCall() {
if (USE_ITELEPHONY)
ignoreCallAidl();
else
ignoreCallPackageRestart();
}
/**
* AIDL/ITelephony technique for ignoring calls
*/
private void ignoreCallAidl() {
try {
// telephonyService.silenceRinger();
telephonyService.endCall();
} catch (RemoteException e) {
e.printStackTrace();
Log.d(tag, "ignoreCall: " + "Error: " + e.getMessage());
} catch (Exception e) {
e.printStackTrace();
Log.d(tag, "ignoreCall" + "Error: " + e.getMessage());
}
}
/**
* package restart technique for ignoring calls
*/
private void ignoreCallPackageRestart() {
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
am.restartPackage("com.android.providers.telephony");
am.restartPackage("com.android.phone");
}
/**
* cleanup and exit routine
*/
private void exitCleanly() {
unHookReceiver();
this.finish();
}