今天我和同學們討論一下Android平台下如何調用系統方法發送短信、接收短信、系統的短信庫相關的問題。進入正題,我們先使用Eclipse工具模擬給自己的模擬器發送一條短信。在Eclipse下打開DDMS
Incoming number: 這裡須要填寫的是發件人的手機號碼,這裡只能輸入數字否則會無法發送。
Message: 這裡為發送的內容
send: 上面兩項都填寫完畢點擊發送鍵可以給模擬器發送短信。
點擊發送後,模擬器中就可以看到自己收到了一條消息 發件人的號碼為123456 發送內容為hello。收到短信後會將這條信息寫入系統的短信庫,下面我們分析分析Android系統的短信庫的結構。
系統的短信庫存在data/data/com.android.providers.telephony/databases/mmssms.db 下圖藍框中就是模擬器的短信庫,我們將它打開看看裡面存的是什麼東東。
打開mmssms.db 在打開sms表 因為所有短信數據都儲存在這張表上,下面分析一下這張表的字段。
_id 不用說了吧,標示它的唯一性
thread_id :這個字段很重要,同一個會話中他們的thread_id是一樣的,也就是說通過thread_id就可以知道A與B在聊天 還是 A與C在聊天
date :這條消息發送或接收的時間
read: 0 表示未讀 1表示已讀
type : 1表示接收 2 表示發出
body 表示 消息的內容
我給12345回一條消息我們會看的更清楚這些節點的意義。
我們再看看thread_id指向的thread表
上圖中可以清晰的看到 收到消息與回復消息的thread_id都為1 ,那麼在thread_id這張表中_id 不用說了吧,標示它的唯一性
date:表示最後接收或者發送消息的時間
message_count:表示發送消息的數量,這裡我接收到了一條消息 也回復了一條消息那麼它的數量就為2
recipient_ids:聯系人ID,指向表 canonical_addresses 裡的id。
snippet :最後收到或者發送的消息內容,就是上圖body中存的東西
這麼看來如果須要短信庫中的數據就去訪問數據庫中的這兩張表,sms表 uri 指向的是 “content://mms-sms/” thread表 uri指向的是”content://mms-sms/threadID” 具體訪問的方法請看之前數據庫的文章這裡就不詳細的說了。下面進入本章代碼部分的正題,調用系統方法給聯系人號碼發送消息
/**
* 參數說明
* destinationAddress:收信人的手機號碼
* scAddress:發信人的手機號碼
* text:發送信息的內容
* sentIntent:發送是否成功的回執,用於監聽短信是否發送成功。
* DeliveryIntent:接收是否成功的回執,用於監聽短信對方是否接收成功。
*/這裡我主要說一下最後兩個參數, SentIntent 這個intent用於接收這條信息自己發送成功還是自己發送失敗, DeliveryIntent這個intent用於對方是否接受成功。 發送成功和接受成功是不一樣的,發送只是把消息發到手機移動或聯通運行商那裡叫發送成功,至於以後怎麼處理它不關心,只管發送是否成功。 而接受成功表示接受者是否將這條消息收到。
Java代碼
- private void sendSMS(String phoneNumber, String message) {
- // ---sends an SMS message to another device---
- SmsManager sms = SmsManager.getDefault();
-
- // create the sentIntent parameter
- Intent sentIntent = new Intent(SENT_SMS_ACTION);
- PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sentIntent,
- 0);
-
- // create the deilverIntent parameter
- Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);
- PendingIntent deliverPI = PendingIntent.getBroadcast(this, 0,
- deliverIntent, 0);
-
- //如果短信內容超過70個字符 將這條短信拆成多條短信發送出去
- if (message.length() > 70) {
- ArrayList<String> msgs = sms.divideMessage(message);
- for (String msg : msgs) {
- sms.sendTextMessage(phoneNumber, null, msg, sentPI, deliverPI);
- }
- } else {
- sms.sendTextMessage(phoneNumber, null, message, sentPI, deliverPI);
- }
- }
注冊 接收成功 或者發送成功的廣播
Java代碼
- // 注冊廣播 發送消息
- registerReceiver(sendMessage, new IntentFilter(SENT_SMS_ACTION));
- registerReceiver(receiver, new IntentFilter(DELIVERED_SMS_ACTION));
注冊後 在BroadcaseRecevice中可以接收到發送 接收相關的廣播
Java代碼
- private BroadcastReceiver sendMessage = new BroadcastReceiver() {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- //判斷短信是否發送成功
- switch (getResultCode()) {
- case Activity.RESULT_OK:
- Toast.makeText(context, "短信發送成功", Toast.LENGTH_SHORT).show();
- break;
- default:
- Toast.makeText(mContext, "發送失敗", Toast.LENGTH_LONG).show();
- break;
- }
- }
- };
-
- private BroadcastReceiver receiver = new BroadcastReceiver() {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- //表示對方成功收到短信
- Toast.makeText(mContext, "對方接收成功",Toast.LENGTH_LONG).show();
- }
- };
下面給出這個小例子的完整代碼
Java代碼
- import java.util.ArrayList;
-
- import android.app.Activity;
- import android.app.PendingIntent;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.telephony.SmsManager;
- import android.text.TextUtils;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.Toast;
-
- public class ContactsActivity extends Activity {
-
- /**發送按鈕**/
- Button button = null;
-
- /**收件人電話**/
- EditText mNumber = null;
-
- /**編輯信息**/
- EditText mMessage = null;
-
- /**發送與接收的廣播**/
- String SENT_SMS_ACTION = "SENT_SMS_ACTION";
- String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";
-
- Context mContext = null;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.message);
-
- button = (Button) findViewById(R.id.button);
- mNumber = (EditText) findViewById(R.id.number);
- mMessage = (EditText) findViewById(R.id.message);
-
- mContext = this;
- button.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View view) {
-
- /** 拿到輸入的手機號碼 **/
- String number = mNumber.getText().toString();
- /** 拿到輸入的短信內容 **/
- String text = mMessage.getText().toString();
-
- /** 手機號碼 與輸入內容 必需不為空 **/
- if (!TextUtils.isEmpty(number) && !TextUtils.isEmpty(text)) {
- sendSMS(number, text);
- }
- }
- });
-
- // 注冊廣播 發送消息
- registerReceiver(sendMessage, new IntentFilter(SENT_SMS_ACTION));
- registerReceiver(receiver, new IntentFilter(DELIVERED_SMS_ACTION));
-
- }
-
- private BroadcastReceiver sendMessage = new BroadcastReceiver() {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- //判斷短信是否發送成功
- switch (getResultCode()) {
- case Activity.RESULT_OK:
- Toast.makeText(context, "短信發送成功", Toast.LENGTH_SHORT).show();
- break;
- default:
- Toast.makeText(mContext, "發送失敗", Toast.LENGTH_LONG).show();
- break;
- }
- }
- };
-
- private BroadcastReceiver receiver = new BroadcastReceiver() {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- //表示對方成功收到短信
- Toast.makeText(mContext, "對方接收成功",Toast.LENGTH_LONG).show();
- }
- };
-
- /**
- * 參數說明
- * destinationAddress:收信人的手機號碼
- * scAddress:發信人的手機號碼
- * text:發送信息的內容
- * sentIntent:發送是否成功的回執,用於監聽短信是否發送成功。
- * DeliveryIntent:接收是否成功的回執,用於監聽短信對方是否接收成功。
- */
- private void sendSMS(String phoneNumber, String message) {
- // ---sends an SMS message to another device---
- SmsManager sms = SmsManager.getDefault();
-
- // create the sentIntent parameter
- Intent sentIntent = new Intent(SENT_SMS_ACTION);
- PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sentIntent,
- 0);
-
- // create the deilverIntent parameter
- Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);
- PendingIntent deliverPI = PendingIntent.getBroadcast(this, 0,
- deliverIntent, 0);
-
- //如果短信內容超過70個字符 將這條短信拆成多條短信發送出去
- if (message.length() > 70) {
- ArrayList<String> msgs = sms.divideMessage(message);
- for (String msg : msgs) {
- sms.sendTextMessage(phoneNumber, null, msg, sentPI, deliverPI);
- }
- } else {
- sms.sendTextMessage(phoneNumber, null, message, sentPI, deliverPI);
- }
- }
-
- }
一定要在AndroidManifest.xml中添加發送短信的權限噢。
XML/HTML代碼
- <!--取得發短信的權限 -->
- <uses-permission android:name="android.permission.SEND_SMS" />
發送完消息後打開手機的發信箱發現沒有看到剛才發的消息,這是為什麼呢? 是這樣的。調用sendTextMessage 確實是發送消息 ,但是系統的短信庫中沒有這條消息 所以就看不到了。如果想要在系統的短信庫中看到消息就必需把這條消息插到系統的短信庫。
下面這段代碼在發短信的同時也將短信內容寫入系統庫,這樣在發件箱中就可以看到我們發送的短信了。
Java代碼
- button.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View view) {
-
- /** 拿到輸入的手機號碼 **/
- String number = mNumber.getText().toString();
- /** 拿到輸入的短信內容 **/
- String text = mMessage.getText().toString();
-
- /** 手機號碼 與輸入內容 必需不為空 **/
- if (!TextUtils.isEmpty(number) && !TextUtils.isEmpty(text)) {
- sendSMS(number, text);
-
- /**將發送的短信插入數據庫**/
- ContentValues values = new ContentValues();
- //發送時間
- values.put("date", System.currentTimeMillis());
- //閱讀狀態
- values.put("read", 0);
- //1為收 2為發
- values.put("type", 2);
- //送達號碼
- values.put("address", number);
- //送達內容
- values.put("body", text);
- //插入短信庫
- getContentResolver().insert(Uri.parse("content://sms"),values);
-
- }
- }
- });
還是一定要在AndroidManifest.xml中添加相關的權限噢。
XML/HTML代碼
- <!-- 發送消息-->
- <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.RECEIVE_SMS" />
源碼下載地址:http://vdisk.weibo.com/s/aa524