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