Android彩信发送

来源:互联网 发布:u3d和java哪个更有发展 编辑:程序博客网 时间:2024/06/09 23:18

彩信发送,首先直接上调用系统app发彩信的代码:

Intent sendIntent = new Intent(Intent.ACTION_SEND,  Uri.parse("mms://"));    sendIntent.setType("image/jpeg");    String url = "file://sdcard//tmpPhoto.jpg";    sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(url));    startActivity(Intent.createChooser(sendIntent, "MMS:"));


 

上面的方法应该都知道,没什么好说的,详细说先后台实现发送彩信。

后台实现发送彩信

看了很多博客,和别人搞的代码,基本原理:先构造出你要发送的彩信内容,即构建一个pdu,需要用到以下几个类,这些类都是从android源码的MMS应用中mms.pdu包中copy出来的。你需要将pdu包中的所有类基本上可以实现彩信的发送,但是存在很多问题。

第一,网络切换问题,只能手动切换gprs和apn后才能发送成功。

第二,pdu打包问题,pdu打包方法android源码里有,但没有提供接口,添加资源时候要注意资源类型和格式。

第三,注意区分不同运营商,不同的彩信代理不一样。

解决以上三个问题,基本保证任何网络环境下,不管联通、移动还是电信都可以发送成功。当然你要开通彩信业务。

第一,网络切换问题

  1.点击发送按钮,检查apn不是cmwap激活apn

info = conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);                                                    String currentAPN = info.getExtraInfo();MLog.i(TAG, currentAPN + "");if (!"cmwap".equals(currentAPN)){openApn();} else{mobileMmsSender(true);}

   2.激活apn,如果网络状态为"请求开始,等待连接通知,测注册广播,监听网络状态改变。

