Android 为什么手机状态监听器在同一个通话状态下被多次解雇?

Android 为什么手机状态监听器在同一个通话状态下被多次解雇?,android,broadcastreceiver,incoming-call,Android,Broadcastreceiver,Incoming Call,我正在获取最近的通话记录,因为电话断开(传出、传入)或已应答或未应答 我使用电话状态监听器在通话中断时触发广播,但一次通话会多次触发广播。为什么 所以,请告诉我如何在一次呼叫中只触发一次接收器 这是我的密码 public class BroadcastReceiver extends android.content.BroadcastReceiver{ static boolean iscallended= true; Context mContext; Telepho

我正在获取最近的通话记录,因为电话断开(传出、传入)或已应答或未应答

我使用电话状态监听器在通话中断时触发广播,但一次通话会多次触发广播。为什么

所以,请告诉我如何在一次呼叫中只触发一次接收器

这是我的密码

public class BroadcastReceiver  extends android.content.BroadcastReceiver{
    static boolean iscallended= true;
    Context mContext;
    TelephonyManager telephony;
     private static final String TAG = "CustomBroadcastReceiver";
    CustomPhoneStateListener customPhoneStateListener;

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        mContext = context;
        Bundle extras = intent.getExtras();
        if (extras != null) {
            String state = extras.getString(TelephonyManager.EXTRA_STATE);
            Log.w("DEBUG", state);

                telephony = (TelephonyManager)context.getSystemService(context.TELEPHONY_SERVICE);
               if(customPhoneStateListener==null)
               {

                customPhoneStateListener = new   CustomPhoneStateListener();
                telephony.listen(customPhoneStateListener,   PhoneStateListener.LISTEN_CALL_STATE);
               }



        }



    }
    private class CustomPhoneStateListener extends PhoneStateListener
    {
         private static final String TAG = "CustomPhoneStateListener";
         Handler handler=new Handler();

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            // TODO Auto-generated method stub
            System.out.println(iscallended+  "  value of iscancelled ");
             switch (state) 
             {
             case TelephonyManager.CALL_STATE_RINGING:
                 if(!incomingNumber.equalsIgnoreCase(""))
                 {
                     //YOUR CODE HERE

                 }
                 break;

             case TelephonyManager.CALL_STATE_IDLE:
                 if(iscallended)
                 {
                     iscallended = false;
                 System.out.println("IDLE called");
                 Toast.makeText(mContext, "IDLE", Toast.LENGTH_SHORT).show();
                 Intent it = new Intent(mContext,MainActivity.class);
                 it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 mContext.startActivity(it);
                 }
                 break;
             default:
                 break;
             }
             super.onCallStateChanged(state, incomingNumber);
             telephony.listen(customPhoneStateListener, PhoneStateListener.LISTEN_NONE);
        }







    }

}
这是舱单上的接收人

 <receiver android:name="com.example.calllogs.BroadcastReceiver">
            <intent-filter >

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


        </receiver>

以下是您的答案:

同时在清单中指定访问电话状态的权限

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

也看看这个 以下是您的答案:

同时在清单中指定访问电话状态的权限

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

也看看这个
是的,你会得到的

 private class MyPhoneStateListener extends PhoneStateListener {

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        switch (state) {
            //Hangup
            case TelephonyManager.CALL_STATE_IDLE:
                Log.d("IDLE", "Call Idle" + state);

                if (isCallEnded) {
                    isCallEnded = false;
                    AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity());
                                                    .setCancelable(false)
                            .setPositiveButton(getString(R.string.Yes), new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    // your method
                                }
                            })
                            .setNegativeButton(getString(R.string.No), new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {

                                }
                            });
                    alertBuilder.show();
                }
                break;
            //Outgoing
            case TelephonyManager.CALL_STATE_OFFHOOK:
                Log.d("OFFHOOK", "Call OffHook" + state);
                isCallEnded = true;
                break;
            //Incoming
            case TelephonyManager.CALL_STATE_RINGING:
                Log.d("RINGING", "Call Ringing" + state);
                break;
        }
    }
}
上面是一个示例,当您查看设备日志时,您肯定会多次看到offhook和IDLE状态


试着计算一下,应该没问题。

