How to achieve the LocalBroadcastManager functionality using the normal broadcasts programmatically without keeping any thing in the manifest. My goal is to limit my broadcast scope to my own application.
To broadcast an Intent within your application's context then LocalBroadcastManager is the safest way to do it. However, if you want to achieve the similar functionality via ordinary broadcast procedures then you may explicitly define a package which should listen your broadcast. For example:
Intent intent = new Intent("com.abc.my_action");
intent.setPackage("com.package.other"); //Set an explicit application package
sendBroadcast(intent);
This restriction for broadcasts is available in ICS and onwards. For more info read this.
P.S. I would still recommend you to stick with LocalBroadcastManager as it broadcasts intents within your application's context and is considered to be the safest.
Related
I understand the basic difference between the two types of intent registering.
But i want to know is there any difference in terms of speed??
Registering broadcast from code and through manifest doesn't have much difference except these points mentioned in the documentation:
1)When you use registerReceiver(BroadcastReceiver, IntentFilter), any application may send broadcasts to that registered receiver. You can control who can send broadcasts to it through permissions described below.
2)When you publish a receiver in your application's manifest and specify intent-filters for it, any other application can send broadcasts to it regardless of the filters you specify. To prevent others from sending to it, make it unavailable to them with android:exported="false".
Read more in developer documentations: http://developer.android.com/reference/android/content/BroadcastReceiver.html
You can use them based on your requirement.
The BroadcastReceiver class (when launched as a component through a manifest's tag) is an important part of an application's overall lifecycle.
If you registerRecevier in onResume method in activity and unregisterReceiver in onPause() method. Your receiver life time is this activity life time.
I need to know if there is a way to obtain the intent filter of an applicaction (activity) and the actual name of the application as we see it on the android launcher screen, through a broadcast it sends to a service.
The service receives the broadcast through its broadcast receiver, then it needs to know the applicatione's name and its intent filter in order to do some work with that information. Is there a way to find this out through the intent, or does the application need to actually putextras in the intent?
Is there a way to find this out through the intent
Not really, insofar as the Intent has no information about the Intent's origination point.
does the application need to actually putextras in the intent?
Yes, because only the originator of the broadcast knows what is appropriate to be used. After all, an app may have zero, one, or many launcher activities.
You're welcome to try the getCallingUid() and/or getCallingPid() static methods on Binder, to try to automatically derive who the sender is, but this may not work well if there are multiple apps that are using sharedUserId on the device.
I'm coming up to speed on Android development and the distinction between an implicit intent and a broadcast receiver is unclear. I was hoping for help in distinguishing these concepts and when to use the two.
Both receive intents, both react to system messages, so why is a broadcast receiver even needed and when is it used as opposed to an implicit intent and intent filter to accept the implicit intent?
Broadcasts are just that -- messages broadcast to anyone listening. They are inherently insecure, and delivery to the intended recipient isn't guaranteed, because there really isn't an intended recipient. For example, the CONNECTIVITY_CHANGE broadcast makes this quite clear: When connectivity changes in an Android device, many apps might be interested. Rather than the ConnectivityManager having to notify each app via specific Intent, it sends a broadcast. Any app that has registered interest in this event will be notified. Any app that isn't running or doesn't care... won't.
An Intent is "sent" when one app or Activity wants to launch another to do something very specific. For example, a file-manager might want to launch an image viewer or video player. Your app might want to launch a very specific Activity within another one of your apps, etc. The communication by specific intents (i.e. including package name and component name) can not easily be intercepted, so it's somewhat more secure. Most importantly, there's only and exactly one "receiver" -- if none can be found, the Intent will fail.
Further, a BroacastReceiver will be active within an Activity or Service and received broadcasts will generally only change state and/or do minor UI updates... for example, you might disable a few actions if your internet connectivity is dropped. By comparison, a specific Intent will usually launch a new Activity or bring an existing one to the foreground.
I am going to compile a list here of all the differences between Implicit Intents (sent via startActivity()) and Broadcasts (sent via sendBroadcast())
Broadcasts, by default, can affect multiple applications at once (Ordered Broadcasts have the potential to be disrupted). In contrast, Implicit Intents will only affect one application. Please note that there may be multiple possibilities of applications that could be affected, but eventually only one will be.
Implicit Intents are handled via Intent-Filters, and Broadcasts are handled via Broadcast Receivers (albeit the intent-filters play a role here too). I have seen in many instances over the web that Broadcasts are compared to Intent-filters and that does not make sense to me.
An Implicit Intent launches an Activity, or a Service. By contrast, a Broadcast launches a Broadcast Receiver. (This, if you think about it, is the core difference between Intents and Broadcasts. It is because of this reason that Broadcasts aren't meant to do too much heavy work, and especially not UI work!)
From the Developers Website:
There is no way for a BroadcastReceiver to see or capture Intents used
with startActivity(); likewise, when you broadcast an Intent, you will
never find or start an Activity. These two operations are semantically
very different: starting an Activity with an Intent is a foreground
operation that modifies what the user is currently interacting with;
broadcasting an Intent is a background operation that the user is not
normally aware of.
I'll add more if I find anything else.
I wondering if it is possible to create a private broadcast.
I actually register broadcastreceiver in my activity and use
sendOrderedBroadcast(broadcast);
method to send the broadcast.
But, for now, the intent (broadcast) used for this method is defined like this :
Intent broadcast = new Intent("com.mypackage.broadcast");
So every external application which declare this package name can listen what I am sending, and I don't want to.
So how to make this impossible, that no one can listen my broadcast ?
I think you are looking for LocalBroadcast Manager. The docs say:
It is a helper to register for and send broadcasts of Intents to local objects within your process. This is has a number of advantages over sending global broadcasts with sendBroadcast(Intent). One of them is that the data you are broadcasting won't leave your app, so don't need to worry about leaking private data.`
See how to use LocalBroadcastManager? for more. Hope it helps you.
For LocalBroadcast Manager to work the app should be running.
To have a generic strategy to limit Android broadcasts to your own app only, we can do as follow.
Intent intent = new Intent();
String packageName = context.getApplicationContext().getPackageName();
intent.setAction(packageName + "<MY_ACTION>");
context.sendBroadcast(intent);
Since the application package would remain unique for all apps on android, this would safely limit the Broadcast to your own app and you can register BroadcastReceivers in AndroidManifest.xml.
I want to use sendBroadcast to broadcast an intent that can only be received by that application that originated it.
The use case is for an authentication module I'm planning to use between several projects I've built. Currently when a 401 (authorization failed) response code is received it broadcasts an intent that can then be wired in the manifest to bring the user back to the login page.
So just to be clear I'm wondering if I can do this:
Intent i = new Intent("my.custom.logout.broadcast.path.that.will.be.the.same.in.multiple.apps");
sendBroadcast(i);
And somehow the intent doesn't get picked up by other apps that use exactly the same un-modified code base.
Not part of the question, but you should be using permissions for restricting who can send/receive the Broadcasts, especially since you're dealing with authentication. In fact, I would highly recommend looking into the AccountManager (in API demos)
Moving on.. one solution is to pass the originating application's package name or a particular permission string in an Intent extra, and when you respond, use that package name or permission in the response, the same way. Unfortunately you can't target a specific package in a Broadcast Intent.
Yet another solution, is using PendingIntent.getActivity() from the originating application, stuff that PendingIntent into the new for-broadcast Intent as an extra (Intent#putExtra()) and broadcast it using the permissions model above (so sender and receiver can handle permissions properly). When the broadcast receiver has finished doing its thing, it can use the PendingIntent to start the target activity (including the ability to attach additional extras)
For this you can use the LocalBroadcastManager, which is specifically designed for in-app communication.