彩信的拦截与发送

前段时间(已经过去两个月了....)公司让搞一下android彩信的拦截与发送,于是就在网上找了一些资料,开始研究它的实现过程。

PS:需要从系统源码中扣取部分文件,大概在30个左右,不知道能不能精简,没认真看过。这里我重点说一下彩信的拦截和解析,因为彩信解析方面的资料相对较少。发送的部分我会提供一下我的参考文章,并且可能会转载一下这篇文章,我就是通过这篇文章实现的彩信发送。

 

因为代码量比较大,所以就只贴下关键源码,并且说下流程和要注意的问题。仔细搜索一下的话网上可以找到相关的demo和资料(主要是彩信发送方面的,解析的好像没有),但是在使用时要注意,他们说的并不是全对的,某些方面给你误导了,他们的整体流程和源码都是好的,但是在一些点上刻意写错了(主要是pdu组包、图片或附件的类型等)。

 

简要说一下我的流程吧:

     一、拦截彩信

     1、注册彩信接收器

           彩信的拦截和网上百度或google 出来的一样,都是注册一个广播接收器,然后把该接收器的权限设置成最大值,这个最大值不是网上说的1000而是2147483647(好像是整型的最大值)

   在AdroidMainfest.xml里的代码如下:

<!-- MMS SMS接收器 -->
		<receiver
			android:name=".app.MmsSmsReceiver">
			<intent-filter android:priority="2147483647">
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
			<intent-filter android:priority="2147483647">
				<action
					android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
				<data
					android:mimeType="application/vnd.wap.mms-message" />
			</intent-filter>
		</receiver>

        2、定义自己的广播接收处理类

            和普通的广播接收一样,我们要自己写一个广播接收处理的类,但是要在onReceive方法里添加一句:abortBroadcast();这样在我们拦截到该条彩信信息后,当执行这一句时,该系统广播(就是接收到彩信的系统广播)就不在继续往下发送。

          我的代码:

PS:部分方法可能不通用,自己按自己的情况来。

import com.shanzha.activity.InvalidHeaderValueException;
import com.shanzha.activity.MmsContent;
import com.shanzha.activity.PduHeaders;
import com.shanzha.activity.PduParser;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class MmsSmsReceiver extends BroadcastReceiver {
	/**
	 * 接收短信
	 */
	public static final String  SMS_RECEIVE_ACTION = "android.provider.Telephony.SMS_RECEIVED"; 
	/**
	 * 接收彩信
	 */
	public static final String  MMS_RECEIVE_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED";
	public static long date = 0;
	 Context context;
	 byte[] TransactionId;
	@Override
	public void onReceive(final Context context, Intent intent) {
		// TODO Auto-generated method stub
		this.context=context;
		String action = intent.getAction();
		
		//彩信
		if(action.equals(MMS_RECEIVE_ACTION)){
		PduParser parser = new PduParser();

		try {
		     PduHeaders headers = parser.parseHeaders(intent.getByteArrayExtra("data"));
		     TransactionId = headers.getTransactionId();
		     if (headers.getMessageType() == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) {
			//号码获取
			String from = headers.getFrom();					    
			final String content_location = headers.getContentLocation();
			if (content_location != null) {
			     new Thread() {
				public void run() {
				MmsConnect mmsConnect = new MmsContent(context,content_location,TransactionId);
				 try {
				      mmsConnect.connect();
				     } catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();}
                                         }
			      }.start();

			}
						
		     }
	
		} catch (InvalidHeaderValueException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();}
                  //广播不在发送
		abortBroadcast();
		}
	}

}

        3、彩信内容的获取与解析 (重点和难点,pdu的解析)

              其实在第二步我们能获得的仅仅是一个号码(发送者的号码)和一个url(彩信内容下载地址)地址(需要扣取系统的源码来解析彩信信息)以及每条彩信的标识id,我们可以根据号码选择是不是把该条彩信屏蔽(当然还可以进行其他操作)。如果需要获取彩信内容,就需要从我们获得url地址下载彩信信息主体,下载获得的数据是byte[]类型的,需要转换才能成为可用数据(这一块是重点,详情参考系统源码)。

             我的关键代码:

 彩信数据(内容)下载:          

