Android系统不光在host上为我们提供了一些好用的命令, 同时device也有一些隐藏着的命令, 通常它是被系统调用,但是由于权限设置的原因, 普通的进程也能通过命令行去使用它们.
比如,我之前提到的<Android性能测试工具之dumpsys>及<Android调试工具之adbs>在device中, 有一个service命令, 可以看到当前所有的service, 同时也可以使用它来往一些activity发送一些信息
如下所示, service的用法:root@android:/ # service Usage: service [-h|-?] service list service check SERVICE service call SERVICE CODE [i32 INT | s16 STR] ...Options: i32: Write the integer INT into the send parcel. s16: Write the UTF-16 string STR into the send parcel.
当前运行的service:
root@android:/ # service list Found 61 services:0 sip: [android.net.sip.ISipService]1 phone: [com.android.internal.telephony.ITelephony]2 iphonesubinfo: [com.android.internal.telephony.IPhoneSubInfo]3 simphonebook: [com.android.internal.telephony.IIccPhoneBook]4 isms: [com.android.internal.telephony.ISms]5 nfc: [android.nfc.INfcAdapter]6 samplingprofiler: []7 diskstats: []8 appwidget: [com.android.internal.appwidget.IAppWidgetService]9 backup: [android.app.backup.IBackupManager]10 uimode: [android.app.IUiModeManager]11 usb: [android.hardware.usb.IUsbManager]12 audio: [android.media.IAudioService]13 wallpaper: [android.app.IWallpaperManager]14 dropbox: [com.android.internal.os.IDropBoxManagerService]15 search: [android.app.ISearchManager]16 country_detector: [android.location.ICountryDetector]17 location: [android.location.ILocationManager]18 devicestoragemonitor: []19 notification: [android.app.INotificationManager]20 mount: [IMountService]21 throttle: [android.net.IThrottleManager]22 connectivity: [android.net.IConnectivityManager]......
使用service的phone来打电话
root@android:/ # service call phone 2 s16 "123" Result: Parcel(00000000 '....')
此时, 就直接拨号了:), 但是这里注意, 紧急号码在这里是不work的.
下面再来一个用来发短信的
root@android:/ # service call isms 4 s16 "12345678" s16 "" s16 "hello world!" s16 "" s16 ""
下面就说一下原理大家先找到代码frameworks/base/telephony/java/com/android/internal/telephony/ITelephony.aidl和ISms.aidl,这两个文件都是给OEM厂商集成用的, 代码我这里就不贴了,细心的童鞋一眼就能看出来, 上面的"2", "4"就是指定了是哪一个函数比如, 2 就是
/** * Place a call to the specified number. * @param number the number to be called. */ void call(String number);
4就是
/** * Send an SMS. * * @param smsc the SMSC to send the message through, or NULL for the * default SMSC * @param text the body of the message to send * @param sentIntent if not NULL thisPendingIntent
is * broadcast when the message is sucessfully sent, or failed. * The result code will beActivity.RESULT_OK
for success, * or one of these errors: *
RESULT_ERROR_GENERIC_FAILURE
*RESULT_ERROR_RADIO_OFF
*RESULT_ERROR_NULL_PDU
* ForRESULT_ERROR_GENERIC_FAILURE
the sentIntent may include * the extra "errorCode" containing a radio technology specific value, * generally only useful for troubleshooting. * The per-application based SMS control checks sentIntent. If sentIntent * is NULL the caller will be checked against all unknown applications, * which cause smaller number of SMS to be sent in checking period. * @param deliveryIntent if not NULL thisPendingIntent
is * broadcast when the message is delivered to the recipient. The * raw pdu of the status report is in the extended data ("pdu"). */ void sendText(in String destAddr, in String scAddr, in String text, in PendingIntent sentIntent, in PendingIntent deliveryIntent);
所以, 以后要想在后台发短信,打电话,可以直接调用Java的Runtime Exec来调用service提供的命令, 这样就可以部分绕过framework中的一些java service, 而直接跟更底层的c++/C实现的service直接交互:)