public void openApn(){int i = conManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableMMS");// 打开新的APN连接switch (i){case 0:MLog.i(TAG, "APN已经激活,可以使用网络");if (isSending == false){isSending = true;mobileMmsSender(false);}if (mNChangeReceiver != null && isRegisterReceiver){myApp.unregisterReceiver(mNChangeReceiver);mNChangeReceiver = null;isRegisterReceiver = false;}break;case 1:// 注册广播IntentFilter filter = new IntentFilter();filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);myApp.registerReceiver(mNChangeReceiver, filter);isRegisterReceiver = true;MLog.i(TAG, "请求开始,等待连接通知");break;case 2:MLog.i(TAG, "apn没有设置好");break;case 3:MLog.i(TAG, "请求失败");break;case 4:MLog.i(TAG, "系统忙,例如net已经连接");break;case 5:MLog.i(TAG, "请求使用wap失败,wifi已经打开");break;default:MLog.i(TAG, "请求错误,错误代码:" + i);break;}}

3.设置网络,优先级,让cmwap网络优先于wifi。

private void MmsWebSet(){String currentAPN = info.getExtraInfo();CommonUtils gprs = new CommonUtils();Log.i("ss", currentAPN + "");gprs.gprsEnabled(true, MmsContactsActivity.this);if (wifiManager.isWifiEnabled()){isWifi = true;ConnectivityManager conManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);conManager.setNetworkPreference(ConnectivityManager.TYPE_MOBILE_MMS);// 设定首选网络类型。}}

4.发送彩信

protected void mobileMmsSender(final boolean defuatWap){// 处理网络MmsWebSet();SendMms sendMms = new SendMms(mmsContent, number, subject,MmsContactsActivity.this, sendListener);sendMms.sendMMS(defuatWap);}


 

public class SendMms {private static final String TAG = "SendMms";private String mmsContent = null; // 彩信存放路径private String number = null; // 选中的手机号private String subject = ""; // 彩信主题private Context mContext = null;private SendMmsListener sendListener = null;public SendMms(String mmsContent, String number, String subject,Context mContext, SendMmsListener sendListener) {super();this.mmsContent = mmsContent;this.number = number;this.subject = subject;this.mContext = mContext;this.sendListener = sendListener;}public void sendMMS(final boolean defuatWap) {// 组织彩信包MakeMMSInfo makeMMs = new MakeMMSInfo();final MMSInfo mms = makeMMs.makeMMSInfos(mmsContent, subject, mContext,number);// 发送并监听状态new Thread() {public void run() {try {byte[] res = MMSSender.sendMMS(mContext, mms.getMMSBytes(),defuatWap);// MLog.i(TAG, "彩信发送成功"+res.length);if (res != null && res.length != 0) {mHandler.sendEmptyMessage(0);}} catch (Exception e) {MLog.e(TAG, "" + e.toString());mHandler.sendEmptyMessage(1);}};}.start();}private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 0:sendListener.sendComplete();break;case 1:sendListener.sendFaild();break;}}};}


第二,pdu资源打包

组织彩信包,就是按上面发送彩信代码红色部分继续。上彩信包解析和组织pdu包代码

public class MakeMMSInfo {private String TAG = "MakeMMSInfo";private Context mContext = null;public MMSInfo makeMMSInfos(String mmsContent, String subject,Context context, String number) {this.mContext = context;List<SmilPar> smilParList = null; // 解析每一帧列表// 获得smil文件名String smilFile = FileUtils.getSmilFilesByPath(mmsContent);// 解析出要添加 的资源File file = new File(mmsContent + "/" + smilFile);// 解析xmil文件返回数据InputStream istream = null;try {istream = new FileInputStream(file);smilParList = ParseSmil.parseSmilPar(istream);} catch (FileNotFoundException e) {MLog.e("FileNotFoundException", e.toString());}if (subject == null) {subject = "无主题";}final MMSInfo mms = new MMSInfo(mContext, number.toString().replaceAll(" ", ""), subject);// 发送的手机号String path = null;MLog.i(TAG, number.replaceAll(" ", ""));// 添加smil资源MLog.i(TAG, mms.getMMSBytes().toString());mms.addSmilPart("file://mnt" + mmsContent + "/" + smilFile, smilFile);for (int i = 0; i < smilParList.size(); i++) {// 添加图片资源for (int j = 0; j < smilParList.get(i).getSmilBtm().size(); j++) {path = smilParList.get(i).getSmilBtm().get(j);mms.addPicturePart("file://mnt" + mmsContent + "/" + path, path);// file://mnt/sdcard//1.jpg}// 添加文本资源for (int j = 0; j < smilParList.get(i).getSmilText().size(); j++) {path = smilParList.get(i).getSmilText().get(j);mms.addTextPart(read(mmsContent + "/" + path), path);}// 添加音频资源for (int j = 0; j < smilParList.get(i).getSmilAudio().size(); j++) {path = smilParList.get(i).getSmilAudio().get(j);mms.addAudioPart("file://mnt" + mmsContent + "/" + path, path);}// 添加视频资源for (int j = 0; j < smilParList.get(i).getSmilVideo().size(); j++) {path = smilParList.get(i).getSmilVideo().get(j);mms.addVideoPart("file://mnt" + mmsContent + "/" + path, path);}}MLog.i(TAG, "添加后:" + mms.getMMSBytes().toString());return mms;}/** * 读取文件内容 *  * @param filename *            文件名称 */public String read(String filename) {byte[] data = null;try {byte[] buffer = new byte[1024];File file = new File(filename);if (!file.exists()) {Toast.makeText(mContext, R.string.mms_pak_error,Toast.LENGTH_LONG).show();return new String(data);}FileInputStream inStream = new FileInputStream(file);ByteArrayOutputStream outStream = new ByteArrayOutputStream();int len = 0;while ((len = inStream.read(buffer)) != -1) {outStream.write(buffer, 0, len);}data = outStream.toByteArray();return new String(data, "gbk");} catch (IOException e) {MLog.i(TAG, e.toString());}return null;}}


解析:根据mms资源包路径,解析smil文件或者mms资源对象,给pdu包添加不同的资源。(注意文本资源编码是gbk)

   pdu添加资源代码

 

public class MMSInfo {private final static String TAG = "MMSInfo";private Context con;private PduBody pduBody;private String recieverNum;private static String SUBJECT_STR = "我的主题"; // 彩信主题public MMSInfo(Context con, String recieverNum, String subject) {// TODO Auto-generated constructor stubthis.con = con;this.recieverNum = recieverNum;pduBody = new PduBody();SUBJECT_STR = subject;}/** * 添加图片资源 *  * @author * @param uriStr *            file://mnt/sdcard//1.jpg */public void addPicturePart(String uriStr, String name) {MLog.i(TAG, "添加图片" + uriStr);PduPart part = new PduPart();part.setCharset(CharacterSets.UTF_8);// part.setName(("图片" + partCount++).getBytes());part.setName(name.getBytes());// part.setContentType(("image/jpg" +// getTypeFromUri(uriStr)).getBytes());// "image/png"String type = FileUtils.getExtension(uriStr);if (type.equals("jpg") || type.equals("JPG")) {part.setContentType(ContentType.IMAGE_JPG.getBytes());} else if (type.equals("jpeg") || type.equals("JPEG")) {part.setContentType(ContentType.IMAGE_JPEG.getBytes());} else if (type.equals("wbmp") || type.equals("WBMP")) {part.setContentType(ContentType.IMAGE_WBMP.getBytes());} else if (type.equals("png") || type.equals("PNG")) {part.setContentType(ContentType.IMAGE_PNG.getBytes());} else if (type.equals("gif") || type.equals("GIF")) {part.setContentType(ContentType.IMAGE_GIF.getBytes());} else {part.setContentType(ContentType.IMAGE_UNSPECIFIED.getBytes());}part.setDataUri(Uri.parse(uriStr));pduBody.addPart(part);}/** * 添加文本资源 *  * @param text */public void addTextPart(String text, String name) {MLog.i(TAG, "添加文本" + text);if (!TextUtils.isEmpty(text)) {PduPart partPdu3 = new PduPart();partPdu3.setCharset(CharacterSets.UTF_8);// partPdu3.setName("mms_text.txt".getBytes());partPdu3.setName(name.getBytes());String type = FileUtils.getExtension(text);if (type.equals("html") || type.equals("HTML")) {partPdu3.setContentType(ContentType.TEXT_HTML.getBytes());} else {partPdu3.setContentType(ContentType.TEXT_PLAIN.getBytes());}partPdu3.setData(text.getBytes());pduBody.addPart(partPdu3);}}/** * 添加smil文件 *  * @param smil */public void addSmilPart(String smil, String smilFile) {MLog.i(TAG, "添加smil" + smil);if (!TextUtils.isEmpty(smil)) {PduPart partPdu3 = new PduPart();partPdu3.setCharset(CharacterSets.UTF_8);partPdu3.setName(smilFile.getBytes());// partPdu3.setName(name.getBytes());partPdu3.setContentType(ContentType.APP_SMIL.getBytes());partPdu3.setDataUri(Uri.parse(smil));//pduBody.addPart(0, partPdu3);}}/** * 添加音频文件 *  * @param audio */public void addAudioPart(String audio, String name) {MLog.i(TAG, "添加音频" + audio);if (!TextUtils.isEmpty(audio)) {PduPart partPdu2 = new PduPart();partPdu2.setCharset(CharacterSets.UTF_8);// partPdu2.setName("speech_test.amr".getBytes());partPdu2.setName(name.getBytes());String type = FileUtils.getExtension(audio);if (type.equals("amr") || type.equals("AMR")) {partPdu2.setContentType(ContentType.AUDIO_AMR.getBytes());} else if (type.equals("mid") || type.equals("MID")) {partPdu2.setContentType(ContentType.AUDIO_MID.getBytes());} else if (type.equals("midi") || type.equals("MIDI")) {partPdu2.setContentType(ContentType.AUDIO_MIDI.getBytes());} else if (type.equals("mp3") || type.equals("MP3")) {partPdu2.setContentType(ContentType.AUDIO_MP3.getBytes());} else if (type.equals("ogg") || type.equals("OGG")) {partPdu2.setContentType(ContentType.AUDIO_OGG.getBytes());} else if (type.equals("acc") || type.equals("ACC")) {partPdu2.setContentType(ContentType.AUDIO_AAC.getBytes());} else {partPdu2.setContentType(ContentType.AUDIO_UNSPECIFIED.getBytes());}partPdu2.setDataUri(Uri.parse(audio));// partPdu2.setDataUri(Uri.fromFile(new File(audioPath)));pduBody.addPart(partPdu2);}}/** * 添加视频文件 *  * @param video */public void addVideoPart(String video, String name) {MLog.i(TAG, "添加视频" + video);if (!TextUtils.isEmpty(video)) {PduPart partPdu2 = new PduPart();partPdu2.setCharset(CharacterSets.UTF_8);// partPdu2.setName("speech_test.amr".getBytes());partPdu2.setName(name.getBytes());String type = FileUtils.getExtension(video);if (type.equals("MP4") || type.equals("MP4")) {partPdu2.setContentType(ContentType.VIDEO_MP4.getBytes());} else if (type.equals("3gp") || type.equals("3GP")) {partPdu2.setContentType(ContentType.VIDEO_3GPP.getBytes());} else {partPdu2.setContentType(ContentType.VIDEO_UNSPECIFIED.getBytes());}partPdu2.setDataUri(Uri.parse(video));// partPdu2.setDataUri(Uri.fromFile(new File(audioPath)));pduBody.addPart(partPdu2);}}/** * 获得彩信包数据͵"http://mmsc.monternet.com" *  * @author * @return */public byte[] getMMSBytes() {PduComposer composer = new PduComposer(con, initSendReq());return composer.make();}/** * 初始化SendReq *  * @author * @return */private SendReq initSendReq() {SendReq req = new SendReq();EncodedStringValue[] sub = EncodedStringValue.extract(SUBJECT_STR);if (sub != null && sub.length > 0) {req.setSubject(sub[0]);// 添加主题}EncodedStringValue[] rec = EncodedStringValue.extract(recieverNum);// if (rec != null && rec.length > 0) {// req.addTo(rec[0]);// 添加接受者// }for (int i = 0; i < rec.length; i++) {req.addTo(rec[i]);// 添加接受者MLog.i(TAG, "添加接受者:" + rec[i]);}req.setBody(pduBody);return req;}}

解析:添加资源时候要区分不同资源,在区分不同的资源格式,才能正常发送。
网络切换和pdu打包完成,剩下的就是调用网关发送了,我只用到移动发送,只提供移动的,想要区分,只要根据imsi卡号设置不同的网关参数即可。

public class MMSSender {private static final String TAG = "MMSSender";public static String mmscUrl = "http://mmsc.monternet.com";public static String mmsProxy = "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, byte[] pdu, boolean defuatWap)throws IOException {MLog.i(TAG, "开始发mms");// HDR_VALUE_ACCEPT_LANGUAGE = getHttpAcceptLanguage();HDR_VALUE_ACCEPT_LANGUAGE = HTTP.UTF_8;if (mmscUrl == null) {throw new IllegalArgumentException("URL must not be null.");}ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);int connectTimes = 0;while (true) {HttpClient client = null;try {if (!defuatWap) {int inetAddr = lookupHost(mmsProxy);if (!connMgr.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_MMS, inetAddr)) {throw new IOException("Cannot establish route to proxy " + inetAddr);}}// 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(ConnRouteParams.DEFAULT_PROXY, httpHost);HttpConnectionParams.setConnectionTimeout(httpParams, 10000);client = new DefaultHttpClient(httpParams);HttpPost post = new HttpPost(mmscUrl);// mms PUD STARTByteArrayEntity 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 ENDHttpParams params = client.getParams();HttpProtocolParams.setContentCharset(params, "UTF-8");MLog.i(TAG, "执行代理请求");// PlainSocketFactory localPlainSocketFactory =// PlainSocketFactory.getSocketFactory();MLog.i(TAG, post.getAllHeaders().toString());HttpResponse response = client.execute(post);StatusLine status = response.getStatusLine();Log.d(TAG, "status " + status.getStatusCode());if (status.getStatusCode() != 200) { // HTTP 200Log.e(TAG, "!200");throw new IOException("HTTP error: "+ status.getReasonPhrase());}HttpEntity resentity = response.getEntity();Header[] headers = response.getAllHeaders();for (int i = 0; i < headers.length; i++) {Log.i(TAG,headers[i].getName() + "=" + headers[i].getValue()+ ";");}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) {MLog.e(TAG, "" + e.toString());}}}} finally {if (entity != null) {entity.consumeContent();}}}Log.d(TAG, "result:" + new String(body));MLog.i(TAG, "返回结果" + new String(body));return body;} catch (Exception e) {MLog.e(TAG, "" + e.toString());connectTimes++;if (connectTimes < Config.MSG_RESET_REQUEST_COUNT) {continue;} else {throw new IOException("Cannect error! ");}}}}// TODO: move this to android-commonpublic static int lookupHost(String hostname) {InetAddress inetAddress;try {inetAddress = InetAddress.getByName(hostname);} catch (UnknownHostException e) {return -1;}byte[] addrBytes;int addr;addrBytes = inetAddress.getAddress();addr = ((addrBytes[3] & 0xff) << 24) | ((addrBytes[2] & 0xff) << 16)| ((addrBytes[1] & 0xff) << 8) | (addrBytes[0] & 0xff);return addr;}}


以上为我彩信发送过程,如有问题,请多多指教。。。。

 


 

          

1 0
原创粉丝点击