Android开发—broadcast短信监控

标签: GPSandroidbroadcastbroadcastreceiver


昨天给自己的app新增了一个功能:可以允许指定好友通过短信方式来打开自己手机的gps定位,并将位置信息上传至服务器。

因为定位功能在程序后台运行的时候是关闭状态的,所以通过app还是不能随时查看好友位置。


通过broadcast receive 来获取监控短信的接收,并且解析短信数据,符合的话即打开gps通知好友。

主要三个步骤:

1, AndroidManifest添加短信接收权限


<uses-permission android:name="android.permission.RECEIVE_SMS"/>


之前忘了这一步,一直没有成功!


2, AndroidManifest添加组件注册


<receiver android:name="com.binqiang.broadcast.SmsBroadcastReceiver">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
            </intent-filter>
        </receiver>


broadcast作为四大基本组件,需要注册


3, 自定义receiver类,分析短信并处理。


public class SmsBroadcastReceiver extends BroadcastReceiver {

	private static final Object SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
	private MyLocationManager myLocationManager;

	@Override
	public void onReceive(Context context, Intent intent) {
		System.out.println("onReceive");
		if(intent.getAction() != null && intent.getAction().equals(SMS_RECEIVED)){
			Bundle bundle = intent.getExtras();
			if(bundle != null){
				Object[] obj = (Object[])bundle.get("pdus");
				SmsMessage smsMessage[] = new SmsMessage[obj.length];
				for(int i = 0; i < obj.length; i++){
					smsMessage[i] = SmsMessage.createFromPdu((byte[])obj[i]);
					String sender = smsMessage[i].getOriginatingAddress();
					String content = smsMessage[i].getMessageBody();
					String teleNum = Config.getGpsTelePhone(context);
					ToastShow.ShowMsg(context, teleNum);
					System.out.println(sender + " " + content + " " + teleNum + " " + Config.SENDER_GPS);
					if(sender.contains(teleNum) && content.equals(Config.CONTENT_OPEN_GPS)){
						ToastShow.ShowMsg(context, "好友正在请求你的GPS位置");
						myLocationManager = ShareWithUApplication.getLocationInstance(context);
						if(myLocationManager.getIsInitial() && myLocationManager.getIsStarted()){
							return;
						}
						myLocationManager.initial();
						myLocationManager.setLocationListener(null);
					}
					else if(sender.contains(teleNum) && content.equals(Config.CONTENT_CLOSE_GPS)){
						myLocationManager = ShareWithUApplication.getLocationInstance(context);
						if(myLocationManager != null){
							System.out.println("stop gps");
							myLocationManager.stopGps();
						}else{
							System.out.println("null");
						}
					}
				}
			}
		}

	}

}


上面的实现逻辑也比较简单,定位那部分代码为了重用,也重新自定义了一个类来实现。


唯一一个问题就是:

当关闭程序的时候,该broadcast receiver也不工作了,不能实现上述功能了。


理论上说:Broadcast Receiver作为系统级别的监听器,拥有自己的进程,与指定应用程序无关;


但是,网上找了一下,找到以下两种解释:

1, 3.1之后,系统的很多广播,只能在APP的进程存在的时候被相应,这个的确是android为了防止病毒做的意向保护措施;

2, 当app被force 关闭的时候,相应的广播也停止工作了,比如任务管理器关掉该app。但是如何是正常的关闭呢?


所以,目前就只能是程序在后台工作的时候,可以执行上述功能。


昨天给自己的app新增了一个功能:可以允许指定好友通过短信方式来打开自己手机的gps定位,并将位置信息上传至服务器。

因为定位功能在程序后台运行的时候是关闭状态的,所以通过app还是不能随时查看好友位置。


通过broadcast receive 来获取监控短信的接收,并且解析短信数据,符合的话即打开gps通知好友。

主要三个步骤:

1, AndroidManifest添加短信接收权限


<uses-permission android:name="android.permission.RECEIVE_SMS"/>


之前忘了这一步,一直没有成功!


2, AndroidManifest添加组件注册

<receiver android:name="com.binqiang.broadcast.SmsBroadcastReceiver">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
            </intent-filter>
        </receiver>


broadcast作为四大基本组件,需要注册


3, 自定义receiver类,分析短信并处理。



public class SmsBroadcastReceiver extends BroadcastReceiver {

	private static final Object SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
	private MyLocationManager myLocationManager;

	@Override
	public void onReceive(Context context, Intent intent) {
		System.out.println("onReceive");
		if(intent.getAction() != null && intent.getAction().equals(SMS_RECEIVED)){
			Bundle bundle = intent.getExtras();
			if(bundle != null){
				Object[] obj = (Object[])bundle.get("pdus");
				SmsMessage smsMessage[] = new SmsMessage[obj.length];
				for(int i = 0; i < obj.length; i++){
					smsMessage[i] = SmsMessage.createFromPdu((byte[])obj[i]);
					String sender = smsMessage[i].getOriginatingAddress();
					String content = smsMessage[i].getMessageBody();
					String teleNum = Config.getGpsTelePhone(context);
					ToastShow.ShowMsg(context, teleNum);
					System.out.println(sender + " " + content + " " + teleNum + " " + Config.SENDER_GPS);
					if(sender.contains(teleNum) && content.equals(Config.CONTENT_OPEN_GPS)){
						ToastShow.ShowMsg(context, "好友正在请求你的GPS位置");
						myLocationManager = ShareWithUApplication.getLocationInstance(context);
						if(myLocationManager.getIsInitial() && myLocationManager.getIsStarted()){
							return;
						}
						myLocationManager.initial();
						myLocationManager.setLocationListener(null);
					}
					else if(sender.contains(teleNum) && content.equals(Config.CONTENT_CLOSE_GPS)){
						myLocationManager = ShareWithUApplication.getLocationInstance(context);
						if(myLocationManager != null){
							System.out.println("stop gps");
							myLocationManager.stopGps();
						}else{
							System.out.println("null");
						}
					}
				}
			}
		}

	}

}


上面的实现逻辑也比较简单,定位那部分代码为了重用,也重新自定义了一个类来实现。


唯一一个问题就是:

当关闭程序的时候,该broadcast receiver也不工作了,不能实现上述功能了。


理论上说:Broadcast Receiver作为系统级别的监听器,拥有自己的进程,与指定应用程序无关;


但是,网上找了一下,找到以下两种解释:

1, 3.1之后,系统的很多广播,只能在APP的进程存在的时候被相应,这个的确是android为了防止病毒做的意向保护措施;

2, 当app被force 关闭的时候,相应的广播也停止工作了,比如任务管理器关掉该app。但是如何是正常的关闭呢?


所以,目前就只能是程序在后台工作的时候,可以执行上述功能。