Home > Blockchain >  Run something in one application from another
Run something in one application from another

Time:12-24

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

CodePudding user response:

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.

  • Related