Run something in one application from another - android

(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.

Related

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

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

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.

Seeking laymans explaination of the pending intent concept

This is a pretty stale question but frankly I'm yet to find it answered in a way that satisfies my curiosity.
Before you, dear reader, leap to the android developer reference to paste me the text, please be aware that I've already read the Intent / Pending Intent documentation and am yet to resolve my confusion.
It strikes me that the Intent model is core to the android system and as such is highly generic. It is because of this that the examples I have seen of its usage tend to be many and varied. This variation obfuscates the concepts I am trying to learn and that is frustrating.
My questions are simply written but perhaps tough to explain in simple terms. I understand that an intent is a message to other activities and that other activities can declare their interest in their manifest. Pending intent, a wrapper for intent, confuses me.
I see documentation referring to permissions and token. I get that, but why is pending intent needed as a separate entity - what behavior does it enable?
What activity / task lifecycle behaviour do pending intents cause?
When is a broadcast receiver required?
What are a broadcast receiver's limitations?
I realise these are seriously newb questions (which I am) but I desperately want to understand these core concepts so I don't have to rely on example / guides / official docs as much.
Any feedback is welcome folks. Thanks.
The main purpose of a PendingIntent is to give another application written permission to do something in your stead. Applications are restricted in what they are allowed to do by, essentially, these two factors:
Visibility. Components like Services or Activities that aren't provided with a publicly visible (or any) intent-filter cannot be called by other applications. They can only be called by your application using explicit intents specifying their package and class name.
Permissions. Each application can request a certain amount of permissions. Those are mostly predefined permissions, but you do have the option to define your own permissions as well, though I never used that. Your application cannot do anything that exceeds those permissions.
Now, with pending intents, you can get past both of those restrictions, if an application that has the required permissions and visibility to do something specifically allows you to do it in her stead. An application could allow you to call one of her private Activities for example, if it gives you a pending intent that contains an explicit intent for said activities.
[edit]
They are used with the alarm manager, for example. It tells the alarm manager what and when to do by giving it a (pending) intent. Since your application probably won't be there any more when the time arrives, the alarm manager will have to send it for you. That would mean that those intents could only do what the alarm manager is allowed to do, not what your application is allowed to do. If the alarm manager was allowed to simply do anything, every application could do anything by using the alarm manager as a proxy. So you have to use pending intents to specifically grant the alarm manager the rights it needs for your particular intent.[/edit]
Apart from that, there isn't too much of a difference to regular intents, at least as far as usage is concerned. It does get a bit more complicated with sticky intents etc, but that's the general gist of it, at least as far as I know.
A broadcast receiver is required when you want to react to certain system events, or events of other applications. A broadcast receiver is invisible, it doesn't create any form of view and doesn't involve any form of user interaction. The advantage is that this can happen irregardless of whether your application (or rather, your activities) are currently running or not.
A broadcast receiver is only granted about 10 seconds to do stuff, after that it gets killed by the system. So if you want to perform any kind of long running processes you'll have to use a background service, or open up an Activity to let your users do stuff.

Android independent services how to?

I was wondering if there is a way to create a service that will run as it's own process independent of an activity. I would want to service to run in the foreground so it would not be killed and also accessible to other .apk that wish to use it. How can I do this? I've read so much that its made me a little more confused then I initially was. Any help would be much appreciated.
To clarify. I would like to run a service that can communicate with many .apk's. It is an in-house application with no market value. What I am trying to do is make service that .apk can register there content providers with so all .apk's using this service have a list of all other .apk's content providers to use as pleased.
Services are by their nature independent of Activities. You don't need one to run the other. Services always run in the background and usually don't get killed unless they take too many resources.
Depending on the type of interaction you want between the Service and Activities you'll need to define the appropriate intents or maybe use a ContentProvider.
UPDATE:
In the case you described above, simply have each content provider register with service using an intent that specifies the URI needed to access that content provider. The service would then keep a list of all registered content providers and their URI's.
When a new activity wants to get a list of all available ContentProviders it can query the service with an intent asking for a list of providers. The service would then respond with an intent that would contain the list of providers and URIs.
Using this information the individual activities could then decide which content providers they want to interact with.
How can I do this?
You don't, insofar as you do not need it to be "as it's own process". Just start up the service via startService() and have the service call startForeground(). It can be part of the same process as the activity, and the user will be able to navigate away from that activity if desired and the service will remain running.
I would want to service to run in the foreground so it would not be killed
Note that users are still welcome to get rid of your service. startForeground() will reduce the odds of Android getting rid of the service on its own.

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.

Categories

Resources