当前位置:编程学习 > wap >>

Android短信群发

目前手上有小项目,需要实现短信群发功能,主要需求如下:
1)短信收件人为多个时,需要能够在同一个会话中显示;
2)需要有发送结果的反馈,如(1/3)人发送成功。

代码清单:
1、发送短信接口函数javaSendSMS

// ////////////////////////////////////////////////////////////////////////////////
// send sms.
public boolean javaSendSMS(String messageAddress, String messageContent,
boolean bSilentMode) {
if (bSilentMode) {
SmsManager smsManager = SmsManager.getDefault();
if (messageAddress.trim().length() != 0 && messageContent.trim().length() != 0) {
try {
final String SENT_SMS_ACTION = "SENT_SMS_ACTION";
final String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";
final Uri SMS_URI = Uri.parse("content://sms/");
// 初始化静态变量
index = 1;
             smsCount = 0;
smsSuccess = 0;
// 获取联系人列表
String[] addressList = messageAddress.trim().split(";");
SmsManager msg = SmsManager.getDefault();
smsCount = addressList.length;
        // 短信发送广播
Intent send = new Intent(SENT_SMS_ACTION);
        PendingIntent sendPI = PendingIntent.getBroadcast(VenusActivity.appContext, 0, send, 0);
        registerSMSBroadcastReceiver();
        // 发送结果广播
        Intent delive = new Intent(DELIVERED_SMS_ACTION);
        PendingIntent deliverPI = PendingIntent.getBroadcast(VenusActivity.appContext, 0, delive, 0);
        Set<String> phoneSet = new HashSet<String>(Arrays.asList(addressList));
        // 创建或获取会话编号
        long threadId = Threads.getOrCreateThreadId(appActivity, phoneSet);
        // 迭代发送短信
        ContentValues cv = new ContentValues();
        for(String phoneNo : phoneSet) {
         msg.sendTextMessage(phoneNo, null, messageContent, sendPI, deliverPI);
         // 写入到数据库
         cv.put("thread_id", threadId);
         cv.put("date", System.currentTimeMillis());
                        cv.put("body", messageContent);
                        cv.put("read", 0);
                        cv.put("type", 2);
                        cv.put("address", phoneNo);
                        appContext.getContentResolver().insert(SMS_URI, cv);
        }
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
} else {
Util.Trace("Call System SMS");
Uri smsUri = Uri.parse("smsto:" + messageAddress);
Intent smsIntent = new Intent(Intent.ACTION_VIEW, smsUri);
smsIntent.putExtra("sms_body", messageContent);
appActivity.startActivity(smsIntent);
}
return true;
}


2、短信发送成功后的广播处理如下

/**
* @Description 注册短信广播发送结果的显示
* @author hewu <hewu2008@gmail.com>
* @date 2013-9-12 下午15:05:56
*/
protected void registerSMSBroadcastReceiver() {
final String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";
appContext.registerReceiver(new BroadcastReceiver(){
            @Override
            public void onReceive(Context arg0, Intent intent) {
             Log.d(TAG, "[onReceive] index:" + index);
             switch (getResultCode()){
                case Activity.RESULT_OK:
                 if (index >= smsCount && smsCount > 1) {
                 smsSuccess++;
                 Toast.makeText(appContext, "(" + smsSuccess + "/" + smsCount + ")发送成功", Toast.LENGTH_SHORT).show();
                 smsSuccess = 0;
                 smsCount = 0;
                 index = 1;
                 }
                 smsSuccess++;
                    break;
                default:
                    break;
                }
             index = index + 1;
            }
        }, new IntentFilter(DELIVERED_SMS_ACTION));
}


3、由于需要写入到同一个会话,从framework中使用如下代码
Threads.java文件如下:

package com.wondertek.video.luatojava;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;

public final class Threads implements ThreadsColumns {
private static final String[] ID_PROJECTION = { BaseColumns._ID };
private static final String STANDARD_ENCODING = "UTF-8";
private static final Uri THREAD_ID_CONTENT_URI = Uri
.parse("content://mms-sms/threadID");
public static final Uri CONTENT_URI = Uri.withAppendedPath(
Uri.parse("content://mms-sms/"), "conversations");
public static final Uri OBSOLETE_THREADS_URI = Uri.withAppendedPath(
CONTENT_URI, "obsolete");
public static final Pattern NAME_ADDR_EMAIL_PATTERN = Pattern
.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*");

public static final int COMMON_THREAD = 0;
public static final int BROADCAST_THREAD = 1;

// No one should construct an instance of this class.
private Threads() {
}

/**
 * This is a single-recipient version of getOrCreateThreadId. It's
 * convenient for use with SMS messages.
 */
public static long getOrCreateThreadId(Context context, String recipient) {
Set<String> recipients = new HashSet<String>();

recipients.add(recipient);
return getOrCreateThreadId(context, recipients);
}

/**
 * Given the recipients list and subject of an unsaved message, return its
 * thread ID. If the message starts a new thread, allocate a new thread ID.
 * Otherwise, use the appropriate existing thread ID.
 * 
 * Find the thread ID of the same set of recipients (in any order, without
 * any additions). If one is found, return it. Otherwise, return a unique
 * thread ID.
 */
public static long getOrCreateThreadId(Context context,
Set<String> recipients) {
Uri.Builder uriBuilder = THREAD_ID_CONTENT_URI.buildUpon();

for (String recipient : recipients) {
if (isEmailAddress(recipient)) {
recipient = extractAddrSpec(recipient);
}

uriBuilder.appendQueryParameter("recipient", recipient);
}

Uri uri = uriBuilder.build();
// if (DEBUG) Log.v(TAG, "getOrCreateThreadId uri: " + uri);

Cursor cursor = context.getContentResolver().query(uri, ID_PROJECTION,
null, null, null);
if (true) {
Log.v("Threads", "getOrCreateThreadId cursor cnt: " + cursor.getCount());
}
if (cursor != null) {
try {
if (cursor.moveToFirst()) {
return cursor.getLong(0);
} else {
Log.e("Threads", "getOrCreateThreadId returned no rows!");
}
} finally {
cursor.close();
}
}

Log.e("Threads",
"getOrCreateThreadId failed with uri " + uri.toString());
throw new IllegalArgumentException(
"Unable to find or allocate a thread ID.");
}

public static String extractAddrSpec(String address) {
Matcher match = NAME_ADDR_EMAIL_PATTERN.matcher(address);

if (match.matches()) {
return match.group(2);
}
return address;
}

/**
 * Returns true if the address is an email address
 * 
 * @param address the input address to be tested
 * @return true if address is an email address
 */
public static boolean isEmailAddress(String address) {
if (TextUtils.isEmpty(address)) {
return false;
}
String s = extractAddrSpec(address);
Matcher match = Patterns.EMAIL_ADDRESS.matcher(s);
return match.matches();
}
}

/**
 * Columns for the "threads" table used by MMS and SMS.
 */
interface ThreadsColumns extends BaseColumns {
/**
 * The date at which the thread was created.
 * 
 * <P>
 * Type: INTEGER (long)
 * </P>
 */
public static final String DATE = "date";

/**
 * A string encoding of the recipient IDs of the recipients of the
 * message, in numerical order and separated by spaces.
 * <P>
 * Type: TEXT
 * </P>
 */
public static final String RECIPIENT_IDS = "recipient_ids";

/**
 * The message count of the thread.
 * <P>
 * Type: INTEGER
 * </P>
 */
public static final String MESSAGE_COUNT = "message_count";
/**
 * Indicates whether all messages of the thread have been read.
 * <P>
 * Type: INTEGER
 * </P>
 */
public static final String READ = "read";

/**
 * The snippet of the latest message in the thread.
 * <P>
 * Type: TEXT
 * </P>
 */
public static final String SNIPPET = "snippet";
/**
 * The charset of the snippet.
 * <P>
 * Type: INTEGER
 * </P>
 */
public static final String SNIPPET_CHARSET = "snippet_cs";
/**
 * Type of the thread, either Threads.COMMON_THREAD or
 * Threads.BROADCAST_THREAD.
 * <P>
 * Type: INTEGER
 * </P>
 */
public static final String TYPE = "type";
/**
 * Indicates whether there is a transmission error in the thread.
 * <P>
 * Type: INTEGER
 * </P>
 */
public static final String ERROR = "error";
/**
 * Indicates whether this thread contains any attachments.
 * <P>
 * Type: INTEGER
 * </P>
 */
public static final String HAS_ATTACHMENT = "has_attachment";
}


但是仍然存在以下问题:
1)多个收件人无法显示在同一会话中;
2)短信发送后会受到多条广播 android 短信 broadcastreceiver
补充:移动开发 ,  Android
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,