为什么BroadcastReceiver没有在后台运行?

2023-12-01

在一个应用程序(App1)中,我正在广播一条消息。下面的代码是正确的 -> 如果我尝试在同一项目中获取广播,则会检测到广播。

sendBroadcast(new Intent("com.example.MESSAGE_INTENT").putExtra("MESSAGE", ((EditText) findViewById(R.id.textField)).getText()));

我创建了 App2,它有一个BroadcastReceiver等待广播的Intent但方法onReceive从未被调用。

如何更改BroadcastReceiver应用程序使服务始终在后台运行?


App2清单和代码:

package com.example;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("WORKS" , "!!!!!!!!!!");
        Toast.makeText(context, "CAUGHTt\n" + intent.getExtras().getString("MESSAGE"), Toast.LENGTH_LONG).show();
    }
}

           <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.jjoe64" >

        <permission-group
            android:name="com.examples.my_permissions"
            android:label="my permissions groupd" />

        <permission
            android:name="com.examples.my_permissions.MY_PERMISSION"
            android:label="my permission"
            android:permissionGroup="com.examples.my_permissions" />

        <application>
            <receiver
                android:name="MyReceiver"
                android:exported="true"
                android:permission="com.examples.my_permissions.MY_PERMISSION" >
                <intent-filter>
                    <action android:name="com.example.MESSAGE_INTENT" />
                </intent-filter>
            </receiver>


            <service android:name="BackgroundService" />
        </application>

    </manifest>

广播商清单

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example"
    android:exported="true" >

    <uses-permission android:name="com.examples.my_permissions.MY_PERMISSION" />

    <permission-group
        android:name="com.examples.my_permissions"
        android:label="my permissions groupd" />

    <permission
        android:name="com.examples.my_permissions.MY_PERMISSION"
        android:label="my permission"
        android:permissionGroup="com.examples.my_permissions" />

    <application>
        <receiver
            android:name="com.example.MyReceiver"
            android:exported="true"
            android:permission="com.examples.my_permissions.MY_PERMISSION" >
            <intent-filter>
                <action android:name="com.example.MESSAGE_INTENT" />
                <action android:name="android.intent.action.AIRPLANE_MODE" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

主要编辑

我创建了另一个应用程序MainActivity我在那里创造了final BroadcastReceiver:

CODE:

package com.example.receiver2;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {
final BroadcastReceiver br = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("WORKS" , "!!!!!!!!!!");
        Toast.makeText(context, "CAUGHTt\n" + intent.getExtras().getString("MESSAGE"), Toast.LENGTH_LONG).show();
    }
};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            return rootView;
        }
    }

}

显现:

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

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

    <uses-permission android:name="com.examples.my_permissions.MY_PERMISSION" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <permission-group
        android:name="com.examples.my_permissions"
        android:label="my permissions groupd" />

    <permission
        android:name="com.examples.my_permissions.MY_PERMISSION"
        android:label="my permission"
        android:permissionGroup="com.examples.my_permissions" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <receiver
            android:name="com.example.MyReceiver"
            android:exported="true" >
            <intent-filter>
                <action android:name="com.example.MESSAGE_INTENT" />
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <activity
            android:name="com.example.receiver2.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>
    </application>

</manifest>

但我有一个例外:

04-18 10:16:46.332: E/AndroidRuntime(1244): FATAL EXCEPTION: main
04-18 10:16:46.332: E/AndroidRuntime(1244): Process: com.example.receiver2, PID: 1244
04-18 10:16:46.332: E/AndroidRuntime(1244): java.lang.RuntimeException: Unable to instantiate receiver com.example.MyReceiver: java.lang.ClassNotFoundException: Didn't find class "com.example.MyReceiver" on path: DexPathList[[zip file "/data/app/com.example.receiver2-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.example.receiver2-1, /system/lib]]
04-18 10:16:46.332: E/AndroidRuntime(1244):     at android.app.ActivityThread.handleReceiver(ActivityThread.java:2400)

v6 - github 上的示例代码

如果有帮助的话,我整理了一个非常快速的演示应用程序(针对 Eclipse),其中包含一个导出的、不安全的BroadcastReceiver您可以将其用作模板。我已将其存储在我的 github 帐户中:

  • github.com/mobiRic/mobiric_BroadcastReceiver

您可以使用它来遵循我的答案 v3 第 2 步中给出的建议,其中我建议您获得一个简单的导出BroadcastReceiver在职的。

我相信一旦你启动并运行了这个过程,剩下的过程就会非常简单。


v5 - 将清单接收者作为单独的类

