21

我在从另一个 Android 应用程序 (API 17) 启动服务时遇到问题。但是,如果我确实从 shell 运行“am”,则服务可以正常启动。

# 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

因此,当我在代码中执行相同操作时,看起来我并没有遗漏任何意图:

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); }

我得到的是(当时服务没有运行):

E/tag( 4026): failed to start with Intent { 
act=android.intent.action.MAIN 
cat=[android.intent.category.LAUNCHER] 
cmp=com.xxx.yyy/.SyncService }

我在服务上没有意图过滤器,我不想设置一个,我真的想了解我在通过其组件名称启动它时做错了什么,或者是什么可能导致无法这样做。

4

3 回答 3

54

您应该能够像这样启动您的服务:

Intent i = new Intent();
i.setComponent(new ComponentName("com.xxx.yyy", "com.xxx.yyy.SyncService"));
ComponentName c = ctx.startService(i);

如果您指定特定组件,则无需设置 ACTION 或 CATEGORY。确保您的服务在清单中正确定义。

于 2013-06-27T17:38:26.663 回答
2

像这样开始你的服务

Intent intent = new Intent();
intent.setComponent(new ComponentName("pkg", "cls"));
ComponentName c = getApplicationContext().startForegroundService(intent);

顺便说一句,您实际上需要使用 applicationId,而不是 pkg。它可以在应用程序 gradle 中找到。我为这个错误苦苦挣扎了好几个小时!

   defaultConfig {
        applicationId "com.xxx.zzz"
}

cls 是清单中声明的​​服务的名称。例如:com.xxx.yyy.yourService。

 <service android:name="com.xxx.yyy.yourService"
android:exported="true"/>
于 2019-04-10T09:09:24.740 回答
1

作为 David Wasser 的回答以使其在针对 API 30 及更高版本时工作的补充,您还必须添加:

清单中查询标记中的必需包名称:

<queries>
        <package android:name="com.example.service.owner.app" />
</queries>

或许可

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

此处有关包可见性更改的其他信息

于 2021-12-01T12:44:01.170 回答