public abstract class BroadcastReceiver
extends Object
java.lang.Object | |
↳ | android.content.BroadcastReceiver |
Known Direct Subclasses |
将接收sendBroadcast()发送的意图的代码的基类。
如果您不需要跨应用程序发送广播,请考虑将此类与LocalBroadcastManager
一起使用,而不是下面介绍的更一般的设施。 这将为您提供更高效的实现(不需要跨进程通信),并且可以避免考虑与其他应用程序能够接收或发送广播相关的任何安全问题。
您可以动态地注册这个类的一个实例 Context.registerReceiver()
或静态发布通过实现 <receiver>
标签在你 AndroidManifest.xml
。
注意:如果在您的Activity.onResume()
实施中注册接收器,则应该在Activity.onPause()
取消注册。 (暂停时不会收到意图,这将减少不必要的系统开销)。 请勿注销Activity.onSaveInstanceState()
,因为如果用户移回历史堆栈中,则不会调用该注册。
有两种主要类型的广播可以收到:
Context.sendBroadcast
) are completely asynchronous. All receivers of the broadcast are run in an undefined order, often at the same time. This is more efficient, but means that receivers cannot use the result or abort APIs included here. Context.sendOrderedBroadcast
) are delivered to one receiver at a time. As each receiver executes in turn, it can propagate a result to the next receiver, or it can completely abort the broadcast so that it won't be passed to other receivers. The order receivers run in can be controlled with the android:priority
attribute of the matching intent-filter; receivers with the same priority will be run in an arbitrary order. 即使在正常广播的情况下,系统在某些情况下也可能恢复为每次传送一个广播接收机。 特别是,对于可能需要创建进程的接收者,一次只能运行一个,以避免使用新进程对系统进行过载。 然而,在这种情况下,无序的语义保持不变:这些接收器仍然不能返回结果或中止它们的广播。
请注意,尽管Intent类用于发送和接收这些广播,但这里的Intent广播机制与用于启动Context.startActivity()
活动”的Intents完全分离。 BroadcastReceiver无法查看或捕获与startActivity()一起使用的Intents; 同样,当您广播一个意图时,您将永远不会找到或启动一个活动。 这两个操作在语义上非常不同:用Intent启动一个Activity是一个前台操作,它修改了用户当前正在与之交互的内容; 广播Intent是用户通常不知道的后台操作。
该广播接收器类(当通过一个清单的一个组成部分推出 <receiver>
标签)是一个重要组成部分 application's overall lifecycle 。
涵盖的主题包括:
有关如何使用此类来接收和解析意图的信息,请阅读 Intents and Intent Filters开发人员指南。
与Context
API一起使用的接收器本身就是一个交叉应用程序,因此您必须考虑其他应用程序如何滥用您的应用程序。 有些事情要考虑的是:
Intent命名空间是全局的。 确保Intent操作名称和其他字符串被写入您拥有的名称空间中,否则可能会与其他应用程序无意中冲突。
当您使用registerReceiver(BroadcastReceiver, IntentFilter)
, 任何应用程序都可能向该注册的接收方发送广播。 您可以通过以下权限控制谁可以向其发送广播。
当您在应用程序的清单中发布接收器并为其指定意图过滤器时,无论您指定哪个过滤器,任何其他应用程序都可以向其发送广播。 为了防止他人发送给它,请使用android:exported="false"
使其不可用。
当您使用sendBroadcast(Intent)
或相关方法时,通常任何其他应用程序都可以接收这些广播。 您可以通过下述权限控制哪些人可以收到此类广播。 或者,从ICE_CREAM_SANDWICH
开始,您还可以安全地将广播限制为单个应用程序,并且Intent.setPackage
使用 LocalBroadcastManager
时,这些问题都不存在,因为意图广播它不会超出当前过程。
访问权限可以由广播的发送者或接收者强制执行。
要在发送时强制执行权限,请向sendBroadcast(Intent, String)
或sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, Bundle)
提供非空权限参数。 谁已被授予这个权限(通过与请求只接收<uses-permission>
在他们的标签AndroidManifest.xml
)将能够接收广播。
为了实施当接收到许可,您在注册时,接收器提供一个非空的许可 -拨打电话时无论是registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)
或静态<receiver>
在标签AndroidManifest.xml
。 谁已被授予这个权限(通过与请求仅广播<uses-permission>
在他们的标签AndroidManifest.xml
)将能够一个Intent发送到接收器。
有关权限和安全性的更多信息,请参阅Security and Permissions文档。
BroadcastReceiver对象仅在调用onReceive(Context, Intent)
期间有效。 一旦你的代码从这个函数返回,系统就认为该对象已经完成并且不再处于活动状态。
这对于在 onReceive(Context, Intent)
实现中可以执行的操作具有重要影响:任何需要异步操作的任何操作都不可用,因为您需要从该函数返回以处理异步操作,但此时BroadcastReceiver不再处于活动状态,因此在异步操作完成之前,系统可以自由地终止其进程。
特别是,您可能不会显示对话框或绑定到BroadcastReceiver中的服务。 对于前者,您应该使用NotificationManager
API。 对于后者,您可以使用Context.startService()
向服务发送命令。
目前正在执行BroadcastReceiver的过程(也就是说,目前正在其 onReceive(Context, Intent)
方法中运行该代码)被视为前台进程,并将由系统继续运行,除非内存压力过大。
一旦从onReceive()返回,BroadcastReceiver不再处于活动状态,其宿主进程与运行在其中的任何其他应用程序组件一样重要。 这一点尤其重要,因为如果该进程仅托管BroadcastReceiver(用户从未或最近未与之交互过的应用程序的常见情况),那么在从onReceive()返回时,系统将认为其进程是空的并积极地杀死它使资源可用于其他更重要的流程。
这意味着对于长时间运行的操作,您通常 Service
与BroadcastReceiver结合使用,以保持包含过程在整个操作过程中处于活动状态。
Nested classes |
|
---|---|
class |
BroadcastReceiver.PendingResult 状态为广播接收器的待处理结果。 |
Public constructors |
|
---|---|
BroadcastReceiver() |
Public methods |
|
---|---|
final void |
abortBroadcast() 设置指示该接收器应当中止当前广播的标志; 仅适用于通过 |
final void |
clearAbortBroadcast() 清除指示该接收机应中止当前广播的标志。 |
final boolean |
getAbortBroadcast() 返回指示此接收器是否应中止当前广播的标志。 |
final boolean |
getDebugUnregister() 返回给定的最后一个值为 |
final int |
getResultCode() 检索当前结果代码,由前一个接收器设置。 |
final String |
getResultData() 检索当前结果数据,由前一个接收器设置。 |
final Bundle |
getResultExtras(boolean makeMap) 检索当前结果的额外数据,由前一个接收器设置。 |
final BroadcastReceiver.PendingResult |
goAsync() 这可以由 |
final boolean |
isInitialStickyBroadcast() 如果接收者当前正在处理粘性广播的初始值(即,上次广播的值并且当前保存在粘性缓存中),则返回true,因此这不是直接由广播产生的结果。 |
final boolean |
isOrderedBroadcast() 如果接收者当前正在处理有序广播,则返回true。 |
abstract void |
onReceive(Context context, Intent intent) 当BroadcastReceiver正在接收Intent广播时调用此方法。 |
IBinder |
peekService(Context myContext, Intent service) 为已经运行的服务提供一个绑定。 |
final void |
setDebugUnregister(boolean debug) 控制对 |
final void |
setOrderedHint(boolean isOrdered) 对于内部使用,设置有关此BroadcastReceiver是否以有序模式运行的提示。 |
final void |
setResult(int code, String data, Bundle extras) 更改从此广播返回的所有结果数据; 仅适用于通过 |
final void |
setResultCode(int code) 更改此广播的当前结果代码; 仅适用于通过 |
final void |
setResultData(String data) 更改此广播的当前结果数据; 仅适用于通过 |
final void |
setResultExtras(Bundle extras) 更改此广播的当前结果附加内容; 仅适用于通过 |
Inherited methods |
|
---|---|
From class java.lang.Object
|
void abortBroadcast ()
设置指示该接收器应当中止当前广播的标志; 仅适用于通过Context.sendOrderedBroadcast
发送的广播。 这将阻止任何其他广播接收机接收广播。 它仍然会调用onReceive(Context, Intent)
的调用者通过的BroadcastReceiver的Context.sendOrderedBroadcast
。
此方法不适用于无序广播,例如与Context.sendBroadcast
发送的Context.sendBroadcast
boolean getAbortBroadcast ()
返回指示此接收器是否应中止当前广播的标志。
Returns | |
---|---|
boolean |
True if the broadcast should be aborted. |
boolean getDebugUnregister ()
返回给定的最后一个值为 setDebugUnregister(boolean)
。
Returns | |
---|---|
boolean |
int getResultCode ()
检索当前结果代码,由前一个接收器设置。
Returns | |
---|---|
int |
int The current result code. |
String getResultData ()
检索当前结果数据,由前一个接收器设置。 通常这是空的。
Returns | |
---|---|
String |
String The current result data; may be null. |
Bundle getResultExtras (boolean makeMap)
检索当前结果的额外数据,由前一个接收器设置。 您对返回的地图所做的任何更改都会传播到下一个接收器。
Parameters | |
---|---|
makeMap |
boolean : If true then a new empty Map will be made for you if the current Map is null; if false you should be prepared to receive a null Map. |
Returns | |
---|---|
Bundle |
Map The current extras map. |
BroadcastReceiver.PendingResult goAsync ()
这可以由onReceive(Context, Intent)
的应用程序调用,以允许它在从该函数返回后保持广播活动。 这不会改变的是相对响应广播(10秒内完成它)的期望,但允许实现移动与它在工作,另一个线程来避免毛刺的主UI线程由于磁盘IO。
Returns | |
---|---|
BroadcastReceiver.PendingResult |
Returns a BroadcastReceiver.PendingResult representing the result of the active broadcast. The BroadcastRecord itself is no longer active; all data and other interaction must go through BroadcastReceiver.PendingResult APIs. The PendingResult.finish() method must be called once processing of the broadcast is done. |
boolean isInitialStickyBroadcast ()
如果接收者当前正在处理粘性广播的初始值(即,上次广播的值并且当前保存在粘性缓存中),则返回true,因此这不是直接由广播产生的结果。
Returns | |
---|---|
boolean |
boolean isOrderedBroadcast ()
如果接收者当前正在处理有序广播,则返回true。
Returns | |
---|---|
boolean |
void onReceive (Context context, Intent intent)
当BroadcastReceiver正在接收Intent广播时调用此方法。 在此期间,您可以使用BroadcastReceiver上的其他方法查看/修改当前结果值。 此方法始终在其进程的主线程中调用,除非您明确要求使用registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)
将其安排在其他线程上。 当它在主线程上运行时,您不应该在其中执行长时间运行的操作(在考虑接收器被阻塞并且候选者被终止之前系统允许超时10秒)。 你不能在你的onReceive()的实现中启动一个弹出对话框。
如果此BroadcastReceiver是通过<receiver>标签启动的,则该对象在从此函数返回后不再有效。 这意味着您不应该执行任何异步返回结果的操作 - 特别是与服务交互时,应该使用startService(Intent)
而不是bindService(Intent, ServiceConnection, int)
。 如果您希望与正在运行的服务交互,可以使用peekService(Context, Intent)
。
registerReceiver(BroadcastReceiver, IntentFilter)
和应用程序清单中使用的Intent过滤器不保证是排他性的。 它们提示操作系统如何找到合适的收件人。 发件人可能会强制传递给特定收件人,从而绕过过滤器解决方案。 出于这个原因, onReceive()
实现应该只响应已知的操作,忽略它们可能会收到的意外意图。
Parameters | |
---|---|
context |
Context : The Context in which the receiver is running. |
intent |
Intent : The Intent being received. |
IBinder peekService (Context myContext, Intent service)
为已经运行的服务提供一个绑定。 此方法是同步的,如果目标服务不存在,将不会启动目标服务,因此从onReceive(Context, Intent)
进行调用是安全的。
Parameters | |
---|---|
myContext |
Context : The Context that had been passed to onReceive(Context, Intent) |
service |
Intent : The Intent indicating the service you wish to use. See startService(Intent) for more information. |
Returns | |
---|---|
IBinder |
void setDebugUnregister (boolean debug)
控制对Context.registerReceiver()
不匹配调用包含调试帮助。 如果在调用registerReceiver()之前调用true,则保留以下Context.unregisterReceiver()
调用的调用堆栈,以便在稍后进行不正确的取消注册调用时进行打印。 请注意,这样做需要在应用程序的整个生命周期中保留有关BroadcastReceiver的信息,导致泄漏 - 这应该仅用于调试。
Parameters | |
---|---|
debug |
boolean
|
void setOrderedHint (boolean isOrdered)
对于内部使用,设置有关此BroadcastReceiver是否以有序模式运行的提示。
Parameters | |
---|---|
isOrdered |
boolean
|
void setResult (int code, String data, Bundle extras)
更改从此广播返回的所有结果数据; 仅适用于通过Context.sendOrderedBroadcast
发送的广播。 所有当前的结果数据都被赋予此方法的值替换。
此方法不适用于无序广播,例如与Context.sendBroadcast
发送的Context.sendBroadcast
Parameters | |
---|---|
code |
int : The new result code. Often uses the Activity RESULT_CANCELED and RESULT_OK constants, though the actual meaning of this value is ultimately up to the broadcaster. |
data |
String : The new result data. This is an arbitrary string whose interpretation is up to the broadcaster; may be null. |
extras |
Bundle : The new extra data map. This is a Bundle holding arbitrary data, whose interpretation is up to the broadcaster. Can be set to null. This completely replaces the current map (if any). |
void setResultCode (int code)
更改此广播的当前结果代码; 仅适用于通过Context.sendOrderedBroadcast
发送的广播。 通常使用活动RESULT_CANCELED
和RESULT_OK
常量,尽管此值的实际含义最终取决于广播者。
此方法不适用于无序广播,例如与 Context.sendBroadcast
发送的 Context.sendBroadcast
Parameters | |
---|---|
code |
int : The new result code. |
void setResultData (String data)
更改此广播的当前结果数据; 仅适用于通过Context.sendOrderedBroadcast
发送的广播。 这是一个任意字符串,其解释由广播公司决定。
此方法不适用于无序广播,例如与Context.sendBroadcast
发送的Context.sendBroadcast
Parameters | |
---|---|
data |
String : The new result data; may be null. |
void setResultExtras (Bundle extras)
更改此广播的当前结果附加内容; 仅适用于通过Context.sendOrderedBroadcast
发送的广播。 这是一个包含任意数据的Bundle,其解释由广播公司决定。 可以设置为空。 调用此方法将完全替换当前映射(如果有)。
此方法不适用于无序广播,例如与Context.sendBroadcast
发送的Context.sendBroadcast
Parameters | |
---|---|
extras |
Bundle : The new extra data map; may be null. |