- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试制作一个 MissCall 应用程序,它会在接到未接来电时自动发送一条消息。我已经完成了我的应用程序并且运行良好!
这是完整的场景:
问题:
该应用程序运行良好但当我重新启动设备时该应用程序无法运行!。它只在我至少启动我的应用程序一次后才工作,直到它关闭为止。
这是我的代码:
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 。所以我注册了一个 BroadcastReceiver 但它没有给我 PhoneStateListener
的功能例如,我尝试使用以下代码,但它不起作用,因为 BroadcastReceivers
仅在接收到与 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 State 的监听器。
解决方案:
我将 CallReceiverBroadcast
类的每个变量设为 static !它在一定程度上解决了问题!!,但每次仍然调用两次服务,这意味着有些类的 2 个实例如何注册为监听器,但我不知道为什么。虽然我可以在某些情况下解决它,但它会导致不必要的开销,任何有更好解决方案的人都会受到高度赞赏。
最佳答案
在第一个版本中,监听器不会在启动时自动重启(也可能被系统杀死),这就是它在启动时不起作用的原因。你也忘了注销监听器。
在您的第二个版本中,只要您的 list 设置正确,只要手机状态发生变化,就应该调用 onReceive()
,例如
<receiver android:name=".CallReceiverBroadcast" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
但是,Android 可能会在 onReceive()
调用之间回收广播接收器,这意味着您的 checkIt
变量可能不会在 onReceive() 调用之间保留
。您可能需要使用静态变量才能使其正常工作。
在您的第三个版本中,每当调用 onReceive()
时,您都会创建并注册多个版本的调用状态监听器。 (注意 tm 应该指向同一个电话管理器实例),这可能就是它们被多次调用的原因。
根据您如何将变量转换为静态变量,问题可能无法解决,因为您可能仍在创建/注册 CallStateListener
的新实例,尽管您将其存储到静态变量中。
要解决这些问题,您应该通过覆盖广播接收器的 onDestroy()
来取消注册调用状态监听器
@Override
public void onDestroy() {
tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE);
}
但是请注意,不能保证在 onReceive()
返回后,托管接收方的进程不会被销毁。在 onReceive()
返回之前执行所有处理的第二个版本是更可取的,如果你能修复它的话。
关于android - 使用具有 PhoneStateListener 功能的 BroadcastReceiver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22504869/
我的应用程序处理传入/传出调用并显示一些 UI。所以我使用 PhoneStateListener 来监听 CALL_STATE_IDLE、CALL_STATE_RINGING、CALL_STATE_O
当设备进入打盹模式或省电模式时,我的 PhoneStateListener 停止工作。我还需要在设备重启时注册 PhoneStateListener。我不想使用 BroadcastReceiver,因
我使用 PhoneStateListener 来查明电话何时处于 Activity 通话中以及通话何时结束并记录它是在来电还是去电中。当我安装监听器时,它在第一次调用时按预期工作。之后,尽管它仍然有效
我实现了一个 PhoneStateListener 如何在您被调用时停止音频并在您完成后再次启动它。当我通过 finish() 退出我的应用程序时,PhoneStateListener 似乎仍然处于
我正在尝试构建一个应用程序,在我接听和拒绝来电时进行记录。因此,我正在使用 PhoneStateListener。 当我在 onCreate() 方法中启动监听器时,它会在一段时间后停止 Activi
我正在尝试设置 PhoneStateListener 但我得到一个 PhoneCallListener cannot be resolved to a type。 public class Butto
我正在尝试使用 Broadcast Receiver 测试 PhoneStateListener。但我无法这样做。接收类中的日志语句也没有在 Logcat 中打印。 这是 list 文件
这是我的全部代码...... 广播示例.java package com.example.broadcast; > import android.app.Activity; import > and
我想在 android 应用程序中检测拨出电话。实际上我可以检测到拨出电话,但它也适用于来电,我不希望这样。我需要它只为传出工作。这是我的代码.... boolean ringing = false;
我目前正在开发一个 android 应用程序来监视来自电话的传入和传出调用并将调用信息注册到文件中,从我读过的内容来看 PhoneStateListener 似乎做了什么我需要。 问题是我需要应用程序
我正在使用 PhoneStateListener,因此当用户接到电话或开始通话时,扬声器将立即打开。 PhoneStateListener phoneStateListener = new P
我写了一个应用程序,它通过 PhoneStateListener 监控我的信号强度。我希望此应用在启动时启动并永远运行。 我的管理方法如下,但我想知道是否有人可以推荐更好的方法。 我已经注册了一个在
我在 android 上遇到问题。我想知道设备是否已连接到 GSM 网络,以便它可以发送短信。 两种方式我都试过了,结果都是一样的。在 Moto G 4G 上,我能够确定它是否可以访问。在 Redmi
我创建了一个 BroadcastReceiver 来监听他的电话状态并采取相应的行动。 这里的问题是它似乎没有从我的数据库中获取正确的值,并且从一开始处于空闲状态的 toast 显示两次,第二次调用后
我的应用程序运行多次后出现内存问题。 java.lang.OutOfMemoryError: 位图大小超出 VM 预算 我想我不知何故泄漏了内存,所以我做了一个 DUMP HPROF 文件并使用 MA
我需要从几个类中调用方法,但我不知道如何获得正确的上下文 持有类: public class SharedData { ...... ...... public static void sto
在某些情况下,我不想听手机的状态。如何销毁 PhoneStateListener 类的对象? 我这样创建对象 try { phoneCallListener = new WnetPlaye
在 Android(目标 25)中,我有一个后台服务,在 onCreate 函数中我已经初始化了一个电话状态监听器。它在 Nougat 之前的 Android 版本上运行良好,但在 Nougat 中它
我正在编写包含两个元素的简单应用程序 - 服务和 Activity 。 Activity 仅用于启动和停止服务。服务使用 PhoneStateListener 获取有关当前 CellID、LAC 和
我刚刚接触 Android 开发,并决定我在这个新领域的第一个征服将是掌握手机对来电的 react 。 后来我用谷歌搜索了一下 http://www.compiletimeerror.com/2013
我是一名优秀的程序员,十分优秀!