Android發送短信


獲取OR創建ThreadId

private long getOrCreateThreadId() {
    Set<String> recipients = new HashSet<String>();
    String[] numbers = mNumber.split(",");
    for(int i=0;i<numbers.length;i++) {
        recipients.add(numbers[i]);
    }
    return Threads.getOrCreateThreadId(mContext, recipients);
}

參考資料

android 中調用接口發送短信

發送短信代碼判斷

private void sendMsg(String destAddress, String content,
        PendingIntent sentIntent, PendingIntent deliveryIntent) {
    SmsManager smsManager = SmsManager.getDefault();
    List<String> divideContents = smsManager.divideMessage(content);
    for (String text : divideContents) {
        smsManager.sendTextMessage(destAddress, null, text, sentIntent,
                deliveryIntent);
    }
}

查看發送短信有關API

1. android.telephony.SmsManager

Manages SMS operations such as sending data, text, and pdu SMS messages. Get this object by calling the static method SmsManager.getDefault().

2. android.telephony.SmsManager.sendTextMessage()

void android.telephony.SmsManager.sendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)

Send a text based SMS.

Parameters:
destinationAddress the address to send the message to
scAddress is the service center address or null to use the current default SMSC
text the body of the message to send
sentIntent if not NULL this PendingIntent is broadcast when the message is sucessfully sent, or failed. The result code will be Activity.RESULT_OK for success, or one of these errors: RESULT_ERROR_GENERIC_FAILURE, RESULT_ERROR_RADIO_OFF, RESULT_ERROR_NULL_PDU
For RESULT_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.
deliveryIntent if not NULL this PendingIntent is broadcast when the message is delivered to the recipient. The raw pdu of the status report is in the extended data ("pdu").
Throws:
IllegalArgumentException - if destinationAddress or text are empty

3. android.app.PendingIntent.getBroadcast()

PendingIntent android.app.PendingIntent.getBroadcast(Context context, int requestCode, Intent intent, int flags)

Retrieve a PendingIntent that will perform a broadcast, like calling Context.sendBroadcast().

Parameters:
context The Context in which this PendingIntent should perform the broadcast.
requestCode Private request code for the sender (currently not used).
intent The Intent to be broadcast.
flags May be FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT, or any of the flags as supported by Intent.fillIn() to control which unspecified parts of the intent that can be supplied when the actual send happens.
Returns:
Returns an existing or new PendingIntent matching the given parameters. May return null only if FLAG_NO_CREATE has been supplied.

4. android.content.Context.sendBroadcast()

void android.content.Context.sendBroadcast(Intent intent)

Broadcast the given intent to all interested BroadcastReceivers. This call is asynchronous; it returns immediately, and you will continue executing while the receivers are run. No results are propagated from receivers and receivers can not abort the broadcast. If you want to allow receivers to propagate results or abort the broadcast, you must send an ordered broadcast using sendOrderedBroadcast(Intent, String).

See BroadcastReceiver for more information on Intent broadcasts.

Parameters:
intent The Intent to broadcast; all receivers matching this Intent will receive the broadcast.
See Also:
android.content.BroadcastReceiver
registerReceiver
sendBroadcast(Intent, String)
sendOrderedBroadcast(Intent, String)
sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)

5. Telephony.Sms.Outbox.addMessage()

Uri com.txrj.sms.system.Telephony.Sms.Outbox.addMessage(ContentResolver resolver, String address, String body, String subject, Long date, boolean deliveryReport, long threadId)

Add an SMS to the Out box.

Parameters:
resolver the content resolver to use
address the address of the sender
body the body of the message
subject the psuedo-subject of the message
date the timestamp for the message
deliveryReport whether a delivery report was requested for the message
threadId
Returns:
the URI for the new message

發送短信給10010和10011出錯

07-14 16:55:53.023: E/AndroidRuntime(4078): FATAL EXCEPTION: main
07-14 16:55:53.023: E/AndroidRuntime(4078): java.lang.SecurityException: Sending SMS message: Neither user 10110 nor current process has android.permission.SEND_SMS.

調用Telephony.Sms.Outbox.addMessage()出現異常

