【问题标题】:Android activity not getting broadcast from local serviceAndroid活动未从本地服务广播
【发布时间】:2011-11-13 14:19:53
【问题描述】:

从示例中这看起来很简单。也许你可以告诉我我做错了什么。我无法获得接收本地服务发送的广播的活动。

我有启动 Service1 的 Activity1:

startService(new Intent(Activity1.this, Service1.class));

Activity1 然后启动 Activity2:

startActivity(new Intent(Activity1.this, Activity2.class));

Service1,本地服务,监听下载:

protected final BroadcastReceiver service2DownloadBroadcastReceiver = new BroadcastReceiver()
{
    public void onReceive(final Context context, final Intent intent)
    {
        ...
        broadcastDownloadFinished(Uri.fromFile(downloadedFile));

Service1 的广播接收者然后广播自己的消息:

protected Intent broadcastDownloadFinished(final Uri uri)
{
    final Intent intent = new Intent(ACTION_DOWNLOAD_FINISHED).setData(checkNotNull(uri));
    sendBroadcast(intent);

当时处于前台的Activity2使用自己的广播接收器监听ACTION_DOWNLOAD_FINISHED意图:

private final BroadcastReceiver activity2DownloadBroadcastReceiver = new BroadcastReceiver()
{
    public void onReceive(final Context context, final Intent intent)
    {
        Log.i(Activity2.class.getSimpleName(), "Received download event: " + intent.getAction() + " " + intent.getData());

Activity2当然会注册接收者:

protected void onResume()
{
    super.onResume();
    final IntentFilter downloadIntentFilter = new IntentFilter();
    downloadIntentFilter.addAction(ACTION_DOWNLOAD_FINISHED);
    registerReceiver(activity2DownloadBroadcastReceiver, downloadIntentFilter);

如果重要,ACTION_DOWNLOAD_FINISHED 类似于 "com.example.intent.action.DOWNLOAD_FINISHED"

Service1 在其接收器中接收到下载管理器事件,并且显然广播了它自己的自定义事件,但 Activity2 似乎从未接收到它。我做错了什么?在处理另一个意图的过程中广播一个意图是否有问题? (我不这么认为——这是异步的,对吧?)

更新: 为了确保在接收广播的过程中发送广播没有问题,我将广播代码更改为在主线程三秒后实际执行广播:

    Log.i(getClass().getSimpleName(), "...ready to broadcast");     
    final Intent intent = new Intent(ACTION_DOWNLOAD_FINISHED).setData(checkNotNull(uri));
    mainThreadHandler.postDelayed(new Runnable()
    {
        public void run()
        {
            Log.i(getClass().getSimpleName(), "...broadcasting");
            sendBroadcast(intent);
            Log.i(getClass().getSimpleName(), "...broadcasted");                
        }
    }, 3000);
    Log.i(getClass().getSimpleName(), "...scheduled to broadcast");

不出所料,日志显示:

...ready to broadcast
...scheduled to broadcast
...broadcasting
...broadcasted

但在活动中没有收到任何内容。请帮忙。

【问题讨论】:

    标签: android service broadcastreceiver


    【解决方案1】:

    尤里卡!我找到了!问题是我在广播意图中提供了一个数据 URI。 Android 意图匹配规则有点复杂。如果您提供数据 URI,那么您的意图过滤器必须指定匹配的 MIME 类型。

    不幸的是,虽然 Android 文档说可以从数据 URI 推断出数据类型,但显然 Android 不知道 file://.../example.jpg 是图像。所以这不起作用:

    intentFilter.addDataType("image/*");
    

    但是,我可以指定我接受的方案,而不是指定类型:

    intentFilter.addDataScheme("file");
    

    这行得通!将我的广播限制为 file: URI 有点粗糙,而且有点人为,但我目前只使用这些,它可以工作。

    请注意,当我广播它时,显然我可以在意图中手动指定 MIME 类型,但现在这太麻烦了,因为我正在从 Picasa 下载图像,所以我已经知道它们是图像(并且不要注意特定的 MIME 类型)。如果它太麻烦,我可以完全放弃整个 setData() 并设置一个额外的东西——但我当然想以正确的方式做事。

    【讨论】:

    • 你打败了我。我没有发现这个自我回答,只是在查看您的代码。我将建议将setData(...) 排除在代码之外只是为了看看发生了什么-显然(从您的回答中)它会起作用。抱歉,我不能早点开始——我今天上班迟到了。很高兴您找到了解决方案。
    • 非常感谢您花时间看这个,MisterSquonk。这让我发狂。我希望这最终能帮助某人。晚安。
    【解决方案2】:

    您是否将接收器包含在您的活动清单中?

    <receiver
      android:name=".YourReceiver">
      <intent-filter>
        <action
          android:name="intent_name"></action>
      </intent-filter>
    </receiver>
    

    【讨论】:

    • 没有。据我了解,手动注册的接收器不需要这样做。另外,receiver是一个内部类,不能按照你描述的方式注册。
    • 肯定可以。设置 android:name=".ParentClass$ReceiverName"
    • 也许我在这里偏离了基础,但是 1) 我使用的是匿名内部类,所以你必须猜测生成的 ...$Name,2) &lt;receiver&gt;元素是让Android根据需要自动实例化接收器,Android不能自动实例化我的非静态匿名内部类,3)我的接收器类已经实例化并注册了,所以@987654325不需要@元素。试图回到主题:手动注册的接收器是否需要&lt;receiver&gt;?我相信他们不是。
    • 只是跟进:手动注册广播接收器时,清单中的静态定义不需要;见developer.android.com/reference/android/content/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多