Android 彩信發送的兩種方式
第一種:直接調用彩信發送接口
實現代碼如下,
Intent intent = new Intent(Intent.ACTION_SEND); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(Intent.EXTRA_STREAM, Uri.parse(url));// uri為你的附件的uri intent.putExtra("subject", "it's subject"); //彩信的主題 intent.putExtra("address", "10086"); //彩信發送目的號碼 intent.putExtra("sms_body", "it's content"); //彩信中文字內容 intent.putExtra(Intent.EXTRA_TEXT, "it's EXTRA_TEXT"); intent.setType("image/*");// 彩信附件類型 intent.setClassName("com.android.mms","com.android.mms.ui.ComposeMessageActivity"); startActivity(intent);
看到彩信發送的代碼,跟短信發送的代碼有很大的不同,彩信發送不同於短信發送,調用系統的彩信發送會出現發送界面。
有朋友就要問了,這樣不適合我的需求,我需要實現自定義彩信發送,並且不調用系統彩信。第二種方法將滿足我們的需求
第二種:自定義彩信發送
自定義彩信發送,無需進入彩信發送界面,需要調用系統源碼 PDU 實現。
首先給出發送代碼
//彩信發送函數 public static void sendMMS(final Context context, String number, String subject, String text, String imagePath, String audioPath) { final MMSInfo mmsInfo = new MMSInfo(context, number, subject, text, imagePath, audioPath); final List<String> list = APNManager.getSimMNC(context); new Thread() { @Override public void run() { try { byte[] res = MMSSender.sendMMS(context, list, mmsInfo.getMMSBytes()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }; }.start(); }
APNManager.getSimMNC 用來設置 彩信Url和代理端口
MMSSender.sendMMS 實現彩信的發送
APNManager類源代碼

