安卓系统中的未接来电检测

4

我想开发一个未接来电检测器,通过广播接收器通知用户。我在以下链接中找到了代码:link

public abstract class PhoneCallReceiver extends BroadcastReceiver {
        static CallStartEndDetector listener;

    @Override
    public void onReceive(Context context, Intent intent) {
        savedContext = context;
        if(listener == null){
            listener = new CallStartEndDetector();
        }


            TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
        telephony.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
    }



    public class CallStartEndDetector extends PhoneStateListener {
        int lastState = TelephonyManager.CALL_STATE_IDLE;
        boolean isIncoming;

        public PhonecallStartEndDetector() {}


        //Incoming call-   IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when hung up
        //Outgoing call-  from IDLE to OFFHOOK when dialed out, to IDLE when hunged up

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            if(lastState == state){
                //No change
                return;
            }
            switch (state) {
                case TelephonyManager.CALL_STATE_RINGING:
                    isIncoming = true;
                     //incoming call started
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    //Transition of ringing->offhook are pickups of incoming calls.  Nothing down on them
                    if(lastState != TelephonyManager.CALL_STATE_RINGING){
                        isIncoming = false;
                       //outgoing call started
                    }
                    break;
                case TelephonyManager.CALL_STATE_IDLE:
                    //End of call(Idle).  The type depends on the previous state(s)
                    if(lastState == TelephonyManager.CALL_STATE_RINGING){
                       //toast here for missed call
                    }
                    else if(isIncoming){
                          //incoming call ended
                    }
                    else{
                       //outgoing call ended                                              
                    }
                    break;
            }
            lastState = state;
        }

    }

}

以上代码运行良好。但是,当我从同一个号码接收到未接来电时,它会重复检测未接来电。请问如何只得到一次提示信息?请帮忙解决。

这是最佳答案:https://stackoverflow.com/a/52232504/843001 它采用了不同的方法。 - Duna
2个回答

6
大家好,我已经找到了解决方案,现在通过未接来电可以正常工作。
这是我的类代码:MyCallListener继承自BroadcastReciever
private static boolean ring=false;
private static boolean callReceived=false;
private String callerPhoneNumber;
private Context saveContext;

@Override
public void onReceive(Context mContext, Intent intent)
{
     saveContext=mContext;
   // Get the current Phone State


    String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

    if(state==null){
      return;
    }

    Bundle bundle = intent.getExtras();
    number= bundle.getString("incoming_number");
    Calendar calendar=Calendar.getInstance();
    currentTimeStamp=calendar.getTimeInMillis();
    // If phone state "Rininging"
    if(state.equals(TelephonyManager.EXTRA_STATE_RINGING))
    {           
              ring =true;
             // Get the Caller's Phone Number

      }



     // If incoming call is received
    if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
     {
            callReceived=true;
      }


     // If phone is Idle
    if (state.equals(TelephonyManager.EXTRA_STATE_IDLE))
    {
              // If phone was ringing(ring=true) and not received(callReceived=false) , then it is a missed call
               if(ring==true&&callReceived==false)
               {
                        Toast.makeText(mContext, "missed call : "+number, Toast.LENGTH_LONG).show();
                       //workingWithFunctions();
                        ring=false;
               }
               callReceived=false;
  }}

请不要忘记在清单文件中定义接收器。
 <receiver android:name="com.abc.broadcastrecivers.MyBroadcastReciver" />

在应用程序标签中。

7
这样行不通。如果用户拒绝了一个来电,这段代码会将其检测为未接来电。此外,如果用户在通话时收到了未接来电,这段代码也无法检测到。 - Ritesh Mahato
这是最佳答案:https://stackoverflow.com/a/52232504/843001 它采用了不同的方法。 - Duna

4
     public class callServiceReceiver extends BroadcastReceiver
        {
            TelephonyManager telephonyManager;
            @Override
            public void onReceive(Context context, Intent intent)
            {

                phoneStateListener phoneListener = new phoneStateListener(context);
                telephonyManager = (TelephonyManager) context
                        .getSystemService(Context.TELEPHONY_SERVICE);
                telephonyManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);

            }`enter code here`

            public void onDestroy() {
                telephonyManager.listen(null, PhoneStateListener.LISTEN_NONE);
            }
        }





    public class phoneStateListener extends PhoneStateListener
        {

            private Context mContext;
            private static boolean ringing =false;
            private static boolean call_received =false;



            //Constructor
            public phoneStateListener(Context context)
            {
                    mContext = context;

            }


            @Override
            public void onCallStateChanged(int state, String incomingNumber)
            {
                super.onCallStateChanged(state, incomingNumber);
                try
                {


                    switch (state)
                    {
                        case TelephonyManager.CALL_STATE_RINGING:
                            ringing = true;
                            // Get the Caller's Phone Number
                            break;
                        case TelephonyManager.CALL_STATE_OFFHOOK:
                            call_received =true;
                            break;

                        case TelephonyManager.CALL_STATE_IDLE:
                            // If phone was ringing(ringing=true) and not received(call_received=false) , then it is a missed call
                            if(ringing ==true&& call_received ==false)
                            {
                                Toast.makeText(mContext, "missed call : "+incomingNumber, Toast.LENGTH_LONG).show();

                                ringing =false;
                            }
                            call_received =false;
                            break;
                    }
                }catch (Exception e)
                {
                    e.printStackTrace(System.err);
                }
            }
        }

    <receiver android:name=".callServiceReceiver">
        <intent-filter>
            <action android:name="android.intent.action.PHONE_STATE" />
        </intent-filter>
   </receiver>

当您有第二个等待呼叫并且没有挂断第二个呼叫,仍在与第一个呼叫通话时(多个SIM卡,等待呼叫已激活,会议呼叫),此功能无法正常工作。 - Duna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接