隨筆 - 33, 文章 - 0, 評(píng)論 - 12, 引用 - 0
          數(shù)據(jù)加載中……

          Android 彩信的發(fā)送

          最近有個(gè)需求,不去調(diào)用系統(tǒng)界面發(fā)送彩信功能。做過(guò)發(fā)送短信功能的同學(xué)可能第一反應(yīng)是這樣:
          不使用 StartActivity,像發(fā)短信那樣,調(diào)用一個(gè)類似于發(fā)短信的方法
          SmsManager smsManager = SmsManager.getDefault();
          smsManager.sendTextMessage(phoneCode, null, text, null, null);
          可以實(shí)現(xiàn)嗎? 答案是否定的,因?yàn)閍ndroid上根本就沒有提供發(fā)送彩信的接口,如果你想發(fā)送彩信,對(duì)不起,請(qǐng)調(diào)用系統(tǒng)彩信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:"));

          但是這種方法往往不能滿足我們的需求,能不能不調(diào)用系統(tǒng)界面,自己實(shí)現(xiàn)發(fā)送彩信呢?經(jīng)過(guò)幾天的努力,終于找到了解決辦法。
          第一步:先構(gòu)造出你要發(fā)送的彩信內(nèi)容,即構(gòu)建一個(gè)pdu,需要用到以下幾個(gè)類,這些類都是從android源碼的MMS應(yīng)用中mms.pdu包中copy出來(lái)的。你需要將pdu包中的所有類

          都拷貝到你的工程中,然后自己酌情調(diào)通。
             final SendReq sendRequest = new SendReq();
             final PduBody pduBody = new PduBody();

          final PduPart part = new PduPart();//存放附件,每個(gè)附件是一個(gè)part,如果添加多個(gè)附件,就想body中add多個(gè)part。

             pduBody.addPart(partPdu);
             sendRequest.setBody(pduBody);
             final PduComposer composer = new PduComposer(ctx, sendRequest);

          final byte[] bytesToSend = composer.make(); //將彩信的內(nèi)容以及主題等信息轉(zhuǎn)化成byte數(shù)組,準(zhǔn)備通過(guò)http協(xié)議發(fā)送到 ”http://mmsc.monternet.com”;

           第二步:發(fā)送彩信到彩信中心。
           構(gòu)建pdu的代碼:
            String subject = "測(cè)試彩信";
          		    String recipient = "接收彩信的號(hào)碼";//138xxxxxxx
          		    final SendReq sendRequest = new SendReq();
          		    final EncodedStringValue[] sub = EncodedStringValue.extract(subject);
          		    if (sub != null && sub.length > 0) {
          		    	sendRequest.setSubject(sub[0]);
          		    }
          		    final EncodedStringValue[] phoneNumbers = EncodedStringValue.extract(recipient);
          		    if (phoneNumbers != null && phoneNumbers.length > 0) {
          		    	sendRequest.addTo(phoneNumbers[0]);
          		    }
          		    final PduBody pduBody = new PduBody();
          		    final PduPart part = new PduPart();
          		    part.setName("sample".getBytes());
          		    part.setContentType("image/png".getBytes());
          		    String furl = "file://mnt/sdcard//1.jpg";
           
          		    		final PduPart partPdu = new PduPart();
          		    		partPdu.setCharset(CharacterSets.UTF_8);//UTF_16
          		    		partPdu.setName(part.getName());
          		    		partPdu.setContentType(part.getContentType());
          		    		partPdu.setDataUri(Uri.parse(furl));
          		    		pduBody.addPart(partPdu);   
           
          		    sendRequest.setBody(pduBody);
          		    final PduComposer composer = new PduComposer(ctx, sendRequest);
          		    final byte[] bytesToSend = composer.make();
           
          		    Thread t = new Thread(new Runnable() {
           
          				@Override
          				public void run() {
          					try {
          						HttpConnectInterface.sendMMS(ctx,  bytesToSend);
          //
          					} catch (IOException e) {
          						e.printStackTrace();
          					}
          				}
          			});
          		    t.start();
          發(fā)送pdu到彩信中心的代碼:
                  public static String mmscUrl = "http://mmsc.monternet.com";
          //	public static String mmscUrl = "http://www.baidu.com/";
          	public static String mmsProxy = "10.0.0.172";
          	public static String mmsProt = "80";
           
                 private static String HDR_VALUE_ACCEPT_LANGUAGE = "";
              // Definition for necessary HTTP headers.
                 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)throws IOException{
          		HDR_VALUE_ACCEPT_LANGUAGE = getHttpAcceptLanguage();
           
          		if (mmscUrl == 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);
          	        HttpPost post = new HttpPost(mmscUrl);
          	        //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);
          	        //mms PUD END
          	        HttpParams params = client.getParams();
          	        HttpProtocolParams.setContentCharset(params, "UTF-8");
          	        HttpResponse response = client.execute(post);
           
          			LogUtility.showLog(tag, "111");
          	        StatusLine status = response.getStatusLine();
          	        LogUtility.showLog(tag, "status "+status.getStatusCode());
          	        if (status.getStatusCode() != 200) { // HTTP 200 is not success.
                      	LogUtility.showLog(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();
                              }
                          }
                      }
                      LogUtility.showLog(tag, "result:"+new String(body));
                      return body;
          		}  catch (IllegalStateException e) {
          			LogUtility.showLog(tag, "",e);
          //            handleHttpConnectionException(e, mmscUrl);
                  } catch (IllegalArgumentException e) {
                  	LogUtility.showLog(tag, "",e);
          //            handleHttpConnectionException(e, mmscUrl);
                  } catch (SocketException e) {
                  	LogUtility.showLog(tag, "",e);
          //            handleHttpConnectionException(e, mmscUrl);
                  } catch (Exception e) {
                  	LogUtility.showLog(tag, "",e);
                  	//handleHttpConnectionException(e, mmscUrl);
                  } finally {
                      if (client != null) {
          //                client.;
                      }
                  }
          		return new byte[0];
          	}

          至此,彩信的發(fā)送算是完成了。
          總結(jié):android的彩信相關(guān)操作都是沒有api的,包括彩信的讀取、發(fā)送、存儲(chǔ)。這些過(guò)程都是需要手動(dòng)去完成的。想要弄懂這些過(guò)程,需要仔細(xì)閱讀android源碼中的mms這個(gè)app。還有就是去研究mmssms.db數(shù)據(jù)庫(kù),因?yàn)椴市诺淖x取和存儲(chǔ)其實(shí)都是對(duì)mmssms.db這個(gè)數(shù)據(jù)庫(kù)的操作過(guò)程。而且因?yàn)檫@個(gè)是共享的數(shù)據(jù)庫(kù),所以只能用ContentProvider這個(gè)組件去操作db。

          總之,想要研究彩信這塊(包括普通短信),你就必須的研究mmssms.db的操作方法,多多了解每個(gè)表對(duì)應(yīng)的哪個(gè)uri,每個(gè)uri能提供什么樣的操作,那些字段代表短信的那些屬性等。
          最后推薦個(gè)好用的sqlite查看工具:SQLite Database Browser。


          posted on 2011-08-16 14:50 建華 閱讀(4540) 評(píng)論(2)  編輯  收藏

          評(píng)論

          # re: Android 彩信的發(fā)送  回復(fù)  更多評(píng)論   

          為什么我的這個(gè)發(fā)送總是失敗,聯(lián)接超時(shí),發(fā)送不了。
          2011-08-29 16:46 | sun.huang

          # re: Android 彩信的發(fā)送  回復(fù)  更多評(píng)論   

          hgkjhjkljkl
          2013-11-11 21:50 | dfgfh

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 大石桥市| 项城市| 张掖市| 泰来县| 迭部县| 白玉县| 宝丰县| 陕西省| 新安县| 金昌市| 延庆县| 忻州市| 濮阳市| 凉山| 嘉峪关市| 苗栗市| 彩票| 沙湾县| 杂多县| 玛多县| 南岸区| 济源市| 吉林市| 墨江| 老河口市| 郎溪县| 波密县| 桐庐县| 永寿县| 衡南县| 温泉县| 镇康县| 突泉县| 海阳市| 华亭县| 岫岩| 涿州市| 阿拉善盟| 浮梁县| 长沙县| 麻城市|