3

ネイティブの Android メッセージング アプリを使用せずに MMS を送信するアプリを作成しようとしています。ここの例に従いました。ログ ステートメントは正しく出力されているようですが、MMS が送信されない理由がわかりません。

また、別のメモとして、添付ファイル (画像など) が MMS として送信するために選択されている例の場所について少し混乱しています。デモを Android Studio にインポートしようとしましたが、問題が発生しました。

MMS を送信するための私の機能は以下のとおりです。

 public void sendMMS() {
    Log.d(TAG, "sendMMS()");
    Random random = new Random();
    final String fileName = "send." + String.valueOf(Math.abs(random.nextLong())) + ".dat";

    final File mSendFile = new File(mContext.getCacheDir(), fileName);
    // Making RPC call in non-UI thread
    AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
        @Override
        public void run() {
            final byte[] pdu = buildPdu();
            Uri writerUri = (new Uri.Builder())
                    .authority("com.example.appname")
                    .path(fileName)
                    .scheme(ContentResolver.SCHEME_CONTENT)
                    .build();
            Log.d(TAG, "sendMMS(): Uri: " + writerUri.toString());
            FileOutputStream writer = null;
            Uri contentUri = null;
            try {
                writer = new FileOutputStream(mSendFile);
                writer.write(pdu);
                contentUri = writerUri;
                Log.d(TAG, "sendMMS(): just wrote file");
            } catch (final IOException e) {
                Log.d(TAG, "sendMMS(): FAILED: couldn't write file");
            } finally {
                if (writer != null) {
                    try {
                        writer.close();
                    } catch (IOException e) {
                    }
                }
            }
            if (contentUri != null) {
                SmsManager.getDefault().sendMultimediaMessage(mContext, contentUri, null, null, null);
                Log.d(TAG, "sendMMS(): just sent");
            } else {
                Log.d(TAG, "sendMMS(): FAILED: couldn't write file so didn't send");
            }
        }
    });

}

ヘルパー関数

    private byte[] buildPdu() {
    final SendReq req = new SendReq();
    // from
    final String lineNumber = getSimNumber();
    if (!TextUtils.isEmpty(lineNumber)) {
        req.setFrom(new EncodedStringValue(lineNumber));
    }
    // to
    String[] destsArray = mDestList.toArray(new String[mDestList.size()]);
    EncodedStringValue[] encodedNumbers = EncodedStringValue.encodeStrings(destsArray);
    if (encodedNumbers != null) {
        req.setTo(encodedNumbers);
    }
    // date
    req.setDate(System.currentTimeMillis() / 1000);
    // body
    PduBody body = new PduBody();
    // message text
    final int size = addMessagePart(body, true/* add text smil */);
    req.setBody(body);
    // message size
    req.setMessageSize(size);
    // message class
    req.setMessageClass(PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes());
    // expiry
    req.setExpiry(DEFAULT_EXPIRY_TIME);
    try {
        // priority
        req.setPriority(DEFAULT_PRIORITY);
        // delivery report
        req.setDeliveryReport(PduHeaders.VALUE_NO);
        // read report
        req.setReadReport(PduHeaders.VALUE_NO);
    } catch (InvalidHeaderValueException e) {}
    return new PduComposer(mContext, req).make();
}

private String getSimNumber() {
    TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
    return telephonyManager.getLine1Number();
}

private int addMessagePart(PduBody pb, boolean addTextSmil) {
    PduPart part = new PduPart();
    part.setCharset(CharacterSets.UTF_8);
    part.setContentType(ContentType.TEXT_PLAIN.getBytes());
    part.setContentLocation(TEXT_PART_FILENAME.getBytes());
    int index = TEXT_PART_FILENAME.lastIndexOf(".");
    String contentId = (index == -1) ? TEXT_PART_FILENAME : TEXT_PART_FILENAME.substring(0, index);
    part.setContentId(contentId.getBytes());
    part.setData(mMessage.getBytes());
    pb.addPart(part);
    if (addTextSmil) {
        String smil = String.format(sSmilText, TEXT_PART_FILENAME);
        addSmilPart(pb, smil);
    }
    return part.getData().length;

}

private void addSmilPart(PduBody pb, String smil) {
    PduPart smilPart = new PduPart();
    smilPart.setContentId("smil".getBytes());
    smilPart.setContentType(ContentType.APP_SMIL.getBytes());
    smilPart.setContentLocation("smil.xml".getBytes());
    smilPart.setData(smil.getBytes());
    pb.addPart(0, smilPart);
}

私のマニフェストの関連部分

<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

関連するインスタンス変数

    private final long DEFAULT_EXPIRY_TIME = 7 * 24 * 60 * 60;
private final String TEXT_PART_FILENAME = "text_0.txt";
private final int DEFAULT_PRIORITY = PduHeaders.PRIORITY_NORMAL;
private String mMessage;
private ArrayList<String> mDestList;
private Context mContext;
private static final String sSmilText =
        "<smil>" +
                "<head>" +
                    "<layout>" +
                        "<root-layout/>" +
                        "<region height=\"100%%\" id=\"Text\" left=\"0%%\" top=\"0%%\" width=\"100%%\"/>" +
                    "</layout>" +
                "</head>" +
                "<body>" +
                    "<par dur=\"8000ms\">" +
                        "<text src=\"%s\" region=\"Text\"/>" +
                    "</par>" +
                "</body>" +
        "</smil>";

すでに入力チェックを行っているため、sendMMS() が呼び出されるまでに、メッセージと destList は null ではありません。

4

1 に答える 1

4

フローは次のようになります。

  1. Mms send-request を作成し、new SendReq()日付、本文、宛先などを設定します。
  2. Mms ボディを作成しますnew PduBody()
  3. new PduPart()添付ファイルごとにパーツを作成し、ボディに追加します。body.addPart(pdu)
  4. 本文をリクエストに追加します -req.setBody(body)
  5. send-request を byte[] に変換して呼び出してすぐに送信できるようにしnew PduComposer(context, mySendReq).make()ます。PduComposer クラスを取得するには、Android のソース コードから多くのコードをコピーする必要があることに注意してください。
  6. ここが興味深い部分です。アプリのみがアクセスできるローカル ファイルに byte[] を保存し、ContentProvider他のアプリがファイルへのアクセスを要求できるようにするクラスを追加します。これはMmsFileProviderサンプル アプリのクラスです。マニフェスト ファイルのプロバイダー。
  7. ここで、SmsManager.sendMultimediaMessageAPI を呼び出すと、ファイル プロバイダーがウェイクアップして、pdu バイトを含むファイルをシステム SmsManager に提供します。システム SmsManager は、それを読み取ってネットワーク上に送信します。

そうは言っても、この API は一部のデバイス (Nexus など) でのみ機能しますが、他のデバイス (HTC One など) では機能しません。ここで私の SO の質問を参照してください: HTC/LG の SmsManager MMS API

于 2015-04-19T07:38:18.847 に答える