Android BroadcastReceiver onReceive() 在 android 5.1.1 上调用两次,即使在一次注册之后

2024-02-17

我无法弄清楚下面的代码有什么问题。我还检查了两次注册接收者的情况。但事实也并非如此。或者可能是我遗漏了一些东西。 请帮忙。我真的很需要它。 :(

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

/**
 * 
 * @author Bharat
 *
 */
public class CallNotifierService extends Service 
{
    private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
    private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
    private CallBr br_call;

    @Override
    public IBinder onBind(Intent arg0) 
    {
        return null;
    }

    @Override
    public void onDestroy() 
    {
        Log.d("service", "destroy");
        this.unregisterReceiver(this.br_call);
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        final IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_OUT);
        filter.addAction(ACTION_IN);
        this.br_call = new CallBr();
        this.registerReceiver(this.br_call, filter);
        return START_NOT_STICKY;
    }

    public class CallBr extends BroadcastReceiver 
    {
        Bundle bundle;
        String state;
        String inCall, outCall;
        public boolean wasRinging = false;
        public boolean answered = false;
        public boolean outgoing = false;

        @Override
        public void onReceive(Context context, Intent intent) 
        {
            if (intent.getAction().equals(ACTION_IN)) 
            {
                if ((bundle = intent.getExtras()) != null) 
                {
                    state = bundle.getString(TelephonyManager.EXTRA_STATE);

                    if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) 
                    {
                        inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
                        wasRinging = true;
                        Toast.makeText(context, "Incoming Call : " + inCall, Toast.LENGTH_LONG).show();
                    } 
                    else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) 
                    {
                        if (wasRinging == true) 
                        {
                            answered = true;
                            Toast.makeText(context, "Answered", Toast.LENGTH_LONG).show();
                        }
                    } 
                    else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) 
                    {
                        wasRinging = false;
                        Toast.makeText(context, "Disconnected", Toast.LENGTH_LONG).show();
                    }
                }
            } 
            else if (intent.getAction().equals(ACTION_OUT)) 
            {
                if ((bundle = intent.getExtras()) != null) 
                {
                    outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                    Toast.makeText(context, "Outgoing Call : " + outCall, Toast.LENGTH_LONG).show();
                    outgoing = true;
                }
            }
        }
    }
}

以下是我从中调用它的活动

public class MyActivity extends Activity 
{

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.roaming);

    Intent intent = new Intent(this, CallNotifierService.class);
    startService(intent);
}
.
.
.
}

Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ind.cosmos.main"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

    <uses-sdk
        android:minSdkVersion="22"
        android:targetSdkVersion="22" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >

        <!-- android:theme="@style/AppTheme"> -->
        <activity
            android:name="ind.cosmos.main.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="ind.cosmos.callRecord.CallNotifierService" />
    </application>