07-14 22:18:53.465: E/AndroidRuntime(8912): FATAL EXCEPTION: main
07-14 22:18:53.465: E/AndroidRuntime(8912): java.lang.SecurityException: Permission Denial: writing com.android.providers.telephony.SmsProvider uri content://sms/outbox from pid=8912, uid=10110 requires android.permission.WRITE_SMS

發送信息到10010日志

07-14 22:21:36.935: I/txrjsms(9352): send msg to 10010, content:
07-14 22:21:36.935: I/txrjsms(9352): 1314649
07-14 22:21:39.857: I/txrjsms(9352): send Msg success.
07-14 22:21:43.171: I/txrjsms(9352): message arrived.

將發送的信息添加到outBox中

Uri uri = Telephony.Sms.Outbox.addMessage(getContentResolver(), "13146491234", content,
        null, System.currentTimeMillis(), false, getOrCreateThreadId());
onOutboxAddMessage(uri);

//…

private void onOutboxAddMessage(Uri uri) {
    Cursor cursor = getContentResolver().query(uri,
            new String[]{Sms._ID, Sms.THREAD_ID, Sms.TYPE, Sms.BODY, Sms.DATE},
            null, null, null);
    TxrjMessage msg = null;
    if(cursor != null) {
        if(cursor.moveToFirst()) {
            msg = new TxrjMessage();
            msg.setMessageId(cursor.getInt(cursor.getColumnIndex(Sms._ID)));
            msg.setThreadId(cursor.getInt(cursor.getColumnIndex(Sms.THREAD_ID)));
            msg.setType(cursor.getInt(cursor.getColumnIndex(Sms.TYPE)));
            msg.setBody(cursor.getString(cursor.getColumnIndex(Sms.BODY)));
            msg.setTime(cursor.getLong(cursor.getColumnIndex(Sms.DATE)));
            mMessages.add(msg);
            mListAdapter.notifyDataSetChanged();
            if(!uriMap.containsKey(msg.getMessageId())){
                uriMap.put(msg.getMessageId(), uri);
            }
        }
        cursor.close();
    }
}

注冊ContentObserver需要API至少是16

Call requires API level 16 (current min is 11): android.database.ContentObserver#onChange

private void onMsgStatusChanged(Uri uri, int msgId) {
    ContentObserver observer = new ContentObserver(null) {
        @Override
        public void onChange(boolean selfChange, Uri uri) {
            super.onChange(selfChange, uri);
        }
    };
    getContentResolver().registerContentObserver(uri, false, observer);
}

實現onMsgStatusChanged()

private void onMsgStatusChanged(final Uri uri, final int msgId) {
    final Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            mListAdapter.notifyDataSetChanged();
            mListView.setSelection(mListView.getBottom());
        }
    };
    ContentObserver observer = new ContentObserver(null) {
        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            Cursor cursor = getContentResolver().query(uri,
                    new String[]{Sms._ID, Sms.THREAD_ID, Sms.TYPE, Sms.BODY, Sms.DATE},
                    null, null, null);
            if(cursor != null) {
                if(cursor.moveToFirst()) {
                    int type = cursor.getInt(cursor.getColumnIndex(Sms.TYPE));
                    for (int i = mMessages.size() - 1; i >= 0; i--) {
                        if(mMessages.get(i).getMessageId() == msgId) {
                            mMessages.get(i).setType(type);
                            break;
                        }
                    }
                    handler.sendMessage(handler.obtainMessage());
                    getContentResolver().unregisterContentObserver(this);
                }
                cursor.close();
            }
        }
    };
    getContentResolver().registerContentObserver(uri, false, observer);
}

發送信息成功或失敗時修改信息狀態

private void updateMsgType(Uri uri, int type) {
    ContentValues values = new ContentValues();
    values.put(Sms.TYPE, type);
    getContentResolver().update(uri, values, null, null);
}

