Android的活动没有得到来自当地的服务广播 [英] Android activity not getting broadcast from local service

查看:134
本文介绍了Android的活动没有得到来自当地的服务广播的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从这个例子看起来简单。也许你能告诉我我做错了什么。我不能让一个活动接收来自本地服务发送一个广播。

我有活性1启动服务1:

  startService(新意图(Activity1.this,Service1.class));
 

活动1然后启动活性2:

  startActivity(新意图(Activity1.this,Activity2.class));
 

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

 保护最后的BroadcastReceiver service2DownloadBroadcastReceiver =新的BroadcastReceiver()
{
    公共无效的onReceive(最终上下文的背景下,最终的意图意图)
    {
        ...
        broadcastDownloadFinished(Uri.fromFile(downloadedFile));
 

服务1的广播接收器,然后广播自己的消息:

 保护意图broadcastDownloadFinished(最终乌里URI)
{
    最终意向意图=新的意图(ACTION_DOWNLOAD_FINISHED).setData(checkNotNull(URI));
    sendBroadcast(意向);
 

使用其自己的广播接收机

活性2,这是在前景的时候,侦听ACTION_DOWNLOAD_FINISHED意图:

 私人最终的BroadcastReceiver activity2DownloadBroadcastReceiver =新的BroadcastReceiver()
{
    公共无效的onReceive(最终上下文的背景下,最终的意图意图)
    {
        Log.i(Activity2.class.getSimpleName(),接收到的下载活动:+ intent.getAction()++ intent.getData());
 

当然,活性2寄存器接收器:

 保护无效onResume()
{
    super.onResume();
    最后的IntentFilter downloadIntentFilter =新的IntentFilter();
    downloadIntentFilter.addAction(ACTION_DOWNLOAD_FINISHED);
    registerReceiver(activity2DownloadBroadcastReceiver,downloadIntentFilter);
 

在情况下它的事项, ACTION_DOWNLOAD_FINISHED 是像com.example.intent.action.DOWNLOAD_FINISHED

服务1接收下载管理器事件的接收器,显然广播自己的自定义事件,但活性2似乎永远不会接受它。我做了什么错?是一个问题,在广播处理另一个之一的中间的意图是什么? (我不这么认为---这是异步的,对吧?)

更新:的只是为了确保没有问题,在接收广播的中间发送广播,我改变了我的广播code到实际执行广播三秒钟后在主主题:

  Log.i(的getClass()getSimpleName(),...准备播出的。);
    最终意向意图=新的意图(ACTION_DOWNLOAD_FINISHED).setData(checkNotNull(URI));
    mainThreadHandler.postDelayed(新的Runnable()
    {
        公共无效的run()
        {
            Log.i(的getClass()getSimpleName(),...广播。);
            sendBroadcast(意向);
            Log.i(的getClass()getSimpleName(),...广播。);
        }
    },3000);
    Log.i(的getClass()getSimpleName(),...预定广播。);
 

正如预期的那样,该日志称:

  ...准备播出
...预定播出
...广播
...播放
 

然而没有被接收在活动。请大家帮帮忙。

解决方案

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

不幸的是,尽管Android的文件说,该数据类型可以从数据URI来推断,显然是Android不知道,文件://.../example.jpg 是一个图像。所以,这不工作:

  intentFilter.addDataType(图像/ *);
 

不过,而不是指定的类型,我可以指定一个计划,我接受:

  intentFilter.addDataScheme(文件);
 

这作品!这是一个有点粗糙---和一点点人为的限制我的节目,以文件:的URI,但因为这是所有我使用的那一刻,它的工作原理

请注意,显然我可以手动指定MIME类型的意图,当我播放它,但是这太麻烦了,因为我从Picasa下载图片,所以我已经知道他们是图像(并且不关心具体的MIME类型)。如果它变得太麻烦了,我可以完全抛弃整个使用setData()的事情,并设置一个额外的 - 但当然,我想要做的事情的正确方法。

From the examples this looked straightforward. Maybe you can show me what I did wrong. I can't get an activity to receive a broadcast sent from a local service.

I have Activity1 that start Service1:

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

Activity1 then starts Activity2:

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

Service1, a local service, listens for downloads:

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

The broadcast receiver of Service1 then broadcasts its own message:

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

Activity2, which is in the foreground at the time, listens for the ACTION_DOWNLOAD_FINISHED intent using its own broadcast receiver:

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 of course registers the receiver:

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

In case it matters, ACTION_DOWNLOAD_FINISHED is something like "com.example.intent.action.DOWNLOAD_FINISHED".

Service1 receives the download manager event in its receiver and apparently broadcasts its own custom event, but Activity2 never seems to receive it. What did I do wrong? Is it a problem to broadcast an intent in the middle of processing another one? (I wouldn't think so---this is asynchronous, right?)

Update: Just to make sure there is no problem sending a broadcast in the middle of receiving a broadcast, I changed my broadcast code to actually perform the broadcast three seconds later on the main thread:

    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");

As expected, the log says:

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

Yet nothing is received in the activity. Please help.

解决方案

Eureka! I found it! The problem is that I supplied a data URI in my broadcast intent. The Android intent matching rules get a little complicated. If you supply a data URI, then your intent filter must specify a matching MIME type.

Unfortunately, although the Android documentation says that the data type can be inferred from the data URI, apparently Android doesn't know that a file://.../example.jpg is an image. So this doesn't work:

intentFilter.addDataType("image/*");

However, instead of specifying a type, I can specify a scheme that I accept:

intentFilter.addDataScheme("file");

That works! It's a little rough---and a little artificial to restrict my broadcasts to file: URIs, but as that's all I'm using for the moment, it works.

Note that apparently I could manually specify the MIME type in the intent when I broadcast it, but that's too much trouble for now, as I'm downloading images from Picasa so I already know that they are images (and don't care the specific MIME type). And if it gets too much trouble, I could ditch the whole setData() thing altogether and set an extra---but of course I want to do things the Right Way.

这篇关于Android的活动没有得到来自当地的服务广播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