protected byte[] getPdu(String url) throws IOException {
	    //    ensureRouteToHost(url, mTransactionSettings);
	        return HttpUtils.httpConnection(
	        		context, -1L,
	                url, null, HttpUtils.HTTP_GET_METHOD,
	                true,
	               "10.0.0.172",
	                80);
	    }

彩信数据解析:

                  //下载彩信数据
		mmsData=getPdu(contentLocation);
			
		//彩信数据解析
		PduBody body = null;
		GenericPdu pdu = new PduParser(mmsData).parse();
		if ((pdu == null) || (pdu.getMessageType() != 0x84)) {
				
                          Log.e("xml", "数据为空或类型错误");
                  }else if (pdu instanceof MultimediaMessagePdu) {
	            body = ((MultimediaMessagePdu) pdu).getBody();
	            
	            //获取主题
	            String subject=((MultimediaMessagePdu) pdu).getSubject().getString();
		 if (body != null) {
	                int partsNum = body.getPartsNum();
	                for (int i = 0; i < partsNum; i++) {
	                    PduPart part = body.getPart(i);
	                    
	                    //附件类型获取
	                    String contentType=new String( part.getContentType(),"gb2312");
	                    
	                    //文本类型
	                    if(contentType.contains("text")){
	                    	
	                    	//文本内容获取
	 	                    String content= new EncodedStringValue(part.getData()).getString();
	 	                    //记录
	 	                    MMs_Content.put("text",part.getData());	                    }
	                    //jpg图片类型
	                    else if(contentType.contains("jpeg")){
	                    	
	                  //图片文件生成
	                    	Bitmap bmp=BitmapFactory.decodeByteArray(part.getData(), 0,part.getData().length);
	                        if(bmp!=null){
		                    //记录
		                    	  MMs_Content.put("jpeg",part.getData());
	                        }else
	                        	Log.i("xml","Bitmap is null");
                      
	                    }else{
	                    	//其他类型数据:音频等,暂不处理。
	                    }
	                }
	            }
	        }

       4、向彩信中心返回成功状态信息。

             当我们成功下载数据后要向向彩信中心返回成功的状态(第三步解析获得的彩信id),彩信中心才认为我们成功接收到彩信。

          

//给彩信中心返回成功接收信息
			NotifyRespInd notifyRespInd = new NotifyRespInd(
					PduHeaders.CURRENT_MMS_VERSION,
					TransactionId, PduHeaders.STATUS_RETRIEVED);
		
			mHttpBox = new HttpBox(MMSC, new PduComposer(context,notifyRespInd).make());
			
			mHttpBox.setConnectTimeout(50 * 1000);
			mHttpBox.setReadTimeout(30 * 1000);
			mHttpBox.setRequestMethod(true);

			mHttpBox.addHeader("User-Agent","Nokia6120c/4.21 (SymbianOS/9.2; U; Series60/3.1 Nokia6120c/4.21; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) Mozilla/5.0 AppleWebK");
			mHttpBox.addHeader("Accept","*/*, application/vnd.wap.mms-message, application/vnd.wap.sic");
			mHttpBox.addHeader("Content-Type","application/vnd.wap.mms-message");
			mHttpBox.addHeader("Accept-Charset","iso-8859-1, utf-8; q=0.7, *; q=0.7");
			mHttpBox.addHeader("Accept-Language","zh-cn, zh;q=1.0,en;q=0.5");

			mHttpBox.connect();
			
	//		mHttpBox.read();
	//		mmsData  = mHttpBox.getInData();

 

     二、发送彩信

     这部分相对而言没有那么复杂,难点是pdu的组包,很多问题都是由组包不正确引起的,另外需要注意的一点是:要注意APN的切换,这样才能提高发送成功的成功率。这一部分的资料相对很多啊,我就不贴代码了。注意我开篇说的问题就行了,自己多试一下吧。

    这里提供一篇作为参考的文章,我就是根据这篇文章实现的彩信发送,但是同样要注意我开篇说的问题哦。

    彩信发送参考:http://blog.csdn.net/aniuaniuaniuaniu/article/details/7225967
   


评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值