package com.rayray.util; import java.util.ArrayList; import java.util.List; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; public class APNManager { // 電信彩信中心url,代理,端口 public static String mmscUrl_ct = "http://mmsc.vnet.mobi"; public static String mmsProxy_ct = "10.0.0.200"; // 移動彩信中心url,代理,端口 public static String mmscUrl_cm = "http://mmsc.monternet.com"; public static String mmsProxy_cm = "10.0.0.172"; // 聯通彩信中心url,代理,端口 public static String mmscUrl_uni = "http://mmsc.vnet.mobi"; public static String mmsProxy_uni = "10.0.0.172"; private static String TAG = "APNManager"; private static final Uri APN_TABLE_URI = Uri .parse("content://telephony/carriers");// 所有的APN配配置信息位置 private static final Uri PREFERRED_APN_URI = Uri .parse("content://telephony/carriers/preferapn");// 當前的APN private static String[] projection = { "_id", "apn", "type", "current", "proxy", "port" }; private static String APN_NET_ID = null; private static String APN_WAP_ID = null; public static List<String> getSimMNC(Context context) { TelephonyManager telManager = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); String imsi = telManager.getSubscriberId(); if (imsi != null) { ArrayList<String> list = new ArrayList<String>(); if (imsi.startsWith("46000") || imsi.startsWith("46002")) { // 因為移動網絡編號46000下的IMSI已經用完,所以虛擬了一個46002編號,134/159號段使用了此編號 // 中國移動 list.add(mmscUrl_cm); list.add(mmsProxy_cm); } else if (imsi.startsWith("46001")) { // 中國聯通 list.add(mmscUrl_uni); list.add(mmsProxy_uni); } else if (imsi.startsWith("46003")) { // 中國電信 list.add(mmscUrl_ct); list.add(mmsProxy_ct); } shouldChangeApn(context); return list; } return null; } private static boolean shouldChangeApn(final Context context) { final String wapId = getWapApnId(context); String apnId = getCurApnId(context); // 若當前apn不是wap,則切換至wap if (!wapId.equals(apnId)) { APN_NET_ID = apnId; setApn(context, wapId); // 切換apn需要一定時間,先讓等待2秒 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return true; } return false; } public static boolean shouldChangeApnBack(final Context context) { // 彩信發送完畢后檢查是否需要把接入點切換回來 if (null != APN_NET_ID) { setApn(context, APN_NET_ID); return true; } return false; } // 切換成NETAPN public static boolean ChangeNetApn(final Context context) { final String wapId = getWapApnId(context); String apnId = getCurApnId(context); // 若當前apn是wap,則切換至net if (wapId.equals(apnId)) { APN_NET_ID = getNetApnId(context); setApn(context, APN_NET_ID); // 切換apn需要一定時間,先讓等待幾秒,與機子性能有關 try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } Log.d("xml", "setApn"); return true; } return true; } // 切換成WAPAPN public static boolean ChangeWapApn(final Context context) { final String netId = getWapApnId(context); String apnId = getCurApnId(context); // 若當前apn是net,則切換至wap if (netId.equals(apnId)) { APN_WAP_ID = getNetApnId(context); setApn(context, APN_WAP_ID); // 切換apn需要一定時間,先讓等待幾秒,與機子性能有關 try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } Log.d("xml", "setApn"); return true; } return true; } // 獲取當前APN public static String getCurApnId(Context context) { ContentResolver resoler = context.getContentResolver(); // String[] projection = new String[] { "_id" }; Cursor cur = resoler.query(PREFERRED_APN_URI, projection, null, null, null); String apnId = null; if (cur != null && cur.moveToFirst()) { apnId = cur.getString(cur.getColumnIndex("_id")); } Log.i("xml", "getCurApnId:" + apnId); return apnId; } public static APN getCurApnInfo(final Context context) { ContentResolver resoler = context.getContentResolver(); // String[] projection = new String[] { "_id" }; Cursor cur = resoler.query(PREFERRED_APN_URI, projection, null, null, null); APN apn = new APN(); if (cur != null && cur.moveToFirst()) { apn.id = cur.getString(cur.getColumnIndex("_id")); apn.apn = cur.getString(cur.getColumnIndex("apn")); apn.type = cur.getString(cur.getColumnIndex("type")); } return apn; } public static void setApn(Context context, String id) { ContentResolver resolver = context.getContentResolver(); ContentValues values = new ContentValues(); values.put("apn_id", id); resolver.update(PREFERRED_APN_URI, values, null, null); Log.d("xml", "setApn"); } // 獲取WAP APN public static String getWapApnId(Context context) { ContentResolver contentResolver = context.getContentResolver(); // 查詢cmwapAPN Cursor cur = contentResolver.query(APN_TABLE_URI, projection, "apn = \'cmwap\' and current = 1", null, null); // wap APN 端口不為空 if (cur != null && cur.moveToFirst()) { do { String id = cur.getString(cur.getColumnIndex("_id")); String proxy = cur.getString(cur.getColumnIndex("proxy")); if (!TextUtils.isEmpty(proxy)) { Log.i("xml", "getWapApnId" + id); return id; } } while (cur.moveToNext()); } return null; } public static String getNetApnId(Context context) { ContentResolver contentResolver = context.getContentResolver(); Cursor cur = contentResolver.query(APN_TABLE_URI, projection, "apn = \'cmnet\' and current = 1", null, null); if (cur != null && cur.moveToFirst()) { return cur.getString(cur.getColumnIndex("_id")); } return null; } // 獲取所有APN public static ArrayList<APN> getAPNList(final Context context) { ContentResolver contentResolver = context.getContentResolver(); Cursor cr = contentResolver.query(APN_TABLE_URI, projection, null, null, null); ArrayList<APN> apnList = new ArrayList<APN>(); if (cr != null && cr.moveToFirst()) { do { Log.d(TAG, cr.getString(cr.getColumnIndex("_id")) + ";" + cr.getString(cr.getColumnIndex("apn")) + ";" + cr.getString(cr.getColumnIndex("type")) + ";" + cr.getString(cr.getColumnIndex("current")) + ";" + cr.getString(cr.getColumnIndex("proxy"))); APN apn = new APN(); apn.id = cr.getString(cr.getColumnIndex("_id")); apn.apn = cr.getString(cr.getColumnIndex("apn")); apn.type = cr.getString(cr.getColumnIndex("type")); apnList.add(apn); } while (cr.moveToNext()); cr.close(); } return apnList; } // 獲取可用的APN public static ArrayList<APN> getAvailableAPNList(final Context context) { // current不為空表示可以使用的APN ContentResolver contentResolver = context.getContentResolver(); Cursor cr = contentResolver.query(APN_TABLE_URI, projection, "current is not null", null, null); ArrayList<APN> apnList = new ArrayList<APN>(); if (cr != null && cr.moveToFirst()) { do { Log.d(TAG, cr.getString(cr.getColumnIndex("_id")) + ";" + cr.getString(cr.getColumnIndex("apn")) + ";" + cr.getString(cr.getColumnIndex("type")) + ";" + cr.getString(cr.getColumnIndex("current")) + ";" + cr.getString(cr.getColumnIndex("proxy"))); APN apn = new APN(); apn.id = cr.getString(cr.getColumnIndex("_id")); apn.apn = cr.getString(cr.getColumnIndex("apn")); apn.type = cr.getString(cr.getColumnIndex("type")); apnList.add(apn); } while (cr.moveToNext()); cr.close(); } return apnList; } // 自定義APN包裝類 static class APN { String id; String apn; String type; @Override public String toString() { return "id=" + id + ",apn=" + apn + ";type=" + type; } } }
MMSSender類源代碼

//發送類 package com.rayray.util; import java.io.DataInputStream; import java.io.IOException; import java.net.SocketException; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.params.ConnRoutePNames; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; import android.content.Context; import android.util.Log; /** * @author * @version 創建時間:2012-2-1 上午09:32:54 */ public class MMSSender { private static final String TAG = "MMSSender"; // public static String mmscUrl = "http://mmsc.monternet.com"; // public static String mmscProxy = "10.0.0.172"; public static int mmsProt = 80; private static String HDR_VALUE_ACCEPT_LANGUAGE = ""; private static final String HDR_KEY_ACCEPT = "Accept"; private static final String HDR_KEY_ACCEPT_LANGUAGE = "Accept-Language"; private static final String HDR_VALUE_ACCEPT = "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic"; public static byte[] sendMMS(Context context, List<String> list, byte[] pdu) throws IOException { System.out.println("進入sendMMS方法"); // HDR_VALUE_ACCEPT_LANGUAGE = getHttpAcceptLanguage(); HDR_VALUE_ACCEPT_LANGUAGE = HTTP.UTF_8; String mmsUrl = (String) list.get(0); String mmsProxy = (String) list.get(1); if (mmsUrl == null) { throw new IllegalArgumentException("URL must not be null."); } HttpClient client = null; try { // Make sure to use a proxy which supports CONNECT. // client = HttpConnector.buileClient(context); HttpHost httpHost = new HttpHost(mmsProxy, mmsProt); HttpParams httpParams = new BasicHttpParams(); httpParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, httpHost); HttpConnectionParams.setConnectionTimeout(httpParams, 10000); client = new DefaultHttpClient(httpParams); HttpPost post = new HttpPost(mmsUrl); // mms PUD START ByteArrayEntity entity = new ByteArrayEntity(pdu); entity.setContentType("application/vnd.wap.mms-message"); post.setEntity(entity); post.addHeader(HDR_KEY_ACCEPT, HDR_VALUE_ACCEPT); post.addHeader(HDR_KEY_ACCEPT_LANGUAGE, HDR_VALUE_ACCEPT_LANGUAGE); post.addHeader( "user-agent", "Mozilla/5.0(Linux;U;Android 2.1-update1;zh-cn;ZTE-C_N600/ZTE-C_N600V1.0.0B02;240*320;CTC/2.0)AppleWebkit/530.17(KHTML,like Gecko) Version/4.0 Mobile Safari/530.17"); // mms PUD END HttpParams params = client.getParams(); HttpProtocolParams.setContentCharset(params, "UTF-8"); System.out.println("准備執行發送"); // PlainSocketFactory localPlainSocketFactory = // PlainSocketFactory.getSocketFactory(); HttpResponse response = client.execute(post); System.out.println("執行發送結束, 等回執。。"); StatusLine status = response.getStatusLine(); Log.d(TAG, "status " + status.getStatusCode()); if (status.getStatusCode() != 200) { // HTTP 200 表服務器成功返回網頁 Log.d(TAG, "!200"); throw new IOException("HTTP error: " + status.getReasonPhrase()); } HttpEntity resentity = response.getEntity(); byte[] body = null; if (resentity != null) { try { if (resentity.getContentLength() > 0) { body = new byte[(int) resentity.getContentLength()]; DataInputStream dis = new DataInputStream( resentity.getContent()); try { dis.readFully(body); } finally { try { dis.close(); } catch (IOException e) { Log.e(TAG, "Error closing input stream: " + e.getMessage()); } } } } finally { if (entity != null) { entity.consumeContent(); } } } Log.d(TAG, "result:" + new String(body)); System.out.println("成功!!" + new String(body)); return body; } catch (IllegalStateException e) { Log.e(TAG, "", e); // handleHttpConnectionException(e, mmscUrl); } catch (IllegalArgumentException e) { Log.e(TAG, "", e); // handleHttpConnectionException(e, mmscUrl); } catch (SocketException e) { Log.e(TAG, "", e); // handleHttpConnectionException(e, mmscUrl); } catch (Exception e) { Log.e(TAG, "", e); // handleHttpConnectionException(e, mmscUrl); } finally { if (client != null) { // client.; } APNManager.shouldChangeApnBack(context); } return new byte[0]; } }
注意,這里需要從系統源碼中引入 com.google.android.mms包,並將相關引用包調通,才可以使用。
//////////////////////////////////////////////
需要獲取源代碼的朋友,可以通過下面兩種方式獲取
(1)下載地址 http://download.csdn.net/detail/fnext/5228721
(2)請在評論中填寫郵件地址,會通過郵箱發送源碼。
看到大家的反饋,源碼調試有些問題,我抽時間會再更新代碼,請諒解,同時感謝大家的幫助和支持
原創聲明 轉載請注明
本文出自 Ray-Ray的博客
文章地址 http://www.cnblogs.com/rayray/archive/2013/03/11/2954214.html
感謝大家的推薦和收藏
你的支持! 我們的動力!