以编程方式逐个拨打多个号码的Android

时间:2017-05-20 11:17:27

标签: java android ussd

我正在尝试为应用开发一个功能,其中包含一个"代码列表"你输入并逐个拨打。我已经查看了TelephonyManager并跟随tutorial开发了一个带有响应侦听器的广播接收器,但它并不总能正常工作。 一个想法是存储SharedPref中所需的所有数字。如果 Activity (仅针对dialer的意图创建)进入onStop()(意思是上面,拨号器屏幕打开)然后进入onResume()(调用结束并恢复活动),I将删除最后从SharedPref拨打的号码,然后,如果仍然存在,再次打开拨号器。广播确保TelephonyManager的状态流不是一次" OFFHOOK => IDLE",它会将用户返回到 Activity 。简短的故事,它并不总是如此表现。

我该如何解决这个问题?

修改

我的解决方案是

  1. 创建一个doPhoneCall()函数,用于处理意图创建和部署本身。

    @Override
    protected void doPhoneCall(){
        super.onResume();
        wentIntoCall = false;
        /** More code here for dialing */ 
    }
    
  2. 将此函数放入onResume()。即使onResume被多次调用,goIntoCall布尔值也会确保函数不会被多次调用。

    @Override
    protected void onResume() {
        super.onResume();
        if(wentIntoCall) 
        doPhoneCall();
    }
    
  3. 请记住,在通话后,手机应该返回到之前的状态,因此它将返回我们正在进行的Activity调用,我们将向活动添加一个CallListener,并在IDLE的情况,基于上面链接的教程,我们使goIntoCall成为现实。 (该活动将进入onResume(),并且在看到布尔值为true时,它将初始化下一个调用。)

    case TelephonyManager.CALL_STATE_IDLE:
    
                Log.e(TAG, "CALL_STATE_IDLE==>"+incoming_number);
    
                if((prev_state == TelephonyManager.CALL_STATE_OFFHOOK)){
                    prev_state=state;
                    wentIntoCall = true;
                    //Answered Call which is ended
    
                }
                if((prev_state == TelephonyManager.CALL_STATE_RINGING)){
                    prev_state=state;
                    wentIntoCall = true;
                    //Rejected or Missed call
                }
    
  4. 我的最后一个问题:这是处理此功能的正确方法,还是我应该尝试另外实现它?

    编辑2

    看起来像我的#34;代码",是USSD代码,不像普通电话那样。所以对于普通电话,上面的代码似乎有效,但对于拨号代码,不是那么多。我已降级"降级"我对一个简单的for循环的解决方案。现在似乎工作正常。

2 个答案:

答案 0 :(得分:1)

我不知道对于Android O,但是对于android 6.0>你无法直接找到答案。调用不存在的数字,并查看PhoneStateListener在一个案例中将触发什么并跟踪成功的调用。

制作公共静态数组,添加所有数字intro数组。  我提供服务。在清单中插入权限也可以自己动作(例如NEXT_CALL)。

比startServices更容易制作意图:

SharedPreferences settings;
SharedPreferences.Editor SAVES;

Intent serviceIntent = new Intent(MainActivity.this, ServiceForCalls.class);
                    serviceIntent.setAction("xxx.xxx.NEXT_CALL");
                    startService(serviceIntent);
                    isCalling = true;

                    SAVES.putBoolean(   "isCalling" ,  isCalling  );
                    SAVES.commit();
                    SAVES.apply();

您必须在下次通话时使用大约10秒的超时间隔。

Heres little help func - end call和phoneState handler

  void END_CALL () throws InvocationTargetException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException {

    tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
      Class c = null;
      try {
          c = Class.forName(tm.getClass().getName());
      } catch (ClassNotFoundException e) {
          e.printStackTrace();
      }
      Method m = null;
      try {
          m = c.getDeclaredMethod("getITelephony");
      } catch (NoSuchMethodException e) {
          e.printStackTrace();
      }
      m.setAccessible(true);
    Object telephonyService = m.invoke(tm); // Get the internal ITelephony object
    c = Class.forName(telephonyService.getClass().getName()); // Get its class
    m = c.getDeclaredMethod("endCall"); // Get the "endCall()" method
    m.setAccessible(true); // Make it accessible
    m.invoke(telephonyService); // invoke endCall()

      if ( SIGNAL_STOP == false ) {
          timerHandlerServicesStartNewNumber.postDelayed(timerRunnableServicesStartNewNumber, 1000);
      }

}


  private class PhoneStateChangeListener extends PhoneStateListener {

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            switch(state){
                case TelephonyManager.CALL_STATE_RINGING:
                    Log.println( Log.INFO , "RINGING" , "SERVICES%%%%%%%%%%%%%%%%RINGING%%%%%%%%%%%%%%%%%%");
                    wasRinging = true;
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    Log.println( Log.INFO , "OFFHOOK BROADCAST" , "SERVICES%%%%%%%%%%%%%%%%%%%%%%%%");

                    if (!wasRinging) {
                        // Start your new activity
                        Log.println( Log.INFO , "OFFHOOK BROADCAST" , "SERVICES%%%%%%%%%%%%%%%%%%%%%%%");

                      if (SIGNAL_STOP == false) {
                          timerHandlerServices.postDelayed(timerRunnableServices, 10000);

                      }


                    } else {
                        // Cancel your old activity
                        Log.println( Log.INFO , "OFFHOOK BROADCAST" , "SERVICES%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
                    }

                    // this should be the last piece of code before the break
                    wasRinging = true;
                    break;
                case TelephonyManager.CALL_STATE_IDLE:
                    Log.println( Log.INFO , "IDLE BROADCAST" , "SERVICES%%%%%%%%%%%%%%%%%IDLE%%%%%%%%%%%%%%%%%%%");

                    // this should be the last piece of code before the break
                    wasRinging = false;
                    break;
            }
        }
    }

感谢:“意思就是上面,拨号器屏幕上有”很好的捕捉。

答案 1 :(得分:0)

作为旁注,在Android O开发者预览版中,有一个新的API允许您send a USSD request并注册回调以接收其结果。对于较新版本的Android,这可能会更好地满足您的需求。