如何挂断在Android的传出呼叫?

我正在开发一个应用程序,其中我们需要的一件事是控制传出的呼叫,至less是能够阻止它从我们的应用程序。

我已经尝试从现有的活动使用Intent.ACTION_CALL

 Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber)); startActivity(callIntent); 

但是停止通话似乎是通过API禁止的。

你能提出一些解决方法吗?

例如:在通话过程中启用飞行模式? 只是一个例子; 这黑客没有为我工作。

BroadcastReceiver捕获拨出电话已被提及,如果您想在拨号之前结束呼叫,这绝对是最好的方式。

一旦拨号或通话,但是,这种技术不再起作用。 到目前为止遇到的唯一方法就是通过Java Reflection来完成。 由于它不是公共API的一部分,你应该小心使用它,而不是依赖它 。 Android的内部组成的任何变化将有效地打破你的应用程序。

Prasanta Paul的博客演示了如何完成,我在下面总结。

获取ITelephony对象:

 TelephonyManager tm = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); try { // Java reflection to gain access to TelephonyManager's // ITelephony getter Log.v(TAG, "Get getTeleService..."); Class c = Class.forName(tm.getClass().getName()); Method m = c.getDeclaredMethod("getITelephony"); m.setAccessible(true); com.android.internal.telephony.ITelephony telephonyService = (ITelephony) m.invoke(tm); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "FATAL ERROR: could not connect to telephony subsystem"); Log.e(TAG, "Exception object: " + e); } 

结束通话:

 telephonyService.endCall(); 

尝试这个:

(我用Reflection来访问高级电话function并修改一些东西)

 // required permission <uses-permission android:name="android.permission.CALL_PHONE"/> try { //String serviceManagerName = "android.os.IServiceManager"; String serviceManagerName = "android.os.ServiceManager"; String serviceManagerNativeName = "android.os.ServiceManagerNative"; String telephonyName = "com.android.internal.telephony.ITelephony"; Class telephonyClass; Class telephonyStubClass; Class serviceManagerClass; Class serviceManagerStubClass; Class serviceManagerNativeClass; Class serviceManagerNativeStubClass; Method telephonyCall; Method telephonyEndCall; Method telephonyAnswerCall; Method getDefault; Method[] temps; Constructor[] serviceManagerConstructor; // Method getService; Object telephonyObject; Object serviceManagerObject; telephonyClass = Class.forName(telephonyName); telephonyStubClass = telephonyClass.getClasses()[0]; serviceManagerClass = Class.forName(serviceManagerName); serviceManagerNativeClass = Class.forName(serviceManagerNativeName); Method getService = // getDefaults[29]; serviceManagerClass.getMethod("getService", String.class); Method tempInterfaceMethod = serviceManagerNativeClass.getMethod( "asInterface", IBinder.class); Binder tmpBinder = new Binder(); tmpBinder.attachInterface(null, "fake"); serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder); IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone"); Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class); telephonyObject = serviceMethod.invoke(null, retbinder); //telephonyCall = telephonyClass.getMethod("call", String.class); telephonyEndCall = telephonyClass.getMethod("endCall"); //telephonyAnswerCall = telephonyClass.getMethod("answerRingingCall"); telephonyEndCall.invoke(telephonyObject); } catch (Exception e) { e.printStackTrace(); Log.error(DialerActivity.this, "FATAL ERROR: could not connect to telephony subsystem"); Log.error(DialerActivity.this, "Exception object: " + e); } 
  1. 创build一个优先级为0的BroadcastReceiver
  2. BC在其onReceive方法中拦截ACTION_NEW_OUTGOING_CALL意图
  3. 在同一个方法中调用setResultData(null)

这将阻止呼叫发起(只要你的接收者是最后处理我认为的意图)

您可以尝试启用,然后禁用飞行模式:

 android.provider.Settings.System.putInt(getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, 1); Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); intent.putExtra("state", 1); sendBroadcast(new Intent("android.intent.action.AIRPLANE_MODE")); sendBroadcast(intent); android.provider.Settings.System.putInt(getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, 0); intent.putExtra("state", 0); sendBroadcast(new Intent("android.intent.action.AIRPLANE_MODE")); sendBroadcast(intent); 

对于Ilana:

 public class ilanasReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) { if (getResultData()!=null) { String number = "123456"; setResultData(number); } } } } 

另外在Manifest中放入包部分:

 <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> 

就这些。

考虑到美妙的恶作剧的潜力,我会惊讶,如果这是允许的。

这个线程平淡地说API不能结束一个调用 。 其他人也尝试过 。

根据ACTION_NEW_OUTGOING_CALL的文档

意图将具有以下额外价值:

EXTRA_PHONE_NUMBER – 最初打算拨打的电话号码。

一旦广播结束,resultData被用作实际的号码来呼叫。 如果为空,则不会发出呼叫。

Interesting Posts