When to use BroadcastReceiver for non-cross-application communication? - android

Are there any use cases in which I would want to use a BroadcastReceiver for something other than cross-application communication?
After reading the documentation, it seems like they are targeted at cross-application communication, but the idea of using them with the LocalBroadcastManager is also mentioned. I also read this post, which addresses the general usage of broadcast receivers. Neither seem to hit clearly on why it would be useful to use broadcasts and receivers for anything other than cross-application communication.
Does it have anything to do with their asynchronous nature, or maybe they're just used to move some processing out of the main activity?
Clarification: I guess the term cross-application was too general. I was considering the built-in actions such as
android.hardware.action.NEW_PICTURE
to be coming from applications. What I would like to know is: when is it useful to use a BroadcastReceiver for communication within my app - I guess this would narrow it down to custom intent actions/categories. Sorry if the way I'm asking this is confusing. I've only just recently begun programming with Android and I still don't understand the OS very well.

As it quotes in the post you linked: "A broadcast receiver is a component that responds to system-wide broadcast announcements. Many broadcasts originate from the system."
Therefore, they are useful in "catching" system broadcasts, e.g., when the device has booted up, when the battery level changes, when your Wi-Fi has been turned on, etc.
Personally, I've used a BroadcastReceiver to start my app whenever the device receives a text message. In my case, this is preferred, as my app does not need to be running when the text message is received. Upon receipt, the system will broadcast an intent with an SMS_RECEIVED action. My BroadcastReceiver component, registered to accept this particular type ofbroadcast, will be notified and can then react as needed. In my case, it launches an Activity to notify the user of the text message and choose a particular reply text message.
This is just a specific example. There are many other broadcasts that the system transmits and your Receiver can get. Check this link and this post for more examples.
Clarification:
A LocalBroadcastManager is preferable in instances when you want rather simple way to communicate between app components without an intent being broadcast system-wide. Knowing this, you would want to go this route when the info you're passing is to be used only by your app. A LocalBroadcastManager is more efficient, generally simpler than using an IBinder interface, and can ensure that information isn't leaving your app.
For an example, suppose you have a Service that runs in the background to track and log some constantly changing data; let's say your battery level. The Service can run on its own without user interaction, saving the battery level to the disk as it changes. When you start your activity to view said data, it would use LocalBroadcastManager to register a receiver to accept the info the Service is sending, and update the Activity's UI in real time to reflect this. Since no other app needs the info from your Service, it's better to do this than broadcasting an intent to which any other app could have access.
To sum up, using a LocalBroadcastManager is:
More efficient.
More secure.
Simpler.

Related

Run something in one application from another

(The title is a bit weird because the words "code" and "app" are apparently forbidden in question titles.)
I have two Android apps, one is a normal unprivileged app and one is a system app with the permission to shut down the system. From my normal app I want to initiate the shutdown. I know the package name and I have full control over both apps. Both are signed with the same key.
What is the most concise way to run code in one app from another?
One way would be a Service that I can then start with intent.setComponent(...); startService(intent), but being a Service implies some background activity is going on, which isn't in my case.
Another way would be a BroadcastReceiver but that doesn't allow me to target a specific component, it requires an identifier whose purpose is conceptually to be received by other apps as well.
Is there another way with better fitting semantics?
but being a Service implies some background activity is going on, which isn't in my case.
Service using AIDL is simply an inter-process communication (IPC) mechanism. What the recipient of that communication does in response to that communication is up to it.
Besides, you have some background activity going on. You wrote:
From my normal app I want to initiate the shutdown
Shutting down a device is "background activity", at least in my interpretation of the expression.
Another way would be a BroadcastReceiver but that doesn't allow me to target a specific component
Sure it does. You can use setComponent() on a broadcast Intent the same way that you do for binding to a Service, or starting a Service, or starting an Activity.
There are downsides of using setComponent(), notably a dependency between the two code bases. Basically, the ComponentName becomes part of the API contract, and since that maps to a Java class name, you are limited in your ability to refactor that class (new name, new package). However, there's nothing stopping you from using setComponent().
For example, I describe using setComponent() for a broadcast in this blog post. In that case, I am deriving the ComponentName values via PackageManager, but that's just in service of this specific example.
Is there another way with better fitting semantics?
For a single interaction, "fire and forget" sort of thing, where you are not looking for any sort of acknowledgment, I'd send an explicit broadcast (i.e., a broadcast of an Intent that uses the ComponentName to identify the recipient). And I'd definitely use a signature-level permission to secure it.
While CommonsWare's answer is excellent and the explicit broadcast with a custom permission is usually the way to go, in this particular case I ran into an issue.
Apps cannot receive broadcasts until they have started an activity because until then they remain in "stopped" state. So an app with only a BroadcastReceiver won't work.
And since I need to have an activity anyway, I put the shutdown code in the activity.

Android controlling service with different applications

