通过ADB在Android上发送短信

yshpjwxd  于 2023-02-06  发布在  Android
关注(0)|答案(8)|浏览(315)

我希望能够发送短信从我的Android手机,而它连接到我的电脑使用以下ADB命令

adb shell am start -a android.intent.action.SENDTO -d sms:CCXXXXXXXXXX --es sms_body "SMS BODY GOES HERE" --ez exit_on_sent true
adb shell input keyevent 22
adb shell input keyevent 66

我已经得到了这个工作,但在手机上,这将弹出一个文本消息的收件人与身体填写,然后点击发送按钮,并返回到你在哪里.有没有任何方法来完成这一点完全在后台,所以它不会干扰任何事情发生在手机上?

axkjgtzd

axkjgtzd1#

    • 简短版本:**

Android 5及更早版本(此处为Android 4):

adb shell service call isms 5 s16 "com.android.mms" s16 "+01234567890" s16 "+01SMSCNUMBER" s16 "Hello world !" i32 0 i32 0

Android 5及更高版本(此处为Android 9):

adb shell service call isms 7 i32 0 s16 "com.android.mms.service" s16 "+1234567890" s16 "null" s16 "Hey\ you\ !" s16 "null" s16 "null"

isms方法编号(上面的5和7)可能会随着android版本而改变。阅读完整的解释来理解它。

    • 所有安卓版本的完整说明:**

是的,它存在!但不是用这个命令,因为这些输入事件在睡眠模式下被阻止。这个解决方案取决于你的安卓版本,所以我会解释你几乎所有的版本...
首先,通过运行以下命令检查您是否拥有服务isms:

adb shell service check isms
Service isms: found

答案是找到了,很好,继续前进。服务isms有各种"选项",语法是:

service call name_service option args

可以通过键入以下内容找到服务名称:

adb shell service list

它将显示许多可用的服务,但有趣的一行是:

5       isms: [com.android.internal.telephony.ISms]

你可以看到com.android.internal.telephony.isms,所以在这个link上选择你的android版本(通过改变分支),然后导航到:telephony/java/com/android/internal/telephony和打开的Isms.aidl
其余的我将采取android馅饼(android 9)文件(link)。
在第185行,我们有:
具有自身权限的订阅服务器的void sendText...

    • 注意:**在android 5之前,该方法被命名为sendText(...)

这是接口ISMS中的第7个声明。因此,我们发送短信的选项是数字7。在声明的顶部有参数的解释。以下是简短版本:

  • subId:在Android 5之后,您要使用的SIM卡0,1或2取决于您的Android版本(例如0 - 1的Android 9和1 - 2的Android 8)
  • 调用 Package :将发送您的SMS的包的名称(我稍后解释如何找到它)
  • 目的地地址:消息接收者的电话号码
  • scAddress:您的短信是唯一需要在android5和更低版本(解释后)
  • 部分:您的消息!
  • 发送意图和交付意图:你不在乎
  • *-〉查找您的套餐名称:**探索您的应用文件或在Google Play上下载套餐名称查看器,找到您的消息应用并复制名称(com.android ...)
  • *-〉查找您的短消息中心:**在您的应用程序-〉设置-〉短消息中心或服务中心或消息中心等,复制号码显示(不要更改它)

就在完成之前,在服务中,字符串由s16整数以及带有i32的PendingIntent声明。
对于我的例子,我们有:

  • 子ID:0
  • 调用 Package :com.android.mms
  • 目标数量:+01234567890
  • 短信中心:+0100000000
  • 我的短信:你好,世界!
  • sendIntends和deliveryIntents我们并不关心,因此我们将其设置为0以将其设置为默认值。

最后:
Android 5及更早版本(此处为Android 4):

adb shell service call isms 5 s16 "com.android.mms" s16 "+01234567890" s16 "+01000000000" s16 "Hello world !" i32 0 i32 0

Android 5及更高版本(此处为Android 9):

adb shell service call isms 7 i32 0 s16 "com.android.mms.service" s16 "+1234567890" s16 "null" s16 "'Hey you !'" s16 "null" s16 "null"
  • -〉批处理文件中的示例:*

安卓4的send.bat:

echo off
set num=%1
shift
for /f "tokens=1,* delims= " %%a in ("%*") do set ALL_BUT_FIRST=%%b
echo %ALL_BUT_FIRST%
adb shell service call isms 5 s16 "com.android.mms" s16 "%num%" s16 "+01000000000" s16 "%ALL_BUT_FIRST%" i32 0 i32 0

