Reputation: 4225
I'm having a problem starting a service from another Android app (API 17). However, if I do run 'am' from the shell, the service starts fine.
# am startservice com.xxx.yyy/.SyncService
Starting service: Intent { act=android.intent.action.MAIN cat=
[android.intent.category.LAUNCHER] cmp=com.xxx.yyy/.SyncService }
(service starts fine at this point)
# am to-intent-uri com.xxx.yyy/.SyncService
intent:#Intent;action=android.intent.action.MAIN;
category=android.intent.category.LAUNCHER;
component=com.xxx.yyy/.SyncService;end
So, it doesn't look like I'm missing anything from the intent when I do the same in the code:
Intent i = new Intent();
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.setComponent(new ComponentName("com.xxx.yyy", ".SyncService"));
ComponentName c = ctx.startService(i);
if (c == null) { Log.e(TAG, "failed to start with "+i); }
What I get is (the service is not running at that time):
E/tag( 4026): failed to start with Intent {
act=android.intent.action.MAIN
cat=[android.intent.category.LAUNCHER]
cmp=com.xxx.yyy/.SyncService }
I don't have an intent filter on the service, and I don't want to set one up, I'm really trying to understand what am I doing wrong starting it through its component name, or what may be making it impossible to do so.
Upvotes: 23
Views: 37046
Reputation: 181
As an addition to David Wasser's answer to make it work when targeting API 30 and above you also have to add either:
Required package name in queries tag in manifest:
<queries>
<package android:name="com.example.service.owner.app" />
</queries>
or permission
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
Additional info on package visibility changes here
Upvotes: 6
Reputation: 171
Start your service like this
Intent intent = new Intent();
intent.setComponent(new ComponentName("pkg", "cls"));
ComponentName c = getApplicationContext().startForegroundService(intent);
btw you actually need to use the applicationId, instead of the pkg. it can be found in the app gradle. I was struggling with that mistake for hours!
defaultConfig {
applicationId "com.xxx.zzz"
}
the cls is the name of your service declared in the manifest. example: com.xxx.yyy.yourService.
<service android:name="com.xxx.yyy.yourService"
android:exported="true"/>
Upvotes: 4
Reputation: 95578
You should be able to start your service like this:
Intent i = new Intent();
i.setComponent(new ComponentName("com.xxx.yyy", "com.xxx.yyy.SyncService"));
ComponentName c = ctx.startService(i);
You don't need to set ACTION or CATEGORY if you are specifying a specific component. Make sure that your service is properly defined in the manifest.
Upvotes: 61