zaxunobi
zaxunobi

Reputation: 940

Starting a service of another Android app into my own app

I am running a service of an android app from the shell with am startservice. All works as it should.

am startservice -a com.anotherdeveloper.app.SERVICE --ef a 1 --ef b 2

I'm wondering if it is possible to start the service of another android app without being the developer? According to this link it's possible: How to start android service from another Android app

But I don't quite get how to do it.

This is the code I'm using in the MainActivity:

Intent intent = new Intent();
intent.setComponent(new ComponentName("com.anotherdeveloper.app", "com.anotherdeveloper.app.SERVICE"));
ComponentName c = getApplicationContext().startForegroundService(intent);

And in the AndroidManifest.xml I've added this:

  <service
        android:name="com.anotherdeveloper.app.SERVICE"
        android:enabled="true"
        android:exported="true" />

But it shows me an error in the manifest because of course Android Studio can't find the package name of this app installed on my phone.


UPDATE

Thanks to @Martin Marconcini, this is the code I'm using:

  Intent intent = new Intent();
  intent.setComponent(new ComponentName("com.anotherdeveloper.app","com.anotherdeveloper.app.SERVICE"));
  intent.putExtra("cty", 4);
  intent.putExtra("stt", 2);
  startService(intent);

And this is the service in the AndroidManifest.xml:

<service name="com.anotherdeveloper.app.General">
  <intent-filter>
    <action name="com.anotherdeveloper.app.SERVICE"/>
  </intent-filter>
  <intent-filter>
    <action name="com.anotherdeveloper.app.SERVICE_ALT"/>
  </intent-filter>
  <intent-filter>
    <action name="com.anotherdeveloper.app.TERMINATE"/>
  </intent-filter>
</service>

Upvotes: 0

Views: 1088

Answers (2)

Martin Marconcini
Martin Marconcini

Reputation: 27236

Expanding on your question inside the comments:

  1. Yes, you can start the service if it's exported (and you said it was), so it should work.

  2. To pass parameters via Intent, you need to use the "Extras". This is akin to the -e parameter you use in adb shell am.

Intent i = new Intent();
i.putXXX(key, value)

You're going to get a lot of options (for each type) instead of XXX , for e.g.:

int value = 1;
i.putExtra("Key", value)

// or

String value = "X"
i.putExtra("Key", value)

// or

boolean value = true;
i.putExtra("Key", value)

They all work (make the keys unique of course).

Alternatively, you can pass a Bundle that contains a bunch.

        Bundle b = new Bundle();
        b.putString("x", "value");
        b.putInt("x", 1);
        b.putBoolean("x", true);

        Intent i = new Intent();
        i.putExtra("theBundle", b);

In essence, it's all very Google/Java like, where consistency was not the key. ;)

(of course, if you pass a bundle, the receiver must know this so it can "get the bundle" out of extras, and then extract each key/value.

Put it differently, a Bundle is a glorified Dictionary that supports different types and where all things must be Parcelable. So it's a key/value store that must be parcelable.

Intent data size (for extras) has a limit of X (can't remember if it's 1mb or what) but you can't just serialize 1 terabyte of information and toss it via intent. Keep that in mind.

Upvotes: 1

ror
ror

Reputation: 3500

Short answer: it solely depends on 3rd party decision (what service creators wrote in corresponding android:exported)

More details here: https://developer.android.com/guide/topics/manifest/service-element

Upvotes: 1

Related Questions