I need to write a shell script to start and stop an android service .
问题:
回答1:
I'm a beginner in Android, but got it working like this:
in AndroidManifest.xml, make sure you, inside <application>
, have something like this:
<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>
where YourServiceSubClassName
extend android.app.Service
is your java class that is the service. Where com.some.package
is the package name, for me both in AndroidManifest.xml and in Java.
Used a javabeat.net article as help, look for <service>
Note also, supposedly between the package name and the class name there should be .service.
in the text, I guess this is some convention, but for me this caused ClassNotFoundException
that I'm yet to solve.
Then, install your apk. I did from eclipse but also adb install -r yourApkHere.apk
should work. Uninstall is adb uninstall com.some.package.name
, btw.
You can start it from host system like this, thanks Just a Tim and MrRoy:
adb shell am startservice com.some.package.name/.YourServiceSubClassName
interestingly, I didn't need -n
.
To stop, I use
adb shell am force-stop com.some.package.name
Hope it helps.
As I'm a beginner, please feel freet to edit/comment to fix any misconceptions (eg. probably regarding .service.
in the component (?) name).
回答2:
Starting a service:
adb shell am startservice ...
start a Service. Options are: --user | current: Specify which user to run as; if not specified then run as the current user.
Stopping a service:
adb shell am stopservice ...
stop a Service. Options are: --user | current: Specify which user to run as; if not specified then run as the current user.
回答3:
If you want to run the script in adb shell, then I am trying to do the same, but with an application. I think you can use "am start" command
usage: am [subcommand] [options]
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>]
回答4:
I can start service through
am startservice com.xxx/.service.XXXService
but i don't know how to stop it yet.
回答5:
You should set the android:exported attribute of the service to "true", in order to allow other components to invoke it. In the AndroidManifest.xml file, add the following attribute:
<service android:exported="true" ></service>
Then, you should be able to start the service via adb:
adb shell am startservice com.package.name/.YourServiceName
For more info about the android:exported attribute see this page.
回答6:
You may get an error "*Error: app is in background *" while using
adb shell am startservice
in Oreo (26+). This requires services in the foreground. Use the following.
adb shell am start-foreground-service com.some.package.name/.YourServiceSubClassName
回答7:
Responding to pzulw's feedback to sandroid about specifying the intent.
The format of the component name is described in the api docs for ComponentName.unflattenFromString
It splits the string at the first '/', taking the part before as the package name and the part after as the class name. As a special convenience (to use, for example, when parsing component names on the command line), if the '/' is immediately followed by a '.' then the final class name will be the concatenation of the package name with the string following the '/'. Thus "com.foo/.Blah" becomes package="com.foo" class="com.foo.Blah".
回答8:
You need to add android:exported="true"
to start service from ADB command line. Then your manifest looks something like this:
<!-- 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 -->
And then from ADB
To start service:
adb shell am startservice com.your.package.name/.YourServiceName
To stop service (on Marshmallow):
adb shell am stopservice com.your.package.name/.YourServiceName
To stop service (on Jelly Bean):
adb shell am force-stop com.your.package.name
回答9:
am startservice <INTENT>
or actually from the OS shell
adb shell am startservice <INTENT>
回答10:
For anyone still confused about how to define the service name parameter, the forward slash goes immediately after the application package name in the fully qualified class name.
So given an application package name of: app.package.name
And a full path to the service of: app.package.name.example.package.path.MyServiceClass
Then the command would look like this:
adb shell am startservice app.package.name/.example.package.path.MyServiceClass