我正在尝试结束用户拨打的电话。基本上我会允许一些用户能够拨打和拨打电话的号码,否则所有其他电话将会结束,用户将无法拨打其他号码。
现在的问题是我已经尝试了几种方法,但它不起作用
我在做什么:
我有一个广播接收器,当用户拨打号码
时被触发在它下面我得到拨打的号码,如果不是我想要的号码,我会尝试结束它。
以下是我在接收方法中所做的事情。
public void onReceive(Context context, Intent intent) {
Log.d(OutgoingCallReceiver.class.getSimpleName(), intent.toString());
//TODO: Handle outgoing call event here
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
disconnectCall();
Toast.makeText(context, "DisConnecting! = "+phoneNumber, Toast.LENGTH_LONG).show();
killCall(context);
TelephonyManager tm=(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Method m1 = null;
try {
m1 = tm.getClass().getDeclaredMethod("getITelephony");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
m1.setAccessible(true);
Object iTelephony = null;
try {
iTelephony = m1.invoke(tm);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
Method m2 = null;
try {
m2 = iTelephony.getClass().getDeclaredMethod("silenceRinger");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Method m3 = null;
try {
m3 = iTelephony.getClass().getDeclaredMethod("endCall");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
// try {
// // m2.invoke(iTelephony);
// } catch (IllegalAccessException e) {
// e.printStackTrace();
// } catch (InvocationTargetException e) {
// e.printStackTrace();
// }
try {
m3.invoke(iTelephony);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
TelephonyManager telephony = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(telephony.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(telephony);
//telephonyService.silenceRinger();
telephonyService.endCall();
} catch (Exception e) {
e.printStackTrace();
}
// }
}
和Endig Call方法
public void disconnectCall(){
try {
String serviceManagerName = "android.os.ServiceManager";
String serviceManagerNativeName = "android.os.ServiceManagerNative";
String telephonyName = "com.android.internal.telephony.ITelephony";
Class<?> telephonyClass;
Class<?> telephonyStubClass;
Class<?> serviceManagerClass;
Class<?> serviceManagerNativeClass;
Method telephonyEndCall;
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);
telephonyEndCall = telephonyClass.getMethod("endCall");
telephonyEndCall.invoke(telephonyObject);
} catch (Exception e) {
e.printStackTrace();
Log.d("Receiver",
"FATAL ERROR: could not connect to telephony subsystem");
Log.d("Receiver", "Exception object: " + e);
}
}
public boolean killCall(Context context) {
try {
// Get the boring old TelephonyManager
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
// Get the getITelephony() method
Class classTelephony = Class.forName(telephonyManager.getClass().getName());
Method methodGetITelephony = classTelephony.getDeclaredMethod("getITelephony");
// Ignore that the method is supposed to be private
methodGetITelephony.setAccessible(true);
// Invoke getITelephony() to get the ITelephony interface
Object telephonyInterface = methodGetITelephony.invoke(telephonyManager);
// Get the endCall method from ITelephony
Class telephonyInterfaceClass =
Class.forName(telephonyInterface.getClass().getName());
Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod("endCall");
// Invoke endCall()
methodEndCall.invoke(telephonyInterface);
} catch (Exception ex) { // Many things can go wrong with reflection calls
Log.d("Receiver","PhoneStateReceiver **" + ex.toString());
return false;
}
return true;
}
正如我们所看到的,我正在使用我在互联网上找到的4种不同类型的方式来结束通话,但它不起作用。目前我在果冻豆上尝试这个代码。但它不起作用。请帮助我,如果我有任何人,我知道如何结束通话,请帮助你。
答案 0 :(得分:2)
杀死电话的代码
public boolean killCall(Context context) {
try {
// Get the boring old TelephonyManager
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
// Get the getITelephony() method
Class classTelephony = Class.forName(telephonyManager.getClass().getName());
Method methodGetITelephony = classTelephony.getDeclaredMethod("getITelephony");
// Ignore that the method is supposed to be private
methodGetITelephony.setAccessible(true);
// Invoke getITelephony() to get the ITelephony interface
Object telephonyInterface = methodGetITelephony.invoke(telephonyManager);
// Get the endCall method from ITelephony
Class telephonyInterfaceClass =
Class.forName(telephonyInterface.getClass().getName());
Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod("endCall");
// Invoke endCall()
methodEndCall.invoke(telephonyInterface);
} catch (Exception ex) { // Many things can go wrong with reflection calls
LogUtil.warn(TAG, "PhoneStateReceiver **" + ex.toString());
return false;
}
return true;
}
不同州的代码
public abstract class PhoneCallReceiver extends BroadcastReceiver {
private static final String TAG = "PhoneCallReceiver";
//The receiver will be recreated whenever android feels like it. We need a static variable to remember data between instantiations
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static boolean isIncoming;
private static String savedNumber; //because the passed incoming is only valid in ringing
@Override
public void onReceive(Context context, Intent intent) {
//We listen to two intents. The new outgoing call only tells us of an outgoing call. We use it to get the number.
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
} else {
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
state = TelephonyManager.CALL_STATE_IDLE;
} else if (stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
state = TelephonyManager.CALL_STATE_OFFHOOK;
} else if (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
state = TelephonyManager.CALL_STATE_RINGING;
}
onCallStateChanged(context, state, number);
// Added this line to remove broadcast from caller application
// abortBroadcast();
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(new PhoneStateListener(context), PhoneStateListener.LISTEN_CALL_STATE);
}
}
//Derived classes should override these to respond to specific events of interest
protected void onIncomingCallStarted(Context ctx, String number, Date start) {
}
protected void onOutgoingCallStarted(Context ctx, String number, Date start) {
}
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {
}
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
}
protected void onMissedCall(Context ctx, String number, Date start) {
}
//Deals with actual events
//Incoming call- goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up
//Outgoing call- goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up
public void onCallStateChanged(Context context, int state, String number) {
if (lastState == state) {
//No change, debounce extras
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
callStartTime = new Date();
savedNumber = number;
onIncomingCallStarted(context, number, callStartTime);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//Transition of ringing->offhook are pickups of incoming calls. Nothing done on them
if (lastState != TelephonyManager.CALL_STATE_RINGING) {
isIncoming = false;
callStartTime = new Date();
onOutgoingCallStarted(context, savedNumber, callStartTime);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
//Went to idle- this is the end of a call. What type depends on previous state(s)
if (lastState == TelephonyManager.CALL_STATE_RINGING) {
//Ring but no pickup- a miss
onMissedCall(context, savedNumber, callStartTime);
} else if (isIncoming) {
onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
} else {
onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());
}
break;
}
lastState = state;
}
class PhoneStateListener extends PhoneStateListener {
//private static final String TAG = "PhoneStateChanged";
Context context; //Context to make Toast if required
public PhoneStateListener(Context context) {
super();
this.context = context;
}
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.DATA_CONNECTED:
LogUtil.debug(TAG, "Data connected send broadcast");
Intent dataConnectedIntent = new Intent(PhoneCallTimerService.DATA_CONNECTED);
context.sendBroadcast(dataConnectedIntent);
break;
case TelephonyManager.DATA_DISCONNECTED:
LogUtil.debug(TAG, "Data disconnected send broadcast");
Intent dataDisConnectedIntent = new Intent(PhoneCallOutgoingService.DATA_DISCONNECTED);
context.sendBroadcast(dataDisConnectedIntent);
break;
default:
break;
}
}
}
}
public class CallReceiver extends PhoneCallReceiver {
private static final String TAG = "CallReceiver";
@Override
protected void onIncomingCallStarted(Context ctx, String number, Date start) {
}
@Override
protected void onOutgoingCallStarted(final Context ctx, final String number, Date start) {
LogUtil.debug(TAG, "Outgoing call started from :: " + number);
final String name = Utils.getContactName(ctx, number);
Handler outgoingCallHandler = new Handler();
outgoingCallHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (!Utils.isMyServiceRunning(PhoneCallOutgoingService.class, ctx) && !Utils.isMyServiceRunning(PhoneCallTimerService.class, ctx)) {
Intent outGoingCallService = new Intent(ctx, PhoneCallOutgoingService.class);
if (name != null && name.length() > 0) {
outGoingCallService.putExtra(CallReceiver.CALLER_NUMBER, name);
} else {
outGoingCallService.putExtra(CallReceiver.CALLER_NUMBER, number);
}
ctx.startService(outGoingCallService);
} else {
LogUtil.error(TAG, "Outgoing call service already started");
}
}
}, 2000);
}
@Override
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {
LogUtil.debug(TAG, "Incoming call end from :: " + number);
Intent callTerminatedIntent = new Intent(ACTION_CALL_TERMINATED);
ctx.sendBroadcast(callTerminatedIntent);
}
@Override
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
LogUtil.debug(TAG, "Outgoing call ended from :: " + number);
Intent dataDisConnectedIntent = new Intent(PhoneCallOutgoingService.DATA_DISCONNECTED);
ctx.sendBroadcast(dataDisConnectedIntent);
}
@Override
protected void onMissedCall(Context ctx, String number, Date start) {
LogUtil.debug(TAG, "Missed call from :: " + number);
Intent missedCallIntent = new Intent(ACTION_CALL_MISSED);
ctx.sendBroadcast(missedCallIntent);
}
当然,有一些代码对您的应用程序并不重要,所以请评论或删除只删除该行。