我正在开发一个应用程序,其中我们需要做的一件事情是控制拨出电话,至少可以阻止它从我们的应用程序中停止。
我已经尝试使用现有活动中的Intent.ACTION_CALL
:
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber));
startActivity(callIntent);
但是通过API似乎不允许停止调用。
您能建议一些解决方法吗?
例如:在通话中启用飞行模式?只是一个例子;此hack对我不起作用。
尝试一下:
((我使用了Reflection to access advanced telephony features并修改了一些内容)// 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);
}
BroadcastReceiver
。ACTION_NEW_OUTGOING_CALL
方法拦截onReceive
意图setResultData(null)
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS"/>
在代码中,使用此:
Java:
@SuppressLint("PrivateApi") public static boolean endCall(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { final TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); if (telecomManager != null && ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) { telecomManager.endCall(); return true; } return false; } //use unofficial API for older Android versions, as written here: https://stackoverflow.com/a/8380418/878126 try { final Class<?> telephonyClass = Class.forName("com.android.internal.telephony.ITelephony"); final Class<?> telephonyStubClass = telephonyClass.getClasses()[0]; final Class<?> serviceManagerClass = Class.forName("android.os.ServiceManager"); final Class<?> serviceManagerNativeClass = Class.forName("android.os.ServiceManagerNative"); final Method getService = serviceManagerClass.getMethod("getService", String.class); final Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class); final Binder tmpBinder = new Binder(); tmpBinder.attachInterface(null, "fake"); final Object serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder); final IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone"); final Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class); final Object telephonyObject = serviceMethod.invoke(null, retbinder); final Method telephonyEndCall = telephonyClass.getMethod("endCall"); telephonyEndCall.invoke(telephonyObject); return true; } catch (Exception e) { e.printStackTrace(); LogManager.e(e); } return false; }
或在科特林:
@SuppressLint("PrivateApi")
fun endCall(context: Context): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) {
telecomManager.endCall()
return true
}
return false
}
//use unofficial API for older Android versions, as written here: https://stackoverflow.com/a/8380418/878126
try {
val telephonyClass = Class.forName("com.android.internal.telephony.ITelephony")
val telephonyStubClass = telephonyClass.classes[0]
val serviceManagerClass = Class.forName("android.os.ServiceManager")
val serviceManagerNativeClass = Class.forName("android.os.ServiceManagerNative")
val getService = serviceManagerClass.getMethod("getService", String::class.java)
val tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder::class.java)
val tmpBinder = Binder()
tmpBinder.attachInterface(null, "fake")
val serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder)
val retbinder = getService.invoke(serviceManagerObject, "phone") as IBinder
val serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder::class.java)
val telephonyObject = serviceMethod.invoke(null, retbinder)
val telephonyEndCall = telephonyClass.getMethod("endCall")
telephonyEndCall.invoke(telephonyObject)
return true
} catch (e: Exception) {
e.printStackTrace()
return false
}
}