【问题标题】:Android how to detect if outgoing call is answeredAndroid如何检测拨出电话是否被接听
【发布时间】:2017-07-12 01:27:56
【问题描述】:

我正在开发一款仅用于内部测试的应用。我进行了很多搜索并尝试了不同帖子中建议的不同建议,但似乎没有一个对我有用。

我愿意接受任何建议,例如 Reflections、Accessibility Service、root 或任何其他 hack。请帮忙。

问候

【问题讨论】:

    标签: android reflection root


    【解决方案1】:

    试试这个

    在 manifest.xml 文件中设置所有必需的权限。

    在Service中调用这个类

    public class PhoneListener extends PhoneStateListener {
    
    private static PhoneListener instance = null;
    
    /**
     * Must be called once on app startup
     *
     * @param context - application context
     * @return
     */
    public static PhoneListener getInstance(Context context) {
        if (instance == null) {
            instance = new PhoneListener(context);
        }
        return instance;
    }
    
    public static boolean hasInstance() {
        return null != instance;
    }
    
    private final Context context;
    private CallLog phoneCall;
    
    private PhoneListener(Context context) {
        this.context = context;
    }
    
    AtomicBoolean isRecording = new AtomicBoolean();
    AtomicBoolean isWhitelisted = new AtomicBoolean();
    
    
    /**
     * Set the outgoing phone number
     * <p/>
     * Called by {@link MyCallReceiver}  since that is where the phone number is available in a outgoing call
     *
     * @param phoneNumber
     */
    public void setOutgoing(String phoneNumber) {
        if (null == phoneCall)
            phoneCall = new CallLog();
        phoneCall.setPhoneNumber(phoneNumber);
        phoneCall.setOutgoing();
        // called here so as not to miss recording part of the conversation in TelephonyManager.CALL_STATE_OFFHOOK
        isWhitelisted.set(Database.isWhitelisted(context, phoneCall.getPhoneNumber()));
    }
    
    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        super.onCallStateChanged(state, incomingNumber);
    
        switch (state) {
            case TelephonyManager.CALL_STATE_IDLE: // Idle... no call
                if (isRecording.get()) {
                    RecordCallService.stopRecording(context);
                    phoneCall = null;
                    isRecording.set(false);
                }
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK: // Call answered
                if (isWhitelisted.get()) {
                    isWhitelisted.set(false);
                    return;
                }
                if (!isRecording.get()) {
                    isRecording.set(true);
                    // start: Probably not ever usefull
                    if (null == phoneCall)
                        phoneCall = new CallLog();
                    if (!incomingNumber.isEmpty()) {
                        phoneCall.setPhoneNumber(incomingNumber);
                    }
                    // end: Probably not ever usefull
                    RecordCallService.sartRecording(context, phoneCall);
                }
                break;
            case TelephonyManager.CALL_STATE_RINGING: // Phone ringing
                // DO NOT try RECORDING here! Leads to VERY poor quality recordings
                // I think something is not fully settled with the Incoming phone call when we get CALL_STATE_RINGING
                // a "SystemClock.sleep(1000);" in the code will allow the incoming call to stabilize and produce a good recording...(as proof of above)
                if (null == phoneCall)
                    phoneCall = new CallLog();
                if (!incomingNumber.isEmpty()) {
                    phoneCall.setPhoneNumber(incomingNumber);
                    // called here so as not to miss recording part of the conversation in TelephonyManager.CALL_STATE_OFFHOOK
                    isWhitelisted.set(Database.isWhitelisted(context, phoneCall.getPhoneNumber()));
                }
                break;
        }
    
    }
    

    }

    并使用广播接收器

    public class MyCallReceiver extends BroadcastReceiver {
    
    public MyCallReceiver() {
    }
    
    static TelephonyManager manager;
    
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("JLCreativeCallRecorder", "MyCallReceiver.onReceive ");
    
        if (!AppPreferences.getInstance(context).isRecordingEnabled()) {
            removeListener();
            return;
        }
    
        if (Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
            if (!AppPreferences.getInstance(context).isRecordingOutgoingEnabled()) {
                removeListener();
                return;
            }
            PhoneListener.getInstance(context).setOutgoing(intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
        } else {
            if (!AppPreferences.getInstance(context).isRecordingIncomingEnabled()) {
                removeListener();
                return;
            }
        }
    
        // Start Listening to the call....
        if (null == manager) {
            manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        }
        if (null != manager)
            manager.listen(PhoneListener.getInstance(context), PhoneStateListener.LISTEN_CALL_STATE);
    }
    
    private void removeListener() {
        if (null != manager) {
            if (PhoneListener.hasInstance())
                manager.listen(PhoneListener.getInstance(null), PhoneStateListener.LISTEN_NONE);
        }
    }
    

    }

    我希望你能从这段代码中得到一些帮助。

    谢谢

    【讨论】:

    • 感谢您的帮助,但上面的代码无法告诉您何时确切接听了电话!
    • 这个问题可能是由于您的设备的双卡或缺少phoneListener。在三星设备上它工作成功。
    • 这实际上是做什么的?我正在努力理解它,但如果答案中已经有一个小小的解释会很酷。
    • AppPreferences.getInstance(context) 来自哪里?还有这些 phoneCall.setPhoneNumber(phoneNumber); phoneCall.setOutgoing();函数没有从 PhoneCall 对象中获取
    【解决方案2】:

    您可以使用辅助功能事件来检测通话时长,并从中可以检测拨出电话是否被接听..

    我已经在Here`详细回答过,你可以查一下。

    【讨论】:

      【解决方案3】:

      您需要在清单中获得此权限

      &lt;uses-permission android:name="android.permission.READ_PHONE_STATE"/&gt;

      TelephonyManager 有一个监听器来获取电话状态。执行此操作以了解电话是否在响铃或通话中。

      TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
              PhoneStateListener callStateListener = new PhoneStateListener() {
      
                  public void onCallStateChanged(int state, String incomingNumber) {
                      // TODO React to a incoming call.
      
                      try {
                          if (state == TelephonyManager.CALL_STATE_RINGING) {
                              Toast.makeText(getApplicationContext(), "Phone Is Ringing" + incomingNumber, Toast.LENGTH_LONG).show();
                              number = incomingNumber;
                              //g.setPhoneNo(incomingNumber);
                              AndroidNetCommunicationClientActivity.mMsgSendRequest("CommandMsgCallIncoming" + number);
                          } else if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
                              Toast.makeText(getApplicationContext(), "Phone is Currently in A call" + incomingNumber, Toast.LENGTH_LONG).show();
                              //number = mIntent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                              number = incomingNumber;
      
      
                          } else if (state == TelephonyManager.DATA_DISCONNECTED) {
                              number = "";
                              CallID = "";
                          }
                      } catch (Exception e) {
                          // TODO Auto-generated catch block
                          //conn.MessageBox(MainActivity.this, e.getMessage());
                          e.printStackTrace();
                      }
                      super.onCallStateChanged(state, incomingNumber);
      
                  }
              };
              telephonyManager.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
      

      【讨论】:

      • CALL_STATE_OFFHOOK 号码一拨就被叫了!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多