如何在 adb shell 中启动和停止 Android 服务?

73
我需要编写一段Shell脚本来启动和停止一个Android服务。

我尝试启动 adb shell whatsapp 备份,但是我找不到与 WhatsApp 备份服务相似的 service (com.whatsapp.backup.google.GoogleBackupService),但没有 com.whatsappactivity。我尝试了各种组合的命令,但是都出现了错误。这是输出结果。由于评论限制,我无法直接在此处放置它。我该如何完成这个任务?“通过 adb 进行 WhatsApp 聊天备份?”https://paste.c-net.org/AlreadyLeveled - user1874594
11个回答

70

我是一个 Android 的新手,但是我这么做让它工作了:

在 AndroidManifest.xml 文件中,确保你在 <application> 标签内部添加以下内容:

<service android:name="com.some.package.name.YourServiceSubClassName" android:permission="com.some.package.name.YourServiceSubClassName">
    <intent-filter>
        <action android:name="com.some.package.name.YourServiceSubClassName"/>
    </intent-filter>
</service>

其中,YourServiceSubClassName是你的Java类,继承了android.app.Servicecom.some.package是包名,在我的AndroidManifest.xml和Java文件中都是如此。

使用a javabeat.net文章进行帮助,查找<service>

请注意,在包名和类名之间可能应该有.service.这一文字,我猜这是某种约定,但这给我造成了ClassNotFoundException的困扰,我还没有解决这个问题。

然后,安装您的apk。我是从eclipse安装的,但也可以使用adb install -r yourApkHere.apk。卸载是adb uninstall com.some.package.name,顺便提一下。

您可以像这样从主机系统启动它,感谢Just a TimMrRoy:

adb shell am startservice com.some.package.name/.YourServiceSubClassName

有趣的是,我不需要-n

停止,我使用

adb shell am force-stop com.some.package.name

我希望能够帮到你。由于我是初学者,如果有任何误解(例如关于组件名称中的.service.),请随时编辑/评论以进行修正。

所以,这就是我为什么会得到这个错误的原因吗?$ am startservice com.adguard.android/.vpn.AdguardVpnService 启动服务:Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.adguard.android/.vpn.AdguardVpnService } 错误:需要 android.permission.BIND_VPN_SERVICE 权限。 - Michele Dall'Agata
我尝试启动 adb shell whatsapp 备份,但是我能找到的最相近的 WhatsApp 备份服务是 com.whatsapp.backup.google.GoogleBackupServiceservice,但是没有适用于 com.whatsappactivity。我尝试使用不同组合的命令来操作,但是都出现了错误。这里是输出结果。由于评论限制,我无法在此直接贴出。我该如何完成这个任务?“通过 adb 进行 WhatsApp 聊天备份?”https://paste.c-net.org/AlreadyLeveled - user1874594

26

启动服务:

adb shell am startservice ...

启动服务的选项是: --user | current:指定要作为哪个用户运行;如果未指定,则作为当前用户运行。

停止服务:

adb shell am stopservice ... 

停止一个服务。选项包括: --user | current: 指定要作为哪个用户运行;如果未指定,则作为当前用户运行。

21

使用过程中可能会出现 "*Error: app is in background *" 错误。

adb shell am startservice 

在Oreo(26+)中,这需要在前台运行的服务。请使用以下内容。

adb shell am start-foreground-service com.some.package.name/.YourServiceSubClassName

15
如果您想在adb shell中运行脚本,那么我正在尝试使用应用程序来完成相同的任务。我认为您可以使用"am start"命令。
用法:am [子命令] [选项]
start an Activity: am start [-D] [-W] <INTENT>
    -D: enable debugging
    -W: wait for launch to complete

**start a Service: am startservice <INTENT>**

send a broadcast Intent: am broadcast <INTENT>

start an Instrumentation: am instrument [flags] <COMPONENT>
    -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT)
    -e <NAME> <VALUE>: set argument <NAME> to <VALUE>
    -p <FILE>: write profiling data to <FILE>
    -w: wait for instrumentation to finish before returning

start profiling: am profile <PROCESS> start <FILE>
stop profiling: am profile <PROCESS> stop

start monitoring: am monitor [--gdb <port>]
    --gdb: start gdbserv on the given port at crash/ANR

