概括的講,彩信發(fā)送可分為兩步執(zhí)行:
(1)組裝彩信PDU
publicstatic GenericPdu makePdu(Context context,String phone,
Stringsubject, String text, String imagePath, String audioPath) {
SendReq sendReq=new SendReq();
//設(shè)置主題
EncodedStringValue[] sub =EncodedStringValue.extract(subject);
if (sub !=null && sub.length >0) {
sendReq.setSubject(sub[0]);
}
//設(shè)置接收號(hào)碼
EncodedStringValue[] phoneNumbers =EncodedStringValue.extract(phone);
if(phoneNumbers != null &&phoneNumbers.length > 0) {
sendReq.addTo(phoneNumbers[0]);
}
//設(shè)置發(fā)送號(hào)碼
TelephonyManager mTelephonyManager =(TelephonyManager)context.getApplicationContext()
.getSystemService(Context.TELEPHONY_SERVICE);
StringlineNumber =mTelephonyManager.getLine1Number();
if (!TextUtils.isEmpty(lineNumber)) {
sendReq.setFrom(new EncodedStringValue(lineNumber));
}
//設(shè)置PduBody內(nèi)容,對(duì)于圖片/音頻/視頻,不需要保存Data在part里,因?yàn)樗鼈兊匿秩酒髦С諹RI作為數(shù)據(jù)源(setDataUri())。
PduBodypduBody = new PduBody();
if(!TextUtils.isEmpty(text)) {
PduPartpartPdu3 = 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)) {
PduPartpartPdu = new PduPart();
partPdu.setCharset(CharacterSets.UTF_8);//編碼格式
partPdu.setName("aa.jpg".getBytes());
partPdu.setContentType("image/jpeg".getBytes());
//partPdu.setDataUri(Uri.parse("file:///sdcard/aa.bmp"));
partPdu.setDataUri(Uri.fromFile(new File(imagePath)));
pduBody.addPart(partPdu);
}
if(!TextUtils.isEmpty(audioPath)) {
PduPartpartPdu2 = new PduPart();
partPdu2.setCharset(CharacterSets.ISO_8859_1);
partPdu2.setName("speech_test.amr".getBytes());
partPdu2.setContentType("audio/amr".getBytes());
//partPdu2.setContentType("audio/amr-wb".getBytes());
//partPdu2.setDataUri(Uri.parse("file://mnt//sdcard//.lv//audio//1326786209801.amr"));
partPdu2.setDataUri(Uri.fromFile(new File(audioPath)));
pduBody.addPart(partPdu2);
}
sendReq.setBody(pduBody);
returnsendReq;
}
(2)發(fā)送
發(fā)送之前,需要先獲取手機(jī)運(yùn)營(yíng)商主機(jī)地址及訪問地址。
//電信彩信中心url,代理,端口
publicstatic String mmscUrl_ct = "http://mmsc.vnet.mobi";
publicstatic String mmsProxy_ct = "10.0.0.200";
//移動(dòng)彩信中心url,代理,端口
publicstatic String mmscUrl_cm = "http://mmsc.monternet.com";
publicstatic String mmsProxy_cm = "010.000.000.172";
//聯(lián)通彩信中心url,代理,端口
publicstatic String mmscUrl_uni = "http://mmsc.vnet.mobi";
publicstatic String mmsProxy_uni = "10.0.0.172";
//默認(rèn)端口
publicstatic int mmsDefautPort=80;
//獲取服務(wù)商訪問地址及端口
privatestatic List<String> getSimMNC(Contextcontext) {
TelephonyManager telManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
String imsi= telManager.getSubscriberId();
if (imsi !=null) {
ArrayList<String> list = newArrayList<String>();
if(imsi.startsWith("46000") || imsi.startsWith("46002")) {
//因?yàn)橐苿?dòng)網(wǎng)絡(luò)編號(hào)46000下的IMSI已經(jīng)用完,所以虛擬了一個(gè)46002編號(hào),134/159號(hào)段使用了此編號(hào)
//中國(guó)移動(dòng)
list.add(mmscUrl_cm);
list.add(mmsProxy_cm);
} else if(imsi.startsWith("46001")) {
//中國(guó)聯(lián)通
list.add(mmscUrl_uni);
list.add(mmsProxy_uni);
} else if(imsi.startsWith("46003")) {
//中國(guó)電信
list.add(mmscUrl_ct);
list.add(mmsProxy_ct);
}
shouldChangeApn(context);
returnlist;
}
returnnull;
}
privatestatic boolean shouldChangeApn(final Context context) {
final StringwapId = getWapApnId(context);
String apnId= getApn(context);
//若當(dāng)前apn不是wap,則切換至wap
if(!wapId.equals(apnId)) {
APN_NET_ID =apnId;
setApn(context, wapId);
//切換apn需要一定時(shí)間,先讓等待2秒
try {
Thread.sleep(2000);
} catch(InterruptedException e) {
e.printStackTrace();
}
returntrue;
}
returnfalse;
}
privatestatic 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());
}
returnapnId;
}
然后將彩信Pdu轉(zhuǎn)換為byte[]數(shù)組,
final PduComposer composer = new PduComposer(context,sendReq);
final byte[] data = composer.make();
調(diào)用httpConnection()方法發(fā)送出去。
彩信接收:
(1)彩信發(fā)送成功后,MMSC會(huì)以短信息PDU包的形式通知接收方,即彩信通知,接收方獲取彩信提取地址等信息。
(2)接收方從MMSC中提取MMS,并解析PDU數(shù)據(jù)。
public static finalString MMS_RECEIVE_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED";
Stringaction = intent.getAction();
if(acttion.equals(MMS_RECEIVE_ACTION)){
new ReceivePushTask(context).execute(intent);
}
// 彩信預(yù)處理過程
classReceivePushTask extends AsyncTask<Intent, Void,Void> {
publicReceivePushTask(Context context) {
super();
}
@Override
protectedVoid doInBackground(Intent... intents) {
Intentintent = intents[0];
//獲取push-data
// Get rawPDU push-data from the message and parse it
byte[]pushData = intent.getByteArrayExtra("data");
PduParserparser = new PduParser(pushData);
//NotificationInd mNotificationInd;
GenericPdumPdu;
//StringmId;
StringmContentLocation;// 彩信下載地址
byte[]retrieveConfData = null;
try {
//mNotificationInd = (NotificationInd) parser.parse();
mPdu=parser.parse();
//mId = newString(mNotificationInd.getTransactionId());
//mContentLocation = newString(mNotificationInd.getContentLocation());
mContentLocation=mPdu.getPduHeaders().getContentLocation();
Log.d(TAG,"HeadermContentLocation:"+mContentLocation);
Log.d(TAG,"HeaderFrom:"+mPdu.getPduHeaders().getFrom());
//獲取彩信Pdu數(shù)據(jù)
retrieveConfData = getPdu(mContentLocation);
if(retrieveConfData != null) {
GenericPdupdu = new PduParser(retrieveConfData).parse();
PduHeadersheader = pdu.getPduHeaders();

EncodedStringValuesubject=header.getEncodedStringValue(PduHeaders.SUBJECT);
subject.setCharacterSet(CharacterSets.ANY_CHARSET);
Log.d(TAG,"Header主題:"+subject.getString());
Log.d(TAG,"ContentLocation:"+header.getContentLocation());
Log.d(TAG,"From:"+header.getFrom());
Log.d(TAG,"MessageType:"+header.getMessageType());
PduBody body= null;
// Get bodyif the PDU is a RetrieveConf or SendReq.
if (pduinstanceof MultimediaMessagePdu) {
Log.d(TAG,"主題:"+((MultimediaMessagePdu)pdu).getSubject().getString());
body = ((MultimediaMessagePdu) pdu).getBody();
// Start saving parts if necessary.
if (body != null) {
int partsNum= body.getPartsNum();
try {
for(int i=0;i<partsNum;i++){
//獲取附件數(shù)據(jù)
Log.d(TAG,"------------part:"+i+"-------------");
PduPart part =body.getPart(i);
String contentType = toIsoString(part.getContentType());
persistData(part,contentType);
}
} catch(MmsException e) {
e.printStackTrace();
}
}
}
}
} catch(InvalidHeaderValueException e) {
e.printStackTrace();
}
returnnull;
}
}
//請(qǐng)求Url獲取彩信數(shù)據(jù)
publicbyte[] getPdu(String url) {
Log.d("TAG","url:"+url);
try {
returnHttpUtils.httpConnection(mContext, -1L, url, null,
HttpUtils.HTTP_GET_METHOD, true, "10.0.0.172", 80);
} catch(IOException e) {
e.printStackTrace();
returnnull;
}
}
public static byte[] httpConnection(String url,
byte[] pdu,int method, boolean isProxySet, String proxyHost,
intproxyPort) throws IOException {
if (url ==null) {
throw newIllegalArgumentException("URL must not be null.");
}
AndroidHttpClient client = null;// 定義客戶端
try {
URI hostUrl= new URI(url);// 訪問地址
// 主機(jī)
HttpHosttarget = new HttpHost(hostUrl.getHost(),
hostUrl.getPort(), HttpHost.DEFAULT_SCHEME_NAME);
client =AndroidHttpClient.newInstance("Android-Mms/2.0");
HttpRequestreq = null;
switch(method) {
caseHTTP_POST_METHOD:
ByteArrayEntity entity = new ByteArrayEntity(pdu);
// Setrequest content type.
entity.setContentType("application/vnd.wap.mms-message");
HttpPostpost = new HttpPost(url);
post.s--etEntity(entity);
req =post;
break;
caseHTTP_GET_METHOD:
req = newHttpGet(url);
break;
default:
Log.e(TAG,"Unknown HTTP method: " + method
+ ". Must beone of POST[" + HTTP_POST_METHOD
+ "] orGET[" + HTTP_GET_METHOD + "].");
returnnull;
}
HttpParamsparams = client.getParams();
//設(shè)置代理
if(isProxySet) {
ConnRouteParams.setDefaultProxy(params, newHttpHost(proxyHost,
proxyPort));
}
req.setParams(params);
// 必要的 Setnecessary HTTP headers for MMS transmission.
req.addHeader(HDR_KEY_ACCEPT, HDR_VALUE_ACCEPT);
req.addHeader(HDR_KEY_ACCEPT_LANGUAGE,HDR_VALUE_ACCEPT_LANGUAGE);
HttpResponseresponse = client.execute(target, req);
StatusLinestatus = response.getStatusLine();
if(status.getStatusCode() != 200) { // HTTP 200 is success.
throw newIOException("HTTP error: " + status.getReasonPhrase());
}
HttpEntityentity = response.getEntity();
byte[] body= null;
if (entity!= null) {
try {
if(entity.getContentLength() > 0) {
body = newbyte[(int) entity.getContentLength()];
DataInputStream dis = new DataInputStream(
entity.getContent());
try {
dis.readFully(body);
} finally{
try {
dis.close();
} catch(IOException e) {
Log.e(TAG,
"Errorclosing input stream: "
+e.getMessage());
}
}
}
} finally{
if (entity!= null) {
entity.consumeContent();
}
}
}
returnbody;
} catch(Exception e) {
Log.e(TAG,"Url: " + url + "n" + e.getMessage());
} finally{
if (client!= null) {
client.close();
}
}
returnnull;
}
//解析Pdu part
public voidpersistData(PduPart part,String contentType)
throws MmsException {
Log.d(TAG,"ContentType:"+contentType);
FileOutputStream os = null;
try {
byte[] data = part.getData();
if (ContentType.TEXT_PLAIN.equals(contentType)
|| ContentType.APP_SMIL.equals(contentType)
|| ContentType.TEXT_HTML.equals(contentType)) {
String partText= new EncodedStringValue(data).getString();
Log.d(TAG, "Text:"+partText);
} else {
os = new FileOutputStream(new File("/sdcard/temp.jpg"));
os.write(data);
}
} catch (FileNotFoundException e) {
Log.e(TAG, "Failed to open Input/Output stream.", e);
throw new MmsException(e);
} catch (IOException e) {
Log.e(TAG, "Failed to read/write data.", e);
throw new MmsException(e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
Log.e(TAG, "IOException while closing: " + os, e);
}
}
}
}
愛華網(wǎng)


