23

次の ADB コマンドを使用して、コンピューターに接続しているときに Android フォンから SMS を送信できるようにしたいと考えています。

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

私はこれを機能させましたが、電話では、本文が入力されたテキストメッセージが受信者にポップアップ表示され、送信ボタンをクリックして元の場所に戻ります. これを完全にバックグラウンドで実行して、電話で起こっていることを妨げないようにする方法はありますか?

4

6 に答える 6

35

短縮版 :

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のバージョンで変わる可能性があります。それを理解するために完全な説明を読んでください。


すべての Android バージョンの完全な説明:

はい、存在します!これらの入力イベントはスリープ モードでブロックされるため、このコマンドではできません。この解決策は、お使いの Android のバージョンに依存するため、ほぼすべてのバージョンについて説明します ...

まず、次を実行してサービス isms があるかどうかを確認します。

adb shell service check isms
Service isms: found

答えは見つかった、よし、動き続けよう。サービスイズムにはさまざまな「オプション」があり、構文は次のとおりです。

service call name_service option args

サービス名は、次のように入力して見つけることができます。

adb shell service list

利用可能な多くのサービスが表示されますが、興味深い行は次のとおりです。

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

com.android.internal.telephony.Isms が表示されるので、このリンクで Android のバージョンを (ブランチを変更して) 選択し、次に : に移動しtelephony/java/com/android/internal/telephonyて開きます。Isms.aidl

残りについては、android Pie (android 9) ファイル (リンク) を使用します。

185行目には、次のものがあります。

void sendTextForSubscriberWithSelfPermissions(...)

注: Android 5 より前では、メソッドの名前はsendText(...).

これは、インターフェース ISMS の 7 番目の宣言です。したがって、SMS を送信するオプションは 7 です。宣言の上部には、引数の説明があります。ここに短いバージョンがあります:

  • subId : Android 5 以降、Android のバージョンに応じて 0、1、または 2 を使用する SIM カード (例: Android 9 の場合は 0-1、Android 8 の場合は 1-2)
  • callingPkg : SMS を送信するパッケージの名前 (見つけ方は後で説明します)
  • destinationAdress : メッセージ受信者の電話番号
  • scAddress : smsc は android 5 以前でのみ必要です (後で説明します)
  • パーツ:メッセージ!
  • sendIntends と deliveryIntents : 気にしない

-> パッケージ名を見つける: アプリ ファイルを調べるか、Google Play で Package Name Viewer をダウンロードし、メッセージ アプリケーションを見つけて名前 (com.android...) をコピーします。

-> smsc を見つけます: アプリケーションで -> 設定 -> SMSC またはサービス センターまたはメッセージ センターなどで、番号表示をコピーします (変更しないでください)。

終了する直前に、サービスで文字列が s16整数で宣言され、 i32 でPendingIntent が宣言されます。

したがって、私の例では次のようになります。

  • サブ ID : 0
  • callingPkg : com.android.mms
  • 対象番号:+01234567890
  • SMSC : +01000000000
  • 私のテキスト: Hello world !
  • 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"

-> バッチ ファイルの例:

Android 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 !

あなたのAndroidバージョンで動作するかどうか教えてください:)

編集 :アレックス P. から提供された情報で修正編集 2:ニールから提供された情報で修正

于 2015-05-13T19:57:05.127 に答える
4

この の代わりに、次のように独自のインテント サービスを記述します。マニフェストに次の 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);
        }
    }
}
于 2013-07-11T00:11:39.947 に答える
1

以下の答えは私にとってうまくいきました!Android 5.02 ではオプションは 12 で、SMSC として null を送信してデフォルトを使用できることがわかったので、SMS の送信は次のように機能しました。

adb shell service call isms 12 s16 "com.android.mms" s16 "+01234567890" s16 "null" s16 "Hello world" i32 0 i32 0
于 2015-06-26T19:22:19.167 に答える