你可以声明一个BroadcastReceiver有两种不同的方式:

  • 作为另一个类中的字段(如您的MainActivity)
  • 或作为一个单独的类

当在另一个类中声明时,需要使用以下方法ContextWrapper.registerReceiver() and ContextWrapper.unregisterReceiver()注册意向。您的代码需要执行此操作,因此您的应用程序必须正在运行才能接收广播。

如果您想通过广播“唤醒”您的应用程序,那就是当您在清单中声明接收器时(就像您所做的那样)。在这种情况下,你的BroadcastReceiver将是一个单独的类文件:

package mobiric.demo;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * Must be declared in the manifest.
 */
public class MobiricReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // do something
    }
}

看起来您正在混淆这两种技术。我认为你需要第二种技术:

  • 在清单中声明
  • 根据代码创建单独的类文件

v4 - 手动启动两个应用程序

我现在能想到的最后一件事是,我认为您需要在系统允许之前手动启动您的应用程序BroadcastReceiver上班。

所以一定要启动任何Activity在测试之前在您的应用程序中。

这是一篇关于此的博客文章:

  • Android 广播接收器 – 自 API 3.1 以来的流程变化

v3 - 授予您的应用程序自定义权限

哦等等 - 你还没有宣布<uses-permission android:name="com.examples.my_permissions.MY_PERMISSION" />在你的清单中。

  • Android 开发者网站的权限
  • Android中如何使用自定义权限?

但我通常希望 logcat 告诉您存在权限问题。

就其价值而言,我会将这个问题分解为几个步骤:

  1. 从两个应用程序中删除所有必需的自定义权限
  2. 调试您的广播接收器,使其在这种不安全的配置中工作
  3. 最后添加自定义权限

通过这种方式,您可以隔离潜在的问题,这样您一次只需处理一个棘手的问题。这将使您更容易专注于问题,而无需寻找其他可能性。

此外,通过在开发时删除自定义权限,您可以使用 ADB 来测试您的接收器,这可以节省大量时间。查找详细信息adb shell am broadcast ... here:

  • Android 开发者网站上的 ADB

v2 - 对您的应用程序进行签名以使用自定义权限

原始问题更新为exported="true".

使用自定义权限需要使用相同的签名密钥对两个应用程序进行签名。

However我过去遇到过未解决的“自定义权限”问题。基本上我的新自定义权限没有在设备上授予。卸载并重新安装应用程序没有任何区别 - 系统似乎将该自定义权限存储在我无法更新的地方。

这是该论坛上的相关帖子 - 不幸的是我始终无法解决该问题,并且不得不接受提供的解决方法:

  • 意图自定义权限不起作用

v1 - 导出广播接收器

您需要“导出”您的BroadcastReceiver通过把exported="true"在接收者的舱单声明中。

请参阅下面的更改:

    <receiver
        android:name="MyReceiver"
        android:permission="com.examples.my_permissions.MY_PERMISSION"
        android:exported="true" >

        <intent-filter>
            <action android:name="com.example.MESSAGE_INTENT" />
        </intent-filter>
    </receiver>

Note:这个答案的未来读者,请注意,原始帖子包含permission。这可以防止安全问题,并要求调用应用程序使用相同的签名进行签名。

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

为什么BroadcastReceiver没有在后台运行? 的相关文章