I have an app with an auto log out feature where I was using a Timer to auto log out the user (where user is a static singleton object).
Recently I realized there were some other activities and I have to implement a global log out feature so I tried to implement different Timers to each Activities and tried to synchronize them, but it wasn't a good approach and it was a pain. Then I turned my face to the services.
What I need to know is a good way to control a single service within different applications. Any ideas will be appreciated.
You can implement bound service, start it, and bind it with two activities.
More information You can find in official developer docs this and this
you can implement a "Bound" service to interact it from different activities.
Here is complete example for Bound service with explanation.
http://developer.android.com/guide/components/bound-services.html
A broadcast is a message that any app can receive. The system delivers
various broadcasts for system events, such as when the system boots up
or the device starts charging. You can deliver a broadcast to other
apps by passing an Intent to sendBroadcast(), sendOrderedBroadcast(),
or sendStickyBroadcast().
All that you need to do is to create BroadcastReceiver. Add IntentFilter for it. Register it in your Service. And than send Intent with action that you add to IntentFilter from any of your Applications.
Go throw this article to get better understanding of Intents

Design approach to use in Android when several activities need to connect to a service

I have a class that starts a Bluetooth reading thread and another that receives/decodes what's read from that port and produces some output logs depending on the information read.
In my design, those 2 components form a service for my application (multiple activities) from where I would like to start/stop getting the output logs on a continuous basis (typical frequency of 2-3 logs per second).
My questions:
1) Should I derive from Service or IntentService. The doc says about IntentService: "This is the best option if you don't require that your service handle multiple requests simultaneously". This may be my case since the main activity will start/stop the service...
2) What would be the appropriate way to catch the service events? Does the BroadcastReceiver is appropriate for this type of communication?
3) I may need to occasionally send some stuff to the Bluetooth port. So, I'll have to pass information from my application to the service. Does the PendingIntent should be used for that?
Thank you!
Should I derive from Service or IntentService
IntentService is designed for discrete tasks, not stuff that would run indefinitely until the user manually stops it. I would use Service.
What would be the appropriate way to catch the service events? Does the BroadcastReceiver is appropriate for this type of communication?
That is certainly one approach. You might use the LocalBroadcastManager from the Android Support package to reduce overhead and keep everything private to your app. Have your activities register a receiver in onResume() and remove it in onPause(). The foreground activity will then be notified of events.
I may need to occasionally send some stuff to the Bluetooth port. So, I'll have to pass information from my application to the service. Does the PendingIntent should be used for that?
No, I would have the activity simply send a command to the service via startService(), with the data to be passed included in extras on the Intent. If you have data that cannot be packaged as extras, you may need to consider binding to the service, so you can get a richer API, though this makes configuration changes more annoying.

Android - Going from Binders to Broadcasts

I started with a standard local android service, and used Binders with Listeners to communicate. Then: I began noticing some serious issues with handling orientation changes, so I decided to skip the whole binder thing, and just go with broadcasting intents (and using startService exclusively) that contain all the data/commands that need to be passed.
My question is: what are some of the pitfalls I have to look out for when using this approach?
Are there any disadvantages?
If you are supporting API Level 4 and above, use setPackage() to make your "broadcast" be a "narrowcast" -- keeping the broadcast within your app. By default, the broadcast is truly broadcast, to all apps, which may or may not be a good thing for your data.
Don't forget to unregister your BroadcastReceiver (i.e., don't register it and forget it). At the same time, you will need to consider what to do if the service wraps up and the activity is long gone (e.g., BACK button). One approach is to use an ordered broadcast with a low-priority manifest-registered receiver that will raise a Notification if no activity handles the broadcast -- this sample app demonstrates what I mean.
You might consider a Messenger instead of the broadcast approach, as it is intrinsically a "narrowcast", probably is a smidge less overhead, and can't be leaked. I am still working through the mechanics of using this with configuration changes, though.

Design suggestion required

I want to create an application in which
- Create a listener which listens for outgoing/incoming messages and calls
- UI is shown/hide based on listener results
Shrini,
As dds stated, you will definitely need at least two BroadcastReceivers. You will need one BroadcastReceiver for each incoming call and message that you want to respond to, and one for each outgoing one as well. A BroadcastReceiver may only capture one BroadcastMessage at a time. You will specifically need to capture the Intents sent by the operating system and your Application will need to have the appropriate Permissions for each. That's just setting up the listeners.
Once the BroadcastReceiver has been called you will need to start an Activity for you UI and possibly a Service to do any other processing. In the cases of single-point events (like messages) an Activity is often enough. Calls, however, depend largely upon what you are doing. Since a call has two distinct events, in order to tie them together, many people prefer to use a Service just to hold and watch the call.
In order to best help you, I must inform you that your question is remarkably vague as to what you need to do. Does your custom UI display information about the calls? Does it allow the User to respond or change that information? What kind of messages is your app responding to? SMS? Email? IMs? These are important because each one has different considerations.
Given that the limitation of information provided here, I would recommend researching your topic by downloading and viewing some of the open source projects stored on Google. Here is a Here.
Fuzzical Logic
Create a listener which listens for
outgoing/incoming messages and calls -
UI
To achieve this I think you need to use broadcast receivers to catch the broadcast message when any message activity is going on. You may need 2 in BroadcastReceivers , one for incoming and one for outgoing messages.
In the receivers you need to call your related Activity (your UI) to interact with the user. But note that you should not do any time consuming work in BroadcastReceiver since in BroadcastReceivers are expected to be light weight and killed in 10 seconds after they are invoked. See Broadcast receivers at here

Categories

Resources