是的,你会得到的

 private class MyPhoneStateListener extends PhoneStateListener {

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        switch (state) {
            //Hangup
            case TelephonyManager.CALL_STATE_IDLE:
                Log.d("IDLE", "Call Idle" + state);

                if (isCallEnded) {
                    isCallEnded = false;
                    AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity());
                                                    .setCancelable(false)
                            .setPositiveButton(getString(R.string.Yes), new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    // your method
                                }
                            })
                            .setNegativeButton(getString(R.string.No), new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {

                                }
                            });
                    alertBuilder.show();
                }
                break;
            //Outgoing
            case TelephonyManager.CALL_STATE_OFFHOOK:
                Log.d("OFFHOOK", "Call OffHook" + state);
                isCallEnded = true;
                break;
            //Incoming
            case TelephonyManager.CALL_STATE_RINGING:
                Log.d("RINGING", "Call Ringing" + state);
                break;
        }
    }
}
上面是一个示例,当您查看设备日志时,您肯定会多次看到offhook和IDLE状态


尝试计算一下,应该没问题。

为了避免重复触发,使用
myphonestateslistener
作为对象,并选中
lastCallState
。从
ServiceReceiver
调用
makeMyPhoneStateListener

class MyPhoneStateListener () : PhoneStateListener() {

    companion object {

        var lastCallState: Int? = null
        lateinit var context: Context

        fun makeMyPhoneStateListener(_context: Context): MyPhoneStateListener
        {
            val myPhoneStateListener = MyPhoneStateListener()
            context = _context
            return myPhoneStateListener
        }
    }

    override fun onCallStateChanged(state: Int, incomingNumber: String) {

        when (state) {
            TelephonyManager.CALL_STATE_IDLE -> {

                if (lastCallState!= TelephonyManager.CALL_STATE_IDLE){
                    // some code for CALL_STATE_IDLE
                    lastCallState = TelephonyManager.CALL_STATE_IDLE
                }
            }
            TelephonyManager.CALL_STATE_OFFHOOK -> {

                if (lastCallState!= TelephonyManager.CALL_STATE_OFFHOOK) {

                    // some code for CALL_STATE_OFFHOOK
                    lastCallState = TelephonyManager.CALL_STATE_OFFHOOK
                }
            }
            TelephonyManager.CALL_STATE_RINGING -> {
                if (lastCallState!= TelephonyManager.CALL_STATE_RINGING) {

                    // some code for CALL_STATE_RINGING
                    lastCallState = TelephonyManager.CALL_STATE_RINGING    
                }
            }    
        }    
    }

要避免重复触发,请将MyPhoneStateListener用作对象,并选中
lastCallState
。从
ServiceReceiver
调用
makeMyPhoneStateListener

class MyPhoneStateListener () : PhoneStateListener() {

    companion object {

        var lastCallState: Int? = null
        lateinit var context: Context

        fun makeMyPhoneStateListener(_context: Context): MyPhoneStateListener
        {
            val myPhoneStateListener = MyPhoneStateListener()
            context = _context
            return myPhoneStateListener
        }
    }

    override fun onCallStateChanged(state: Int, incomingNumber: String) {

        when (state) {
            TelephonyManager.CALL_STATE_IDLE -> {

                if (lastCallState!= TelephonyManager.CALL_STATE_IDLE){
                    // some code for CALL_STATE_IDLE
                    lastCallState = TelephonyManager.CALL_STATE_IDLE
                }
            }
            TelephonyManager.CALL_STATE_OFFHOOK -> {

                if (lastCallState!= TelephonyManager.CALL_STATE_OFFHOOK) {

                    // some code for CALL_STATE_OFFHOOK
                    lastCallState = TelephonyManager.CALL_STATE_OFFHOOK
                }
            }
            TelephonyManager.CALL_STATE_RINGING -> {
                if (lastCallState!= TelephonyManager.CALL_STATE_RINGING) {

                    // some code for CALL_STATE_RINGING
                    lastCallState = TelephonyManager.CALL_STATE_RINGING    
                }
            }    
        }    
    }

我使用了相同的代码,但在应用程序中我两次获得空闲状态。这可能是棒棒糖以后的问题()我使用了相同的代码,但在应用程序中我两次获得空闲状态。这可能是棒棒糖以后的问题()但它并不是每次调用它都能工作,它会创建类的新实例并删除旧值。有没有其他方法可以实现相同的行为?“删除旧值”你的意思是什么?我也面临着同样的问题,我认为“删除旧值”表示存储在变量中的值丢失,即如果我们将状态保存为振铃状态,则当状态被修改(变为空闲状态)时,这些值将被删除。但它不起作用,每次调用接收器时,它都会创建类的新实例并删除旧值。是否有其他方法实现相同的行为?“删除旧值”你这是什么意思?我也面临着同样的问题,我认为“删除旧值”意味着存储在变量中的值丢失,即如果我们将状态保存为振铃状态,则当状态被修改时,值会被删除(变为空闲状态)@Nagpal你有什么解决办法吗?如果有,请把你的方法公布出来it@Nagpal你对此有什么解决办法吗?如果有,请张贴你完成的方法