正如 Bharat 所说,最好用代码来处理它。下面是一个这样做的技巧,发现here http://mmarvick.github.io/blog/blog/lollipop-multiple-broadcastreceiver-call-state/,感谢 Michael Marvick 也给出了详细的描述。

     public class PhoneStateBroadcastReceiver extends BroadcastReceiver {

        public static final String TAG = "PHONE STATE";
        private static String mLastState;

        @Override
        public void onReceive(Context context, Intent intent) {
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

            if (!state.equals(mLastState)) {
                mLastState = state;
                Log.e(TAG, state);
            }
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android BroadcastReceiver onReceive() 在 android 5.1.1 上调用两次,即使在一次注册之后 的相关文章

  • 计算Android设备的PPI

    如何计算 Android 设备的 PPI 最特别的是 Android 平板电脑 请注意 我想计算设备的 PPI 而不是 DPI 就像一二三一样简单 让我们来计算一下PPI to Nexus 5 例如 float LCD Diagonal 4
  • 如何获取之前的碎片?

    为了在我的应用程序中重用某些片段 我需要知道哪个片段是返回堆栈上的第二个片段 为了做到这一点 我正在使用getFragmentManager getFragments 显示以下错误 但有效 FragmentManager getFragme
  • Android 在打开应用程序时会广播吗?

    例如 如果我想知道Youtube何时打开 是否有与之相关的广播 我当然知道我可以轮询 logcat 消息来检查活动 但我可以通过广播来做到这一点吗 因为它会少得多的耗电 此链接似乎表明这是不可能的 如何跟踪 Android 中的应用程序使用
  • Android 上的 SVG 支持

    Android 支持 SVG 吗 有什么例子吗 最完整的答案是这样的 Android 2 x 默认浏览器本身不支持 SVG Android 3 默认浏览器支持 SVG 要将 SVG 支持添加到 2 x 版本的平台 您有两个基本选择 安装功能
  • Service 和 IntentService,运行从服务器轮询数据库值的服务哪个更好?

    我读过很多关于Service and IntentService 然而 当做出决定时 我没有足够的信心选择使用哪种类型来创建一个后台服务 该服务将在一定时间间隔内从数据库轮询数据 并在获得所需数据时停止它 因为数据代表请求的状态 例如 订购
  • 调试:在 Android 1.0 中找不到文件

    今天我更新到 Android Studio v 1 0 在尝试编译任何项目时出现以下错误 app build intermediates classes debug 找不到文件 问题是在更新之前我没有任何问题 这是我实际尝试编译的代码 构建
  • 如何在android线性布局上获得阴影? [复制]

    这个问题在这里已经有答案了 可能的重复 如何在android中为View设置阴影 https stackoverflow com questions 4406524 how to set shadow to a view in androi
  • 如何在手机缓存中保存用户名和密码

    我有一个用户登录应用程序 它需要用户的电子邮件和密码 我想将电子邮件和密码保存在手机缓存中 以便用户不必再次输入 有什么办法可以将数据保存在Android缓存中吗 我认为你需要使用SharedPreference用于在设备中使用应用程序时保
  • Android 服务是否有办法检测设备何时锁定?

    我有一个 Android 服务 我希望在设备锁定时执行操作 我想澄清一下 我对屏幕开 关状态不感兴趣 我知道如何使用带有 Intent ACTION USER PRESENT 和 KeyguardManager inKeyguardRest
  • 使用 gradlew assembleRelease 从 React Native 创建发布 apk 时出现错误

    我想发布 apk 但我收到错误 文件已存在 mkdir D mobile 它在 d 驱动器中生成名为 mobile 的文件 删除文件后 再次执行 gradlew assembleRelease 创建该文件并抛出错误 任务 app bundl
  • 画透明圆,外面填充

    我有一个地图视图 我想在其上画一个圆圈以聚焦于给定区域 但我希望圆圈倒转 也就是说 圆的内部不是被填充 而是透明的 其他所有部分都被填充 请参阅这张图片了解我的意思 http i imgur com zxIMZ png 上半部分显示了我可以
  • 菜单在片段的 onCreateOptionsMenu 处多次膨胀调用

    我使用 Fragments 当我切换到嵌套 Fragment 时 它实现了public void onCreateOptionsMenu Menu menu MenuInflater inflater 当我到达该嵌套片段时 我的菜单会多次膨
  • 在旋转时从错误的资源文件夹中提取可绘制对象

    在这里拉我的头发 因此 我正在使用一个具有多种类型的可绘制对象的应用程序 并且它们的结构如下 res Portrait resources drawable mdpi drawable hdpi drawable xhdpi Landsca
  • Android:滚动 Horizo​​ntalScrollView 时如何禁用 ScrollView 的垂直滚动?

    我正在开发一个带有带有 ScrollView 的 Activity 的 Android 应用程序 其中包含 Horizo ntalScrollView 等内容 当我触摸 Horizo ntalScrollView 时 我想禁用外部 Scro
  • HERE 地图:更改路线已行驶部分的颜色

    导航时可以改变路线的颜色吗 具体来说 我希望路线中已行驶的部分的颜色与即将行驶的部分的颜色不同 现在都是同一个颜色 将 MapRoute 对象的 TravelColor 变量设置为透明对我来说很有效 mapRoute color Resou
  • react-native run-android 失败并出现错误:任务 ':app:dexDebug' 执行失败

    我使用的是 Windows 8 1 和react native cli 1 0 0 and react native 0 31 0 添加后react native maps对于该项目 我运行了命令react native upgrade并给
  • 哪些 Flutter 插件或功能可以利用外部 iOS/Android 显示器来显示与主显示器不同的内容

    我正在构建一个跨平台应用程序 需要在外部显示器上显示不同的视图 通常通过连接到 LCD 投影仪的 HDMI 适配器电缆连接 Flutter 是否能够在内置的外部显示器上显示不同的屏幕 在现有的 Flutter 插件中还是使用现有的 Flut
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • Android 中循环事件的星期几和时间选择器

    我想创建一个控件 允许用户在我的 Android 活动中选择一周中的某一天 星期一 和一天中的某个时间 下午 1 00 找不到任何关于此的好帖子 好吧 我想我已经明白了 我只是不喜欢这个解决方案 因为我在一周中的某一天使用的微调器与时间选择
  • 如何在基本活动中使用 ViewBinding 的抽象?

    我正在创建一个基类 以便子级的所有绑定都将设置在基类中 我已经做到了这一点 abstract class BaseActivity2 b AppCompatActivity private var viewBinding B null pr

随机推荐