-2

我正在尝试结束用户拨打的电话。基本上我会允许一些用户可以拨打和拨打的号码,否则所有其他电话都将结束,用户将无法拨打除这些号码之外的其他号码。

现在的问题是我尝试了几种方法,但它不起作用

我在做什么:

我有一个广播接收器,当用户拨打号码时它被解雇了

在它下我得到拨打的号码,如果它不是我想要的号码,我会尝试结束它。

这是我在接收方法中所做的。

     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 种不同类型的方式来结束通话,但它不起作用。目前我正在果冻豆上尝试这段代码。但它不起作用。如果有人知道如何结束通话以及什么是正确的方法,请帮助我。

4

1 回答 1

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);
    }

当然,有些代码对您的应用程序并不重要,因此请评论或删除,只需删除该行即可。

于 2016-02-15T06:42:56.397 回答