运行:

send.bat +01234567890 Hey you !

现在告诉我它是否适用于你的安卓版本:)

    • 编辑:根据Alex P.提供的信息进行更正编辑2:**根据Neil提供的信息进行更正
jtoj6r0c

jtoj6r0c2#

相反,您可以编写自己的IntentService,如下所示。在清单中为以下IntentService创建一个条目。

String targetPhoneNumber = "XX-XXXXXXX-XXXXXX-XXXX";
SmsToSend targetSms = new SmsToSend();
String urlText = url;
targetSms.setPhoneNumbers(new String[]{targetPhoneNumber});
targetSms.setSmsBody("Help me");
Intent smsIntent = targetSms.convertToIntent(context);
        startService(smsIntent);

        import java.util.ArrayList;
        import android.app.IntentService;
        import android.app.PendingIntent;
        import android.content.Intent;

        public class SendStreamMessage extends IntentService {

        public SendStreamMessage() {
            super("Sms Sender Intent Service");
        }

        @Override
        protected void onHandleIntent(Intent intent) {
            sendSms(intent);
        }

        private void sendSms(Intent intent) {
            try {
                SmsToSend smsSend = (SmsToSend) intent
                        .getParcelableExtra("SMSMessage");
                Intent sentIntent = new Intent(SmsDeliveryHandlers.SENT_SMS_ACTION);

                PendingIntent sentPI = PendingIntent.getBroadcast(
                        SendStreamMessage.this, 0, sentIntent, 0);
                Intent deliveryIntent = new Intent(
                        SmsDeliveryHandlers.DELIVERED_SMS_ACTION);
                PendingIntent deliverPI = PendingIntent.getBroadcast(
                        SendStreamMessage.this, 0, deliveryIntent, 0);
                android.telephony.SmsManager smsManager = android.telephony.SmsManager
                        .getDefault();

                ArrayList<String> messages = smsManager.divideMessage(smsSend
                        .getSmsBody());

                int smsSize = messages.size();

                ArrayList<PendingIntent> sentPiList = new ArrayList<PendingIntent>(
                        smsSize);
                ArrayList<PendingIntent> deliverPiList = new ArrayList<PendingIntent>(
                        smsSize);

                for (int i = 0; i < smsSize; i++) {
                    sentPiList.add(sentPI);
                    deliverPiList.add(deliverPI);
                }

                if (smsSize > 1) {
                    for (int i = 0; i < smsSend.getPhoneNumbers().length; i++) {
                        String targetPhoneNumber = smsSend.getPhoneNumbers()[i];
                        SmsDeliveryHandlers handler = new SmsDeliveryHandlers(
                                targetPhoneNumber, smsSend.getSmsBody());
                        try {
                            smsManager.sendMultipartTextMessage(targetPhoneNumber,
                                    null, messages, sentPiList, deliverPiList);
                        } catch (Exception ex) {
                            handler.cleanReceiver();
                        }
                    }
                } else {
                    SmsDeliveryHandlers handler;
                    for (int i = 0; i < smsSend.getPhoneNumbers().length; i++) {
                        String targetPhoneNumber = smsSend.getPhoneNumbers()[i];
                        handler = new SmsDeliveryHandlers(targetPhoneNumber,
                                smsSend.getSmsBody());
                        try {
                            smsManager.sendTextMessage(targetPhoneNumber, null,
                                    smsSend.getSmsBody(), sentPI, deliverPI);
                        } catch (Exception ex) {
                            handler.cleanReceiver();
                        }
                    }
                }
            } finally {
            }
        }
    }

    import android.app.Activity;
    import android.content.BroadcastReceiver;
    import android.content.ContentResolver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.net.Uri;

    public final class SmsDeliveryHandlers extends BroadcastReceiver {
        public static final String SENT_SMS_ACTION = "SENT_SMS_ACTION";
        public static final String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";
        private SmsToSend send;
        private Context context;
        private Uri sendboxUri;

        public SmsDeliveryHandlers(String phoneNumber, String message) {
            this(new SmsToSend(message, phoneNumber));
        }

        public SmsDeliveryHandlers(SmsToSend send) {
            this.send = send;
            IntentFilter targetFilter = new IntentFilter();
            targetFilter.addAction(SENT_SMS_ACTION);
            targetFilter.addAction(DELIVERED_SMS_ACTION); 
            context = MmsLiveApplication.getInstance().getTargetContext();
            context.registerReceiver(this, targetFilter);
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            if (SENT_SMS_ACTION.equals(intent.getAction())) {
                handleSend();
            } else if (DELIVERED_SMS_ACTION.equals(intent.getAction())) {
                handleDelivery();
            }
        }
        private synchronized void handleSend() {
            String address = send.getPhoneNumbers()[0];
            ContentResolver contentResolver = context.getContentResolver();
            int resultCode = getResultCode();
            if(resultCode != Activity.RESULT_OK)
            {           
                cleanReceiver();
            }
        }

        public void cleanReceiver() {
            context.unregisterReceiver(this); 
        }

        private void handleDelivery() {
            switch (getResultCode()) {
            case Activity.RESULT_OK:
                // HACK This is a hack to insert the send sms result to the real
                // message send table ;)
                break;
            case Activity.RESULT_CANCELED:
                break;
            }
            cleanReceiver();
        }
    }