随机推荐

  • CHM 中的 SVG 图形(Html 帮助研讨会)

    我正在尝试在 CHM 文件中使用 SVG 图形 CHM 由 HTML Help Workshop 创建 不幸的是 svg 文件没有显示在我编译的 chm 中 在 Html 中一切正常 我已经将 SVG 添加到了 hhp 的文件部分 但还是什
  • 将 django-oscarapi API ROOT 扩展到自定义 API 类

    我有一个 django oscar 应用程序 我使用 django oscarapi 作为我的自定义 API oscarapi 中缺少一些东西 例如类别和促销 但我已经能够使用 django restframework 来创建类别 API
  • Javascript源代码分析(特别是重复检查)

    部分重复this 笔记 我已经通过我编写的工具广泛使用 JSLint 该工具会定期扫描当前项目目录以查找最近更新 创建的 js 文件 它极大地提高了我的工作效率 而且我怀疑是否有任何东西的价格能与 JSLint 一样好 它是免费的 也就是说
  • lxml/requests 可以选择下拉选项然后解析生成的ajax吗?

    我有一个正在尝试测试的网站 虽然我可以在下拉列表中获取选项列表 但我不确定如何选择它 没有提交按钮 所以如果我选择它 它将加载下面的 ajax 表 我只是不确定 lxml requests 是否可以做到这一点或如何做到这一点 如果有人可以确
  • android服务的优先级如何设置?

    有没有办法设置android服务的优先级 我想在销毁应用程序的主要活动后在后台运行该服务 所以我从我的服务中返回 START REDELIVERY INTENT 但重新启动服务需要一些时间 大约 1 3 分钟 我想立即重新启动服务 有没有办
  • 从 ASP 启动/停止服务。网页

    我实现了一个网页 ASP NET VB 来启动 停止 Windows 服务 我使用了拟人化 如下所述 http support microsoft com kb 306158 当页面读取服务状态时一切正常 domain Me TextBox
  • Curl 错误:无法解析主机:www.localhost

    我收到无法解决的错误host www localhost 我不知道它为什么会来 url http www localhost 81 dbWIP selectApi php name name client curl init echo cl
  • 使用 rake db:create 创建 Rails DB 时出错

    我正在尝试使用 Rails 来实现我的第一个 hello world rails 示例入门指南在我的 OSX 10 6 3 机器上 当我去执行第一个时rake db create命令 我正在使用 mysql 我得到 simon Users
  • 切换选项卡后 WPF ComboBox 选择发生变化

    我做了一个基于嵌套选项卡的项目 嵌套选项卡是同一 viemModel 和同一 UI 的不同实例 当我在选项卡之间切换时 选项卡中存在的组合框会根据失去焦点的选项卡进行选择 我添加了测试项目的视图模型和视图 预先感谢您的帮助 主窗口
  • Hikari 池禁用调试模式

    大家好 我必须禁用日志信息com zaxxer hikari pool HikariPool 我尝试过 Logger getLogger com zaxxer hikari pool HikariPool setLevel Level OF
  • MS Word 宏 - 删除段落

    有人可以帮我使用 MS Word 宏吗 它可以在整个文档的每个段落中搜索特定符号 并删除不包含该符号的段落 我对 VBA 几乎一无所知 但刚刚收到一份巨大且笨重的文档 我需要快速编辑 这是一个快速宏 应该可以完成您想要的操作 谨慎使用 并且
  • 编辑框提示 - 始终显示提示

    我有一个带有提示的文本框 但我希望始终显示提示 即使 TB 中有输入也是如此 示例是 Gmail 应用程序中的 收件人 字段 您可以使用 3 种方法 剧透 使用数字 3 因为正如我的评论中提到的 在 Gmail 示例中 它不是实际的提示 在
  • Observable Angular2

    我的 Angular2 应用程序中有对象数组 当新对象到达时 我使用 SignalR 填充数组 现在的重点是当新对象到达时我遇到了错误 无法读取未定义的属性 我认为这可能是错误的 因为它的工作是异步的 并且在 html 中我曾经在对象内部获
  • WIF - FederatedSignOut 未将用户注销所有站点

    我正在使用 Windows 身份基础 对于一些 MVC 2 0 站点 我在将某人从所有受 WIF 保护的网站中注销时遇到了真正的问题 看起来我的注销只是将当前站点上的人员注销 这是我的代码 public void FederatedSign
  • Rails:从另一个模型调用一个模型。为什么这是不可能的?

    我有以下型号 class Room lt ActiveRecord Base belongs to hotel belongs to layout has many visits validates number presence true
  • 调用fopen时的内存分配不清楚

    1 File fp 2 fp fopen etc myfile txt w 3 fclose fp Now 我读了这个 在语句 1 中 在堆栈上为指针创建了一个 FILE 类型的 4 字节内存 在语句2中 在堆上分配了一块内存 sizeof
  • Firebase 实时数据库 CORS 问题

    我在网站上使用 Firebase 实时数据库 一切正常 但是 当我想使用自定义 json 令牌进行身份验证时 我收到如下 CORS 问题 来自另一个被阻止的源的请求 相同的源策略阻止读取远程资源位于https www googleapis
  • 设置自定义锚点

    有没有办法在实际 HTML 标记之外的位置自定义设置锚点 我正在使用这个简单的视差滚动脚本 名为 smoothscroll js at http www kryogenix org code browser smoothscroll smo
  • 执行中的Python sqlite3字符串变量

    我尝试在 Python 中执行这个 sqlite3 查询 我将代码减少到最少 sqlite connect 等有效 column Pron 1 Pers Sg goal gender constrain Mann with con cur
  • 为什么BroadcastReceiver没有在后台运行?

    在一个应用程序 App1 中 我正在广播一条消息 下面的代码是正确的 gt 如果我尝试在同一项目中获取广播 则会检测到广播 sendBroadcast new Intent com example MESSAGE INTENT putExt