<INTENT> specifications include these flags:
    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]
    [-c <CATEGORY> [-c <CATEGORY>] ...]
    [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
    [--esn <EXTRA_KEY> ...]
    [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
    [-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
    [-n <COMPONENT>] [-f <FLAGS>]
    [--grant-read-uri-permission] [--grant-write-uri-permission]
    [--debug-log-resolution]
    [--activity-brought-to-front] [--activity-clear-top]
    [--activity-clear-when-task-reset] [--activity-exclude-from-recents]
    [--activity-launched-from-history] [--activity-multiple-task]
    [--activity-no-animation] [--activity-no-history]
    [--activity-no-user-action] [--activity-previous-is-top]
    [--activity-reorder-to-front] [--activity-reset-task-if-needed]
    [--activity-single-top]
    [--receiver-registered-only] [--receiver-replace-pending]
    [<URI>]

11
那个帮助页面真的没有帮助你找出如何指定意图。特别是,<COMPONENT>的语法很神秘。 - pzulw
@pzulw 参考 Just a Tim's answerMrRoy's,并根据 <service> on this link 将内容放入 AndroidManifest.xml 中,问题得以解决。 - n611x007
我尝试启动 adb shell whatsapp 备份,我能找到一个听起来接近 WhatsApp 备份服务的 service (com.whatsapp.backup.google.GoogleBackupService),但没有 com.whatsappactivity。我尝试了各种组合的命令,但都出现了错误。这是输出结果。由于评论限制,我无法直接在此处放置它。我该如何完成这个任务?通过 adb 进行 WhatsApp 聊天备份? https://paste.c-net.org/AlreadyLeveled - user1874594

11
我可以通过什么方式启动服务?
am startservice com.xxx/.service.XXXService

但我还不知道如何停止它。


1
您可以使用广播接收器来停止服务,然后向该接收器发送广播。 - shaobin0604

10

您需要在ADB命令行中添加android:exported="true"才能启动服务。您的清单文件应如下所示:

<!-- Service declared in manifest -->
<service
    android:name=".YourServiceName"
    android:exported="true"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="com.your.package.name.YourServiceName"/>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</service> <!-- Note: Service is exported to start it using ADB command -->

然后从ADB开始:

启动服务:

adb shell am startservice com.your.package.name/.YourServiceName

停止服务(在 Marshmallow 上):

adb shell am stopservice com.your.package.name/.YourServiceName

停止服务(在 Jelly Bean 上):

adb shell am force-stop com.your.package.name


10

要停止服务,您需要使用以下命令查找服务名称:

adb shell dumpsys activity services <your package>

例如: adb shell dumpsys activity services com.xyz.something
这将列出你的包运行的服务。 输出应该类似于:
ServiceRecord{xxxxx u0 com.xyz.something.beta/xyz.something.abc.XYZService}

现在选择您的服务并运行:

adb shell am stopservice <service_name> 

例如:
adb shell am stopservice com.xyz.something.beta/xyz.something.abc.XYZService

类似地,要启动服务:

adb shell am startservice <service_name>

要访问服务,在 AndroidManifest.xml 文件中,你的服务应该设置 exported="true"。

<!-- Service declared in manifest -->
<service
    android:name=".YourServiceName"
    android:exported="true"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="com.your.package.name.YourServiceName"/>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</service>

8

为了允许其他组件调用服务,您应将服务的android:exported属性设置为“true”。在AndroidManifest.xml文件中,添加以下属性:

<service android:exported="true" ></service>

然后,您应该能够通过adb启动服务:
adb shell am startservice com.package.name/.YourServiceName

如果您想了解有关 android:exported 属性的更多信息,请参阅此页面


6

针对pzulw关于在sandroid中指定意图的反馈做出回应。

组件名称的格式在ComponentName.unflattenFromString 的API文档中进行了描述。

它将字符串在第一个“/”处分割,将其前面部分作为包名,将其后面部分作为类名。作为一种特殊的便利(例如用于在命令行上解析组件名称),如果“/”紧接着是一个“.”,那么最终的类名将是包名与紧随“/”后面的字符串连接而成。因此,“com.foo/.Blah”变成了package="com.foo" class="com.foo.Blah"。


2

对于仍然不清楚如何定义服务名称参数的人,正斜杠应紧跟在完全限定类名中应用程序包名称之后。

因此,如果应用程序包名称为:app.package.name

并且服务的完整路径为:app.package.name.example.package.path.MyServiceClass

那么命令应该是这样的:

adb shell am startservice app.package.name/.example.package.path.MyServiceClass

我真是为这个问题苦恼了,因为没有地方解释得清楚 - 谢谢你。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接