Android 使用具有PhoneStateListener功能的BroadcastReceiver

Android 使用具有PhoneStateListener功能的BroadcastReceiver,android,broadcastreceiver,phone-state-listener,Android,Broadcastreceiver,Phone State Listener,我正在尝试制作一个MissCall应用程序,当收到一个miss call时,它会自动发送一条消息。我已经完成了我的应用程序,它工作正常以下是完整的场景: 问题: 应用程序运行良好,但当我重新启动设备时,应用程序无法运行。它只有在我启动应用程序至少一次后才起作用,直到它关闭为止,它一直工作正常。 这是我的密码: package com.example.misscallapp; import android.content.Context; import android.content.Inte

我正在尝试制作一个MissCall应用程序,当收到一个miss call时,它会自动发送一条消息。我已经完成了我的应用程序,它工作正常
以下是完整的场景:
问题:
应用程序运行良好,但当我重新启动设备时,应用程序无法运行。它只有在我启动应用程序至少一次后才起作用,直到它关闭为止,它一直工作正常。
这是我的密码:

package com.example.misscallapp;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;

public class Pref_Main extends PreferenceActivity {
    int checkIt = 0;
    TelephonyManager tm;
    CallStateListener callStateListener = new CallStateListener();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.prefs);
        tm = (TelephonyManager) getBaseContext().getSystemService(
                Context.TELEPHONY_SERVICE);
        tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    private class CallStateListener extends PhoneStateListener {

        @Override
        public void onCallStateChanged(int state, String incomingNumber) { 
           // Is called whenever there is a change in call state
            switch (state) {
            case TelephonyManager.CALL_STATE_RINGING:
                // called when someone is ringing to this phone

                Toast.makeText(getBaseContext(), "Incoming: " + incomingNumber,
                        Toast.LENGTH_LONG).show();
                checkIt = 1;
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                checkIt = 0;
                break;
            case TelephonyManager.CALL_STATE_IDLE:
                if (checkIt == 1) {
                    Intent i = new Intent(getBaseContext(),MyService.class);
                    i.putExtra("phno", incomingNumber);
                    startService(i); // service that sends the SMS
                }
                break;
            }
        }

    }



}
解决方案:
我发现解决这个问题的方法是使用广播接收器。因此,我注册了一个BroadcastReceiver,但它没有为我提供PhoneStateListener
例如,我尝试使用以下代码,但它不起作用,因为只有当它接收到某个内容时才会调用
,而
PhoneStateListener
则在调用状态发生变化时调用onCallStateChanged方法:

package com.example.misscallapp;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.Toast;

public class CallReceiverBroadcast extends BroadcastReceiver {
    int checkIt = 0;

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle extras = intent.getExtras();
        if (extras != null) {
            String state = extras.getString(TelephonyManager.EXTRA_STATE);
            String incomingNumber = extras.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);

            if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                Toast.makeText(context , "Incoming: " + incomingNumber,
                        Toast.LENGTH_LONG).show();
                checkIt = 1;
            }

            if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
                // Call received
                checkIt = 0;
            }

            if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                if (checkIt == 1) {
                    Toast.makeText(context , "This is not shown ",
                            Toast.LENGTH_LONG).show();
                    Intent i = new Intent(context,MyService.class);
                    i.putExtra("phno", incomingNumber);
                    context.startService(i);
                }
            }

        }

    }
}
我还尝试了一种变通方法,但结果显示出负面影响,如:

package com.example.misscallapp;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;

public class CallReceiverBroadcast extends BroadcastReceiver {
    int checkIt = 0;
    Context contextt;
    TelephonyManager tm;
    CallStateListener callStateListener = new CallStateListener();
    @Override
    public void onReceive(Context context, Intent intent) {
        contextt = context;
        tm = (TelephonyManager) context.getSystemService(
                Context.TELEPHONY_SERVICE);
        tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);

    }

    private class CallStateListener extends PhoneStateListener {

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            switch (state) {
            case TelephonyManager.CALL_STATE_RINGING:
                // called when someone is ringing to this phone

                Toast.makeText(contextt, "Incoming: " + incomingNumber,
                        Toast.LENGTH_LONG).show();
                checkIt = 1;
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                checkIt = 0;
                break;
            case TelephonyManager.CALL_STATE_IDLE:
                if (checkIt == 1) {
                 //startting the service
                    break;
                }
            }

        }

    }
}
上面的代码满足所有的要求,但它发送算术级数,就像它发送的是第一个未命中调用1,如果是第十个,则发送10条消息!
我真的需要你的帮助, 先谢谢你。


编辑1:
问题是每次调用
onReceive()
方法时,都会创建一个新的
TelphoneManager
实例
,并注册为Phoone状态的侦听器。
解决方案:

我制作了
CallReceiverBroadcast
的每个变量,静态!它解决了这个问题在某种程度上,但每次调用服务两次,这意味着有2个类实例注册为侦听器,但我不知道为什么。虽然我可以在某些情况下解决这个问题,但它会造成不必要的开销,任何拥有更好解决方案的人都将受到高度赞赏

这是因为一旦您接到未接来电,您就处于
电话管理器。呼叫状态空闲
阶段,消息将发送到相应的消息,但您的服务处于运行模式,这就是它将发送10条或多条短信的原因。

在第一个版本中,侦听器在引导时不会自动重新启动(也可能被系统终止),这就是它在引导时无法工作的原因。 您还忘记注销侦听器

在第二个版本中,只要清单设置正确,只要电话状态发生更改,就应该调用
onReceive()
,如

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

但是请注意,无法保证在
onReceive()
返回后,承载接收器的进程不会被破坏。如果可以修复,则最好使用第二个版本,该版本在执行onReceive()返回之前执行所有处理。

尝试创建bootbroadcast接收器,并在其on receive中启动您的服务以检测呼叫。这可确保您的服务在每次设备重新启动后自动激活。

解决您的问题的方法是,在消息成功发送给最终用户时,请停止您的服务。实际上,我从未在那里启动过服务,我只是显示了一个祝酒词,以查看其次数正在呼叫…并查看问题中的更新
@Override
public void onDestroy() {
        tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE);
}