package com.ttech.mmslive.contacts;

import android.content.Context;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;

public class SmsToSend implements Parcelable{
    public static final Parcelable.Creator<SmsToSend> CREATOR = new Parcelable.Creator<SmsToSend>() {
        public SmsToSend createFromParcel(Parcel in) {
            return new SmsToSend(in);
        }
        public SmsToSend[] newArray(int size) {
            return new SmsToSend[size];
        }
    };
    public SmsToSend()
    {       
    }
    public SmsToSend(Parcel in) {
        readFromParcel(in);
    }   
    public SmsToSend(String smsBody,String phoneNumber)
    {
        this.smsBody = smsBody;
        phoneNumbers = new String[]{phoneNumber};
    }   
    public Intent convertToIntent(Context targetContext)
    {
        Intent targetIntent = new Intent(targetContext,SendStreamMessage.class);
        targetIntent.putExtra("SMSMessage", this);
        return targetIntent;
    }
    @Override
    public int describeContents() {
        return 0;
    }
    private String[] phoneNumbers; 
    private String smsBody;
    public String[] getPhoneNumbers() {
        return phoneNumbers;
    }
    public String getSmsBody() {
        return smsBody;
    }
    public void readFromParcel(Parcel in) {
        smsBody = in.readString();
        int length = in.readInt();
        if(length > 0)
        {
            phoneNumbers = new String[length];
            in.readStringArray(phoneNumbers);
        }
    }
    public void setPhoneNumbers(String[] phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }
    public void setSmsBody(String smsBody) {
        this.smsBody = smsBody;
    }
    @Override
    public void writeToParcel(Parcel parcel, int params) {
        parcel.writeString(smsBody);
        if(phoneNumbers != null && phoneNumbers.length > 0)
        {
            parcel.writeInt(phoneNumbers.length);
            parcel.writeStringArray(phoneNumbers);
        }
        else{
            parcel.writeInt(0);
        }
    }
}
yiytaume

yiytaume3#

我已经花了很多时间试图让我的HTC Desire与SlimKat的权利。现在我使用这个脚本,让我发送短信几乎立即(yad图形用户界面是非常快)与我的PC键盘。我只需要选择一个手机号码(让我们说00165826453),并按WinKey+S,这打开:

这是我为此开发的BASH脚本:

#!/usr/bin/env bash