private PendingIntent getSentIntent(final Uri uri) {
    BroadcastReceiver receiver = new BroadcastReceiver(){

        @Override
        public void onReceive(Context context, Intent intent) {
            int resultCode = getResultCode();
            if(resultCode == RESULT_OK) {
                Toast.makeText(context, "send message success.", Toast.LENGTH_SHORT).show();
                Log.i("txrjsms", "send message success.");
                updateMsgType(uri, Sms.MESSAGE_TYPE_SENT);
            } else if(resultCode == SmsManager.RESULT_ERROR_GENERIC_FAILURE) {
                Toast.makeText(context, "Generic failure.", Toast.LENGTH_SHORT).show();
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);
            } else if(resultCode == SmsManager.RESULT_ERROR_NO_SERVICE) {
                Toast.makeText(context, "service is currently unavailable.", Toast.LENGTH_SHORT).show();
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);
            } else if(resultCode == SmsManager.RESULT_ERROR_NULL_PDU) {
                Toast.makeText(context, "no pdu provided.", Toast.LENGTH_SHORT).show();
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);
            } else if(resultCode == SmsManager.RESULT_ERROR_RADIO_OFF) {
                Toast.makeText(context, "radio was explicitly turned off.", Toast.LENGTH_SHORT).show();
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);
            }
        }
    };
    IntentFilter filter = new IntentFilter(TxrjConstant.ACTION_SEND_SMS);
    mContext.registerReceiver(receiver, filter);
    Intent sentIntent = new Intent(TxrjConstant.ACTION_SEND_SMS);
    return PendingIntent.getBroadcast(mContext, 0, sentIntent, 0);
}


發送短信代碼

private void sendMessage(String destAddr, String content) {
    SmsManager smsManager = SmsManager.getDefault();
    List<String> divideContents = smsManager.divideMessage(content);
    for (String text : divideContents) {
        Log.i("txrjsms", "send msg to " + destAddr + ", content:\n" + text);
        smsManager.sendTextMessage(destAddr, null, text, getSentIntent(),
                getDeliveryIntent());
    }
}

private PendingIntent getSentIntent() {
    Intent sentIntent = new Intent(TxrjConstant.ACTION_SEND_SMS);
    BroadcastReceiver receiver = new BroadcastReceiver(){

        @Override
        public void onReceive(Context context, Intent intent) {
            int resultCode = getResultCode();
            if(resultCode == RESULT_OK) {
                Toast.makeText(context, "send Msg success.", Toast.LENGTH_SHORT).show();
                Log.i("txrjsms", "send Msg success.");
            } else if(resultCode == SmsManager.RESULT_ERROR_GENERIC_FAILURE) {
            } else if(resultCode == SmsManager.RESULT_ERROR_NO_SERVICE) {
            } else if(resultCode == SmsManager.RESULT_ERROR_NULL_PDU) {
            } else if(resultCode == SmsManager.RESULT_ERROR_RADIO_OFF) {
            }
        }
    };
    IntentFilter filter = new IntentFilter(TxrjConstant.ACTION_SEND_SMS);
    mContext.registerReceiver(receiver, filter);
    return PendingIntent.getBroadcast(mContext, 0, sentIntent, 0);
}

private PendingIntent getDeliveryIntent() {
    Intent deliveryIntent = new Intent(TxrjConstant.ACTION_DELIVERY_SMS);
    BroadcastReceiver receiver = new BroadcastReceiver(){

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "message arrived.", Toast.LENGTH_SHORT).show();
            Log.i("txrjsms", "message arrived.");
        }
    };
    IntentFilter filter = new IntentFilter(TxrjConstant.ACTION_DELIVERY_SMS);
    mContext.registerReceiver(receiver, filter);
    return PendingIntent.getBroadcast(mContext, 0, deliveryIntent, 0);
}

發送短信LOG

07-14 16:58:29.746: I/txrjsms(4782): send msg to 10010, content:
07-14 16:58:29.746: I/txrjsms(4782): 102
07-14 16:58:29.906: I/txrjsms(4782): send msg to 10011, content:
07-14 16:58:29.906: I/txrjsms(4782): 102
07-14 16:58:33.620: I/txrjsms(4782): send Msg success.
07-14 16:58:33.650: I/txrjsms(4782): send Msg success.
07-14 16:58:36.583: I/txrjsms(4782): message arrived.
07-14 16:58:36.583: I/txrjsms(4782): message arrived.
07-14 16:58:37.554: I/txrjsms(4782): send Msg success.
07-14 16:58:37.564: I/txrjsms(4782): send Msg success.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM