【问题标题】:Can I filter BroadcastReceiver other than using intent filters?除了使用意图过滤器之外,我可以过滤 BroadcastReceiver 吗?
【发布时间】:2014-11-21 07:11:49
【问题描述】:

根据我在文档中的理解,当我在清单中使用意图过滤器注册 BroadcastReceiver 时,将调用 onReceive 方法。 我的应用程序使用 DownloadManager 来处理文件下载。我想听 DOWNLOAD_COMPLETE 动作。所以,在我的清单中,我有一个这样的意图过滤器:

<receiver
       android:name="com.myapp.DownloadReceiver" >
       <intent-filter>
           <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
       </intent-filter>
</receiver>

我的类方法是这样的:

private DownloadManager manager;
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(result));
request.setTitle("MyTitle");
request.setDescription("MyDescription");
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, Test.txt);
manager.enqueue(request);

此接收器将接收由 DownloadManager 发送的所有意图。有没有办法通过侦听仅由我的应用程序排队的已完成下载来限制过滤?如果我尝试android:exported="false",它将不会收到 DownloadManager 广播,因为它们来自另一个应用程序。 如果我过滤 ID,我的 onReceive 方法仍然会被调用。我想要实现的是避免我的接收器接收所有事件。 谢谢!

【问题讨论】:

  • What i want to achieve is avoiding that my receiver will receive ALL the events. 您的接收器仅被调用用于下载完成事件,我认为在清单中注册您的接收器是个好主意,因为即使用户关闭,您也可以尽快处理完成的文件你的应用程序。

标签: android android-intent broadcastreceiver intentfilter


【解决方案1】:

您无法过滤 DownloadManager 发送给您的广播 - 只要您的接收器已注册,您就会收到所有 downloadmanager 事件的广播。

但是,您可以使用 DownLoadManager.enqueue 方法返回的 id。在您的接收器中,您可以获得触发广播的下载的 ID:

Long downLoadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);

另外,我不建议在清单中注册您的接收器 - 这将在所有下载管理器事件中调用您的应用程序,您可能不希望这样。而是在您将下载排入队列后在代码中注册您的接收器,并在下载完成(成功与否)时将其删除。还记得在你的活动被销毁之前取消注册接收器。

如果这是不可接受的,即您有时希望在您的应用未激活时接收广播,您应该在清单中注册您的接收器并根据需要打开/关闭它。

在您的清单中最初禁用接收器:

<receiver
       android:name="com.myapp.DownloadReceiver" 
       android:enabled="false" >
       <intent-filter>
           <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
       </intent-filter>
</receiver>

然后当您需要它时 - 例如在开始下载后启用它:

PackageManager pm  = getApplicationContext().getPackageManager();
ComponentName componentName = new ComponentName("com.myapp", ".DownloadReceiver");
pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

当您不想再接收广播时 - 例如当您下载完成时禁用接收器:

pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

这样,您的应用程序将仅在需要时接收广播。

【讨论】:

  • 好吧,我明白你在说什么,但也许有问题。你说我收到所有下载管理器事件。您的意思是,在我的清单中使用意图过滤器时,我只会收到我从所有使用 DownloadManager 的应用程序中过滤的事件,对吧?
  • 也许我应该在我的应用程序被销毁时注销我的接收器
  • 您正在接收所有 DownloadManager 广播。您不会使用 DownloadManager 从其他应用程序接收任何内容。是的,当您在代码中注册您的接收器时,您应该在您的活动被销毁之前取消注册它。我编辑了我的答案,添加了建议,当您有时需要接收广播时该怎么做,即使您的应用未处于活动状态。
  • 我想我会在需要时以编程方式手动注册/取消注册。
【解决方案2】:

据我了解,您需要一个 BroadcastReceiver,在您的情况下,它应该是 public class DownloadReceiver extends BroadcastReceiver

您需要覆盖the onReceive 方法,这里是您接收和处理广播的地方。 在我收到短信的情况下,我检查了

if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED"))

抱歉,如果这不符合您的需求,我还没有使用 DownloadManager。

【讨论】:

  • 感谢您的回答,但这不是我要问的。我知道如何处理接收器。问题是我想避免从其他使用 DownloadManager 的应用程序接收意图。我知道我应该查看 enqueue 方法返回的长 id,但我想问是否有办法避免使用 DownloadManager 从其他应用程序触发我的接收器来排队和下载文件。
  • 很遗憾,这是不可能的,DownloadManager 不跟踪也不关心哪个应用程序开始下载,所有下载的文件都可用于所有应用程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
  • 2014-06-30
  • 1970-01-01
  • 2018-03-16
  • 2011-07-27
  • 1970-01-01
相关资源
最近更新 更多