======================
转载请注明出处,谢谢!
======================
调用该类的send(final Context context, String phone, String subject, String text, String imagePath, String audioPath)方法。
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
代码是最好的注释,请看代码:
import java.io.DataInputStream;
import java.io.File;import java.io.IOException;
import java.net.SocketException;
import java.net.URI;
import java.util.ArrayList;
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.ConnRouteParams;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.net.http.AndroidHttpClient;
import android.os.Handler;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.google.android.mms.ContentType;
import com.google.android.mms.MmsException;
import com.google.android.mms.pdu.EncodedStringValue;
import com.google.android.mms.pdu.PduBody;
import com.google.android.mms.pdu.PduPart;
import com.google.android.mms.pdu.PduPersister;
import com.google.android.mms.pdu.SendReq;
import com.google.android.mms.util.PduCache;
import com.google.android.mms.pdu.CharacterSets;
import com.google.android.mms.pdu.PduComposer;
public class TestMMS {
private static final String TAG = "MMS";
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 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 String APN_NET_ID = null;
private static boolean shouldChangeApn(final Context context) {
final String wapId = getWapApnId(context);
String apnId = getApn(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;
}
private static String getApn(Context context) {
ContentResolver resoler = context.getContentResolver();
String[] projection = new String[] { "_id" };
Cursor cur = resoler.query(Uri.parse("content://telephony/carriers/preferapn"), projection, null, null, null);
String apnId = null;
if (cur != null && cur.moveToFirst()) {
do {
apnId = cur.getString(cur.getColumnIndex("_id"));
} while (cur.moveToNext());
}
return apnId;
}
private static void setApn(Context context, String id) {
Uri uri = Uri.parse("content://telephony/carriers/preferapn");
ContentResolver resolver = context.getContentResolver();
ContentValues values = new ContentValues();
values.put("apn_id", id);
resolver.update(uri, values, null, null);
}
private static String getWapApnId(Context context) {
ContentResolver contentResolver = context.getContentResolver();
String[] projection = new String[] { "_id", "proxy" };
Cursor cur = contentResolver.query(Uri.parse("content://telephony/carriers"), projection, "current = 1", null, null);
if (cur != null && cur.moveToFirst()) {
do {
String id = cur.getString(0);
String proxy = cur.getString(1);
if (!TextUtils.isEmpty(proxy)) {
return id;
}
} while (cur.moveToNext());
}
return null;
}
/**********************************************************/
private static Handler myHandler = new Handler();
private static boolean sendMMMS(List<String> list, final Context context, byte[] pdu) throws Exception {
// HDR_AVLUE_ACCEPT_LANGUAGE = getHttpAcceptLanguage();
boolean result = false;
if (list == null) {
myHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(context, "找不到sim卡", Toast.LENGTH_LONG).show();
}
});
return false;
}
String mmsUrl = (String) list.get(0);
String mmsProxy = (String) list.get(1);
HttpClient client = null;
try {
URI hostUrl = new URI(mmsUrl);
HttpHost target = new HttpHost(hostUrl.getHost(), hostUrl.getPort(), HttpHost.DEFAULT_SCHEME_NAME);
client = AndroidHttpClient.newInstance("Android-Mms/2.0");
Log.d(TAG, "*******************************1");
HttpPost post = new HttpPost(mmsUrl);
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);
Log.d(TAG, "*******************************2");
HttpParams params = client.getParams();
HttpProtocolParams.setContentCharset(params, "UTF-8");
Log.d(TAG, "*******************************3");
ConnRouteParams.setDefaultProxy(params, new HttpHost(mmsProxy, 80));
HttpResponse response = client.execute(target, post);
StatusLine status = response.getStatusLine();
Log.d(TAG, "*******************************4 status= " + status);
if (status.getStatusCode() != 200) {
throw new IOException("HTTP error: " + status.getReasonPhrase());
}
Log.d(TAG, "*******************************6");
// 彩信发送完毕后检查是否需要把接入点切换回来
if (null != APN_NET_ID) {
setApn(context, APN_NET_ID);
}
Log.d(TAG, "*******************************111");
result = true;
Log.d(TAG, "********************************222");
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "彩信发送失败:" + e.getMessage());
Log.d(TAG, "get exception: " + e);
result = false;
} finally {
Log.d(TAG, "to close client");
if (client != null) {
client = null;
}
}
Log.d(TAG, "********************************return result = " + result);
return result;
}
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 void send(final Context context, String phone, String subject, String text, String imagePath, String audioPath) {
SendReq sendRequest = new SendReq();
EncodedStringValue[] sub = EncodedStringValue.extract(subject);
if (sub != null && sub.length > 0) {
sendRequest.setSubject(sub[0]);
}
EncodedStringValue[] phoneNumbers = EncodedStringValue.extract(phone);
if (phoneNumbers != null && phoneNumbers.length > 0) {
sendRequest.addTo(phoneNumbers[0]);
}
PduBody pduBody = new PduBody();
if (!TextUtils.isEmpty(text)) {
PduPart partPdu3 = new PduPart();
partPdu3.setCharset(CharacterSets.UTF_8);
partPdu3.setName("mms_text.txt".getBytes());
partPdu3.setContentType("text/plain".getBytes());
partPdu3.setData(text.getBytes());
pduBody.addPart(partPdu3);
}
if (!TextUtils.isEmpty(imagePath)) {
PduPart partPdu = new PduPart();
partPdu.setCharset(CharacterSets.UTF_8);
partPdu.setName("camera.jpg".getBytes());
partPdu.setContentType("image/png".getBytes());
partPdu.setDataUri(Uri.fromFile(new File(imagePath)));
pduBody.addPart(partPdu);
}
if (!TextUtils.isEmpty(audioPath)) {
PduPart partPdu2 = new PduPart();
partPdu2.setCharset(CharacterSets.UTF_8);
partPdu2.setName("speech_test.amr".getBytes());
partPdu2.setContentType("audio/amr".getBytes());
partPdu2.setDataUri(Uri.fromFile(new File(audioPath)));
pduBody.addPart(partPdu2);
}
sendRequest.setBody(pduBody);
final PduComposer composer = new PduComposer(context, sendRequest);
final byte[] bytesToSend = composer.make();
final List<String> list = getSimMNC(context);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
// 因为在切换apn过程中需要一定时间,所以需要加上一个重试操作
int retry = 0;
do {
Log.d(TAG, "Repeat times:" + (retry + 1));
try {
if (sendMMMS(list, context, bytesToSend)) {
myHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(context, "彩信发送成功!", Toast.LENGTH_LONG).show();
}
});
return;
}
retry++;
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
} while (retry < 5);
myHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(context, "彩信发送失败!", Toast.LENGTH_LONG).show();
}
});
}
});
t.start();
}
}