- What is receiver in android manifest
- Local Broadcast, less overhead and secure in Android
- Basics of Broadcast
- Register Broadcast
- Receive Broadcasts
- Problem with global broadcast
- What is LocalBroadcastManager?
- Implementation
- How to secure broadcasts
- Restrict your app to receive broadcast
- Control receiver of your broadcast
- Conclusion
- Broadcasts overview
- About system broadcasts
- Changes to system broadcasts
- Android 9
- Android 8.0
- Android 7.0
- Receiving broadcasts
- Manifest-declared receivers
- Kotlin
- Context-registered receivers
- Kotlin
- Kotlin
- Effects on process state
- Kotlin
- Sending broadcasts
- Kotlin
- Restricting broadcasts with permissions
- Sending with permissions
- Kotlin
- Receiving with permissions
- Kotlin
- Security considerations and best practices
What is receiver in android manifest
There are two ways to make a broadcast receiver known to the system: One is declare it in the manifest file with this element. The other is to create the receiver dynamically in code and register it with the Context.registerReceiver() method. See the BroadcastReceiver class description for more on dynamically created receivers.
attributes: android:enabled Whether or not the broadcast receiver can be instantiated by the system — » true » if it can be, and » false » if not. The default value is » true «.
android:exported Whether or not the broadcast receiver can receive messages from sources outside its application — » true » if it can, and » false » if not. If » false «, the only messages the broadcast receiver can receive are those sent by components of the same application or applications with the same user ID.
The default value depends on whether the broadcast receiver contains intent filters. The absence of any filters means that it can be invoked only by Intent objects that specify its exact class name. This implies that the receiver is intended only for application-internal use (since others would not normally know the class name). So in this case, the default value is » false «. On the other hand, the presence of at least one filter implies that the broadcast receiver is intended to receive intents broadcast by the system or other applications, so the default value is » true «.
This attribute is not the only way to limit a broadcast receiver’s external exposure. You can also use a permission to limit the external entities that can send it messages (see the permission attribute).
android:icon An icon representing the broadcast receiver. This attribute must be set as a reference to a drawable resource containing the image definition. If it is not set, the icon specified for the application as a whole is used instead (see the element’s icon attribute).
android:label A user-readable label for the broadcast receiver. If this attribute is not set, the label set for the application as a whole is used instead (see the element’s label attribute).
The label should be set as a reference to a string resource, so that it can be localized like other strings in the user interface. However, as a convenience while you’re developing the application, it can also be set as a raw string.
android:name The name of the class that implements the broadcast receiver, a subclass of BroadcastReceiver . This should be a fully qualified class name (such as, » com.example.project.ReportReceiver «). However, as a shorthand, if the first character of the name is a period (for example, » . ReportReceiver «), it is appended to the package name specified in the element.
Once you publish your application, you should not change this name (unless you’ve set android:exported=»false» ).
There is no default. The name must be specified.
android:permission The name of a permission that broadcasters must have to send a message to the broadcast receiver. If this attribute is not set, the permission set by the element’s permission attribute applies to the broadcast receiver. If neither attribute is set, the receiver is not protected by a permission.
For more information on permissions, see the Permissions section in the introduction and a separate document, Security and Permissions.
android:process The name of the process in which the broadcast receiver should run. Normally, all components of an application run in the default process created for the application. It has the same name as the application package. The element’s process attribute can set a different default for all components. But each component can override the default with its own process attribute, allowing you to spread your application across multiple processes.
If the name assigned to this attribute begins with a colon (‘:’), a new process, private to the application, is created when it’s needed and the broadcast receiver runs in that process. If the process name begins with a lowercase character, the receiver will run in a global process of that name, provided that it has permission to do so. This allows components in different applications to share a process, reducing resource usage.
Источник
Local Broadcast, less overhead and secure in Android
Apr 28, 2017 · 4 min read
Broadcast receiver is an Android component which allows you to send or receive Android system or application events. All the registered application are notified by the Android runtime once event happens.
It works similar to the publish-subscribe design pattern and used for asynchronous inter-process communication.
For example, applications can register for various system events like boot complete or battery low, and Android system sends broadcast when specific event occur. Any application can also create its own custom broadcasts.
Basics of Broadcast
Let’s discuss some basic concepts of broadcast receiver.
Register Broadcast
There are two ways to register broadcast receiver-
Manife s t-declared (Statically) : By this receiver can be registered via the AndroidManifest.xml file.
Context-registered (Dynamically) : By this register a receiver dynamically via the Context.registerReceiver() method.
Receive Broadcasts
To be able to receive a broadcast, application have to extends the BroadcastReceiver abstract class and override its onReceive() method.
If the event for which the broadcast receiver has registered happens, the onReceive() method of the receiver is called by the Android system.
Problem with global broadcast
It is good practice to use broadcast receivers when you want to send or receive data between different applications. But if the communication is limited to your application then it is not good to use the global broadcast.
In this case Android provides local broadcasts with the LocalBroadcastManager class. Using global broadcast, any other application can also send and receives broadcast messages to and from our application. This can be a serious security thread for our application. Also global broadcast is sent system-wide, so it is not performance efficient.
What is LocalBroadcastManager?
For obvious reasons, global broadcasts must never contain sensitive information. You can, however, broadcast such information locally using the LocalBroadcastManager class, which is a part of the Android Support Library.
The LocalBroadcastManager is much more efficient as it doesn’t need inter-process communication.
Below are some of its benefits:
- Broadcast data won’t leave your app, so don’t need to worry about leaking private data.
- It is not possible for other applications to send these broadcasts to your app, so you don’t need to worry about having security holes they can exploit.
- It is more efficient than sending a global broadcast through the system.
- No overhead of system-wide broadcast.
Implementation
There is no additional support library dependency required in the latest version of Android Studio. However, if you want to implement local broadcasts in an old project, following dependency needs to be add in the app module’s build.gradle file:
Create a new instance of the LocalBroadcastManager
You can now send local broadcasts using the sendBroadcast() method like
Now create a broadcast receiver that can respond to the local-broadcast action:
Dynamically registered receivers must be unregistered when they are no longer necessary like:
You can find the reference code to implement Local Broadcast receiver from GitHub. In the sample code I have created an IntentService, which broadcasts current date and it is received by an Activity of the same application.
How to secure broadcasts
Restrict your app to receive broadcast
- Specify a permission parameter when registering a broadcast receiver then only broadcasters who have requested the permission can send an Intent to the receiver.
For example, receiving app has a declared SEND_SMS permission in the receiver as shown below:
- Set the android:exported attribute to “false” in the manifest. This restrict to receive broadcasts from sources outside of the app.
- Limit yourself to only local broadcasts with LocalBroadcastManager.
Control receiver of your broadcast
- You can specify a permission when sending a broadcast then only receivers who have requested that permission can receive the broadcast. For example, the following code sends a broadcast:
- In Android 4.0 and higher, you can specify a package with setPackage(String) when sending a broadcast. The system restricts the broadcast to the set of apps that match the package.
- Send local broadcasts with LocalBroadcastManager.
Conclusion
Hope you understand about the global and local broadcasts and their security consideration. To improve the performance of system Android O has changed the registration of broadcast receiver. From Android O you cannot register implicit broadcasts in your application manifest (few exceptions is there) but application can continue to register for explicit broadcasts in their manifests or at run-time. Read more on broadcast receiver at Android official document.
Thanks for reading. To help others please click ❤ to recommend this article if you found it helpful. Stay tuned for upcoming articles. For any quires or suggestions, feel free to hit me on Twitter Google+ LinkedIn
Check out my blogger page for more interesting topics on Software development.
Источник
Broadcasts overview
Android apps can send or receive broadcast messages from the Android system and other Android apps, similar to the publish-subscribe design pattern. These broadcasts are sent when an event of interest occurs. For example, the Android system sends broadcasts when various system events occur, such as when the system boots up or the device starts charging. Apps can also send custom broadcasts, for example, to notify other apps of something that they might be interested in (for example, some new data has been downloaded).
Apps can register to receive specific broadcasts. When a broadcast is sent, the system automatically routes broadcasts to apps that have subscribed to receive that particular type of broadcast.
Generally speaking, broadcasts can be used as a messaging system across apps and outside of the normal user flow. However, you must be careful not to abuse the opportunity to respond to broadcasts and run jobs in the background that can contribute to a slow system performance, as described in the following video.
About system broadcasts
The system automatically sends broadcasts when various system events occur, such as when the system switches in and out of airplane mode. System broadcasts are sent to all apps that are subscribed to receive the event.
The broadcast message itself is wrapped in an Intent object whose action string identifies the event that occurred (for example android.intent.action.AIRPLANE_MODE ). The intent may also include additional information bundled into its extra field. For example, the airplane mode intent includes a boolean extra that indicates whether or not Airplane Mode is on.
For more information about how to read intents and get the action string from an intent, see Intents and Intent Filters.
For a complete list of system broadcast actions, see the BROADCAST_ACTIONS.TXT file in the Android SDK. Each broadcast action has a constant field associated with it. For example, the value of the constant ACTION_AIRPLANE_MODE_CHANGED is android.intent.action.AIRPLANE_MODE . Documentation for each broadcast action is available in its associated constant field.
Changes to system broadcasts
As the Android platform evolves, it periodically changes how system broadcasts behave. Keep the following changes in mind if your app targets Android 7.0 (API level 24) or higher, or if it’s installed on devices running Android 7.0 or higher.
Android 9
Beginning with Android 9 (API level 28), The NETWORK_STATE_CHANGED_ACTION broadcast doesn’t receive information about the user’s location or personally identifiable data.
In addition, if your app is installed on a device running Android 9 or higher, system broadcasts from Wi-Fi don’t contain SSIDs, BSSIDs, connection information, or scan results. To get this information, call getConnectionInfo() instead.
Android 8.0
Beginning with Android 8.0 (API level 26), the system imposes additional restrictions on manifest-declared receivers.
If your app targets Android 8.0 or higher, you cannot use the manifest to declare a receiver for most implicit broadcasts (broadcasts that don’t target your app specifically). You can still use a context-registered receiver when the user is actively using your app.
Android 7.0
Android 7.0 (API level 24) and higher don’t send the following system broadcasts:
Also, apps targeting Android 7.0 and higher must register the CONNECTIVITY_ACTION broadcast using registerReceiver(BroadcastReceiver, IntentFilter) . Declaring a receiver in the manifest doesn’t work.
Receiving broadcasts
Apps can receive broadcasts in two ways: through manifest-declared receivers and context-registered receivers.
Manifest-declared receivers
If you declare a broadcast receiver in your manifest, the system launches your app (if the app is not already running) when the broadcast is sent.
To declare a broadcast receiver in the manifest, perform the following steps:
Specify the element in your app’s manifest.
The intent filters specify the broadcast actions your receiver subscribes to.
Subclass BroadcastReceiver and implement onReceive(Context, Intent) . The broadcast receiver in the following example logs and displays the contents of the broadcast:
Kotlin
The system package manager registers the receiver when the app is installed. The receiver then becomes a separate entry point into your app which means that the system can start the app and deliver the broadcast if the app is not currently running.
The system creates a new BroadcastReceiver component object to handle each broadcast that it receives. This object is valid only for the duration of the call to onReceive(Context, Intent) . Once your code returns from this method, the system considers the component no longer active.
Context-registered receivers
To register a receiver with a context, perform the following steps:
Kotlin
Kotlin
Context-registered receivers receive broadcasts as long as their registering context is valid. For an example, if you register within an Activity context, you receive broadcasts as long as the activity is not destroyed. If you register with the Application context, you receive broadcasts as long as the app is running.
To stop receiving broadcasts, call unregisterReceiver(android.content.BroadcastReceiver) . Be sure to unregister the receiver when you no longer need it or the context is no longer valid.
Be mindful of where you register and unregister the receiver, for example, if you register a receiver in onCreate(Bundle) using the activity’s context, you should unregister it in onDestroy() to prevent leaking the receiver out of the activity context. If you register a receiver in onResume() , you should unregister it in onPause() to prevent registering it multiple times (If you don’t want to receive broadcasts when paused, and this can cut down on unnecessary system overhead). Do not unregister in onSaveInstanceState(Bundle) , because this isn’t called if the user moves back in the history stack.
Effects on process state
The state of your BroadcastReceiver (whether it is running or not) affects the state of its containing process, which can in turn affect its likelihood of being killed by the system. For example, when a process executes a receiver (that is, currently running the code in its onReceive() method), it is considered to be a foreground process. The system keeps the process running except under cases of extreme memory pressure.
However, once your code returns from onReceive() , the BroadcastReceiver is no longer active. The receiver’s host process becomes only as important as the other app components that are running in it. If that process hosts only a manifest-declared receiver (a common case for apps that the user has never or not recently interacted with), then upon returning from onReceive() , the system considers its process to be a low-priority process and may kill it to make resources available for other more important processes.
For this reason, you should not start long running background threads from a broadcast receiver. After onReceive() , the system can kill the process at any time to reclaim memory, and in doing so, it terminates the spawned thread running in the process. To avoid this, you should either call goAsync() (if you want a little more time to process the broadcast in a background thread) or schedule a JobService from the receiver using the JobScheduler , so the system knows that the process continues to perform active work. For more information, see Processes and Application Life Cycle.
The following snippet shows a BroadcastReceiver that uses goAsync() to flag that it needs more time to finish after onReceive() is complete. This is especially useful if the work you want to complete in your onReceive() is long enough to cause the UI thread to miss a frame (>16ms), making it better suited for a background thread.
Kotlin
Sending broadcasts
Android provides three ways for apps to send broadcast:
- The sendOrderedBroadcast(Intent, String) method sends broadcasts 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.
- The sendBroadcast(Intent) method sends broadcasts to all receivers in an undefined order. This is called a Normal Broadcast. This is more efficient, but means that receivers cannot read results from other receivers, propagate data received from the broadcast, or abort the broadcast.
- The LocalBroadcastManager.sendBroadcast method sends broadcasts to receivers that are in the same app as the sender. If you don’t need to send broadcasts across apps, use local broadcasts. The implementation is much more efficient (no interprocess communication needed) and you don’t need to worry about any security issues related to other apps being able to receive or send your broadcasts.
The following code snippet demonstrates how to send a broadcast by creating an Intent and calling sendBroadcast(Intent) .
Kotlin
The broadcast message is wrapped in an Intent object. The intent’s action string must provide the app’s Java package name syntax and uniquely identify the broadcast event. You can attach additional information to the intent with putExtra(String, Bundle) . You can also limit a broadcast to a set of apps in the same organization by calling setPackage(String) on the intent.
Note: Although intents are used for both sending broadcasts and starting activities with startActivity(Intent) , these actions are completely unrelated. Broadcast receivers can’t see or capture intents used to start an activity; likewise, when you broadcast an intent, you can’t find or start an activity.
Restricting broadcasts with permissions
Permissions allow you to restrict broadcasts to the set of apps that hold certain permissions. You can enforce restrictions on either the sender or receiver of a broadcast.
Sending with permissions
When you call sendBroadcast(Intent, String) or sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) , you can specify a permission parameter. Only receivers who have requested that permission with the tag in their manifest (and subsequently been granted the permission if it is dangerous) can receive the broadcast. For example, the following code sends a broadcast:
Kotlin
To receive the broadcast, the receiving app must request the permission as shown below:
You can specify either an existing system permission like SEND_SMS or define a custom permission with the
element. For information on permissions and security in general, see the System Permissions.
Receiving with permissions
If you specify a permission parameter when registering a broadcast receiver (either with registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) or in tag in your manifest), then only broadcasters who have requested the permission with the tag in their manifest (and subsequently been granted the permission if it is dangerous) can send an Intent to the receiver.
For example, assume your receiving app has a manifest-declared receiver as shown below:
Or your receiving app has a context-registered receiver as shown below:
Kotlin
Then, to be able to send broadcasts to those receivers, the sending app must request the permission as shown below:
Security considerations and best practices
Here are some security considerations and best practices for sending and receiving broadcasts:
If you don’t need to send broadcasts to components outside of your app, then send and receive local broadcasts with the LocalBroadcastManager which is available in the Support Library. The LocalBroadcastManager is much more efficient (no interprocess communication needed) and allows you to avoid thinking about any security issues related to other apps being able to receive or send your broadcasts. Local Broadcasts can be used as a general purpose pub/sub event bus in your app without any overheads of system wide broadcasts.
If many apps have registered to receive the same broadcast in their manifest, it can cause the system to launch a lot of apps, causing a substantial impact on both device performance and user experience. To avoid this, prefer using context registration over manifest declaration. Sometimes, the Android system itself enforces the use of context-registered receivers. For example, the CONNECTIVITY_ACTION broadcast is delivered only to context-registered receivers.
Do not broadcast sensitive information using an implicit intent. The information can be read by any app that registers to receive the broadcast. There are three ways to control who can receive your broadcasts:
- You can specify a permission when sending a broadcast.
- In Android 4.0 and higher, you can specify a package with setPackage(String) when sending a broadcast. The system restricts the broadcast to the set of apps that match the package.
- You can send local broadcasts with LocalBroadcastManager .
When you register a receiver, any app can send potentially malicious broadcasts to your app’s receiver. There are three ways to limit the broadcasts that your app receives:
- You can specify a permission when registering a broadcast receiver.
- For manifest-declared receivers, you can set the android:exported attribute to «false» in the manifest. The receiver does not receive broadcasts from sources outside of the app.
- You can limit yourself to only local broadcasts with LocalBroadcastManager .
The namespace for broadcast actions is global. Make sure that action names and other strings are written in a namespace you own, or else you may inadvertently conflict with other apps.
Because a receiver’s onReceive(Context, Intent) method runs on the main thread, it should execute and return quickly. If you need to perform long running work, be careful about spawning threads or starting background services because the system can kill the entire process after onReceive() returns. For more information, see Effect on process state To perform long running work, we recommend:
- Calling goAsync() in your receiver’s onReceive() method and passing the BroadcastReceiver.PendingResult to a background thread. This keeps the broadcast active after returning from onReceive() . However, even with this approach the system expects you to finish with the broadcast very quickly (under 10 seconds). It does allow you to move work to another thread to avoid glitching the main thread.
- Scheduling a job with the JobScheduler . For more information, see Intelligent Job Scheduling.
Do not start activities from broadcast receivers because the user experience is jarring; especially if there is more than one receiver. Instead, consider displaying a notification.
Content and code samples on this page are subject to the licenses described in the Content License. Java is a registered trademark of Oracle and/or its affiliates.
Источник