if [ $# -eq 1 ]; then
    phoneNumber=${1//[^0-9\+]/}
else
    phoneNumber=`xsel | sed 's/[^0-9\+]//g'`
fi

if [ -z "$phoneNumber" ]; then
    yadText=`yad --form --field="Phone number" --field="Multiline text:TXT" --width=400 --height=320 --title="Send SMS" --focus-field=1 --button="Send SMS:0"`
else
    yadText=`yad --form --field="Phone number" "$phoneNumber" --field="SMS text:TXT" --width=400 --height=320 --title="Send SMS" --focus-field=2 --button="Send SMS:0"`
fi

phoneNumber=${yadText//\|*/}
smsText=${yadText#*|}
smsText=${smsText%|*}

ssh root@noa "su shell service call isms 5 s16 \"com.android.mms\" s16 \"$phoneNumber\" s16 \"null\" s16 \"$smsText\" s16 \"null\" s16 \"null\""

这是phonomenaly有用和快速。唯一的缺点是,发送的短信不会出现在默认的短信应用程序对我的SlimKat。
为了让这个功能在您的Debian衍生产品上运行,您必须:

aptDistro> sudo apt install yad bash

或者你发行版的等价物。
这在我的机器上工作,因为我在我的SlimKat安装上设置了一个SSH服务器,使用密钥认证。你可以稍微修改它,通过ADB无线工作。

ffx8fchx

ffx8fchx4#

下面的答案对我来说很有效!在Android 5.02中,选项是12,我发现您可以发送null作为SMSC来使用默认值,因此发送短信可以使用:

adb shell service call isms 12 s16 "com.android.mms" s16 "+01234567890" s16 "null" s16 "Hello world" i32 0 i32 0
bfrts1fy

bfrts1fy5#

谢谢你,Taknok,给了我一个很棒的回答。
我用的是三星Galaxy S5,Android版本为6.0.1。在我的手机上,SIM卡的subId实际上是3(而不是你回答中建议的0、1或2)。我花了一段时间才弄明白,所以我在这里发帖,以防其他人也想知道。这个命令起作用了:

adb shell service call isms 7 i32 3 s16 "com.android.mms" s16 "+123456789" s16 "+100000000" s16 "'Hello world'" i32 0 i32 0
kgqe7b3p

kgqe7b3p6#

对于Android版本8,我使用了以下代码:

Process process = new Process();
process.StartInfo.FileName = "adb.exe";
process.StartInfo.Arguments = "shell service call isms 7 i32 2  s16 'com.android.mms.service' s16 '" + 03001111111 + "' s16 'null' s16 '" + textBox1.Text + "' i32 0 i32 0";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();

但有时取决于移动的在我使用相同的代码三星j5版本8,但在这里我使用isms 7 i32 8 .
对于Android版本9,我使用了以下代码:

Process process = new Process();
process.StartInfo.FileName = "adb.exe";
process.StartInfo.Arguments = "shell service call isms 7 i32 2 s16 'com.android.mms.service' s16 '" + 03001111111 + "' s16 'null' s16 '" + textBox1.Text + "' i32 0 i32 0";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();

对于Android版本6,我使用了以下代码:

Process process = new Process();
process.StartInfo.FileName = "adb.exe";
process.StartInfo.Arguments = "shell service call isms 7 i32 1 s16 'com.android.mms.service' s16 '" + 03001111111 + "' s16 'null' s16 '" + textBox1.Text + "' i32 0 i32 0";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();

但是我卡在了Android版本11。我习惯了很多条件,但没有来到正确的地方。

4uqofj5v

4uqofj5v7#

对于Android 12(sdk 31),请查找最新的解决方案:

adb shell service call isms 5 i32 0 s16 "com.android.mms.service" s16 "null" s16 '+0123456789' s16 "null" s16 "text message body here" s16 "null" s16 "null" s16 "null" s16 "null"

这基于源代码中的以下函数,以防您想要更改"null"值:

void sendTextForSubscriber(
  in int subId, 
  String callingPkg, 
  String callingAttributionTag, 
  in String destAddr, 
  in String scAddr, 
  in String text, 
  in PendingIntent sentIntent,
  in PendingIntent deliveryIntent, 
  in boolean persistMessageForNonDefaultSmsApp,
  in long messageId);

这是测试成功使用三星Galaxy S21和摩托罗拉(新旗舰)在T-Mobile网络。

**注意以前的问题(投票否决的原因)是由于软件包名称中的“services”而不是“service”。不确定GS 21未受这些更改影响的原因。

wj8zmpe1

wj8zmpe18#

Android 13函数签名未更改,但在此处尝试之前的答案时,adb命令失败,响应奇怪。

void sendTextForSubscriber(in int subId, String callingPkg, String callingAttributionTag,
            in String destAddr, in String scAddr, in String text, in PendingIntent sentIntent,
            in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp,
            in long messageId);

Unix shell别名,例如.bash_profile

alias sms='adb shell service call isms 5 i32 0 s16 "com.android.mms.service" s16 "null" s16 "$1" s16 "null" s16 "$2" s16 "null" s16 "null" i32 0 i64 0'

用法:短信“+372xxxxxx”“您的留言”
Windows CMD别名:

DOSKEY sms=adb shell service call isms 5 i32 0 s16 "com.android.mms.service" s16 "null" s16 "$1" s16 "null" s16 "'$*'" s16 "null" s16 "null" i32 0 i64 0

将 *.bat/cmd文件路径添加到HKLM\Software\Microsoft\Command Processor中的AutoRun
用法:sms +372xxxxxx Your message

相关问题