如何从另一个Android应用程序启动Android服务

Paw*_*lov 18 android android-intent

我在从另一个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
Run Code Online (Sandbox Code Playgroud)

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

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); }
Run Code Online (Sandbox Code Playgroud)

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

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

我没有关于服务的意图过滤器,我不想设置一个,我真的想要了解我做错了什么,通过它的组件名称启动它,或者什么可能使它不可能这样做.

Dav*_*ser 45

你应该能够像这样开始你的服务:

Intent i = new Intent();
i.setComponent(new ComponentName("com.xxx.yyy", "com.xxx.yyy.SyncService"));
ComponentName c = ctx.startService(i);
Run Code Online (Sandbox Code Playgroud)

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

  • 嗨,`i.setComponent(new ComponentName("com.xxx.yyy",".SyncService"));`不起作用.只有完全限定名称才能工作`i.setComponent(new ComponentName("com.xxx.yyy","com.xxx.yyy.SyncService"));`,请更新. (10认同)
  • @VenomVendor谢谢你.我更新了答案. (2认同)
  • 要添加它,如果应用程序和服务在不同的包中,代码应该是i.setComponent(new ComponentName("app.package","service.package")); (2认同)
  • @Vinayaka 实际上没有。`new ComponentName()` 的第一个参数是**`Service`** 的包名,第二个参数是**`Service`** 的完全限定类名。 (2认同)

小智 6

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

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

<queries>
        <package android:name="com.example.service.owner.app" />
</queries>
Run Code Online (Sandbox Code Playgroud)

或许可

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
Run Code Online (Sandbox Code Playgroud)

有关包可见性更改的更多信息请参见此处