文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处http://blog.csdn.net/flowingflying以及作者@恺风Wei。
LocationManager通过addProximityAlert()可以在设备到达或离开某个地点(一定范围)是发送Intent,再由Intent触发Service、BroadcastReceiver或Activity,对触发intent可以设置一定的时限。可以针对GPS和network这两个provider,位置更新间隔时间间隔为1秒,minDistance为1米,这两个参数不可以更改。如果长时间运行,是会很消耗电池。如果屏幕sleep,这个更新时间将是4分钟,这个值同样不能重设。
因此,我们利用之前学习的自行编写可能会更好,当算出两个地点的距离很大时,不需要每1秒更新一次位置信息。同时,我们也注意到Android在reference中队addProximityAlert()有如下的描述:
Due to the approximate nature of position estimation, if the device passes through the given area briefly, it is possible that no Intent will be fired. Similarly, an Intent could be fired if the device passes very close to the given area but does not actually enter it.
也就是说即便真的进入指定范围,不一定能够触发intent。特别是我们通过模拟器来进行位置模拟的时候。尽管如此,我们看是看看如果利用addProximityAlert来实现进入或离开某范围的触发intent,进而触发进一步处理。
小例子中,将触发一个广播通知,接收器收到后在Locat中打印信息。简单的代码片段如下:
public class ProximityActivity extends Activity{
private LocationManager manager = null;
private final String PROXIMITY_ALERT = "cn.wei.flowingflying.testlocation.PROXIMITY_ALERT";
private PendingIntent pIntent1 = null;
private final int REQUEST_CODE = 1000;
private double lat,lon;
ProximityReceiver proxReceiver = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_pure);
proximityStart();
}
private void proximityStart(){
lat = 23.13;
lon = 113.35;
float radius = 1000f; //方圆1公里
manager = (LocationManager)getSystemService(LOCATION_SERVICE);
//由于不是马上触发,所以需要PendingIntent
Intent intent = new Intent(PROXIMITY_ALERT,Uri.parse("geo:" + latDest + "," + lonDest));
intent.putExtra("message", "Destination One");
pIntent1 = PendingIntent.getBroadcast(this, REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT);
//第4个参数是时间,单位毫秒,-1表示无时间限制。通过addProximityAlert,将向network和gps这两个provider注册listener,因此需要android.permission.ACCESS_FINE_LOCATION,检测的时间间隔为1秒,距离变化为1米。如果是屏幕sleep,则时间间隔为4分钟。
manager.addProximityAlert(lat, lon, radius, -1, pIntent1);
// 临时注册接收器,当然我们也可以在AndroidManifest.xml中进行设置,下面的代码相对于设置了
// <receiver android:name=".ProximityReceiver">
// <intent-filter >
// <action android:name="cn.wei.flowingflying.testlocation.PROXIMITY_ALERT"/>
// <data android:scheme="geo" />
// </intent-filter>
//</receiver>
proxReceiver = new ProximityReceiver();
IntentFilter iFilter = new IntentFilter(PROXIMITY_ALERT);
iFilter.addDataScheme("geo");
registerReceiver(proxReceiver, iFilter);
}
private void proximityStop(){
manager.removeProximityAlert(pIntent1); //取消Alter
unregisterReceiver(proxReceiver); //注销临时注册的接收器
}
@Override
protected void onDestroy() {
proximityStop();
super.onDestroy();
}
}
对于LocationManager可以要求对多个地址的进出进行监听。我们可以添加多个:
manager.addProximityAlert(lat2,lon2,radius2,expire2, pendingIntent2);
manager.addProximityAlert(lat3,lon3,radius3,expire3, pendingIntent3);
当然,我们也要记住removeProximityAlter()多个。
接收器的代码如下:
public class ProximityReceiver extends BroadcastReceiver{
private static String tag = "ProximityReceiver";
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getData() != null){
Log.i(tag,intent.getData().toString());
}
Bundle extras = intent.getExtras();
if(extras != null){
Log.i(tag,"Message : " + extras.getString("message"));
Log.i(tag,"Enter : " + extras.getBoolean(LocationManager.KEY_PROXIMITY_ENTERING)); //true表示进入,false表示离开。intent中不会自动提供当前的经纬度,或者自动携带要检测的经纬度。
}
}
}
小例子代码在:Pro Android学习:location小例子
相关链接:我的Android开发相关文章