`

LocationListener监听位置变化,当进入到某一距离内时发出提醒

阅读更多
项目中需要这样的要求:
启动一个服务一直在背后监听当前位置变化,如果进入到离某个地点n千米内,发出一个Notification提醒用户附近有什么什么......

这里我采用的策略是这样的:

首先监听网络,如果联网了就启动距离监听服务,否则关闭距离监听服务。因为网络一旦断了,何谈距离变化?
其次,是否需要开机自启动网络监听,这样也就等于启动了距离监听服务。
其三,一旦进入到某个范围之内,就马上关闭距离监听服务,否则会不停的提醒,用户会觉得很烦。
基于以上步骤,首先实现一个距离监听服务

package com.mobovip.app;

import java.text.DecimalFormat;
import java.util.ArrayList;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class LocationService extends Service{

	private Context context;
	public static ArrayList<Store> stores=new ArrayList<Store>();
	public static double distance = 3;//7430km
	private LocationManager locationManager;
	private NotificationManager notificationManager;
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		context = this;
		locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		
//		if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
//			locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000, 1f, locationListener);
//		}else{
			locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000, 1f,locationListener);
//		}
		
//		Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);     
//        if(location != null){
//        	checkDistance(location);
//        }     
        
	}

	
	private final LocationListener locationListener = new LocationListener() {
		//当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发
	    public void onLocationChanged(Location location) { 
	        // log it when the location changes
	        if (location != null) {
	        	checkDistance(location);
	        }
	    }

	    // Provider被disable时触发此函数,比如GPS被关闭
	    public void onProviderDisabled(String provider) {
	    }

	    //  Provider被enable时触发此函数,比如GPS被打开
	    public void onProviderEnabled(String provider) {
	    }

	    // Provider的在可用、暂时不可用和无服务三个状态直接切换时触发此函数
	    public void onStatusChanged(String provider, int status, Bundle extras) {
	    }
	};
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		if(locationManager!=null){
			locationManager.removeUpdates(locationListener); 
			locationManager=null;
		}
	}

	private void checkDistance(Location location) {
		if (location != null) {
			float[] results = new float[1];
			for (Store store : stores) {
				Location.distanceBetween(location.getLatitude(),
						location.getLongitude(), store.getLatitude(),
						store.getLongitude(), results);
				float result=(results[0] / 1000);//km
				if (result < distance) {
					
					
					showNotification(store);
					
					stopSelf();//不要频繁的提醒
					break;
				}
			}
		}
	}


	private static final int NOTIFY_ID = 0;
	private void showNotification(Store store) {
		notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		
		Intent intent = new Intent(this, BGR.class);
//		intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
				intent, PendingIntent.FLAG_UPDATE_CURRENT);// FLAG_ONE_SHOT
		Notification notification = new Notification.Builder(context)
				.setTicker(context.getString(R.string.app_name, ""))
				.setContentTitle(store.getStoreName()+"("+store.getDistance()+")")
				.setContentText(store.getStoreAddress())
				.setContentIntent(pendingIntent)
				.setSmallIcon(R.drawable.ic_launch_notify)
				.setAutoCancel(true)
				.setWhen(System.currentTimeMillis())
				.setDefaults(Notification.DEFAULT_ALL)
				.getNotification();
		
		notificationManager.notify(NOTIFY_ID, notification);
	}
	
}



网络监听服务,其实注册了一个广播,监听手机CONNECTIVITY_ACTION动作即可
package com.mobovip.app;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.IBinder;

public class NetworkStateService extends Service {

	private static final String tag = "tag";
	private BroadcastReceiver mReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
				ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
				NetworkInfo info = manager.getActiveNetworkInfo();
				if (info != null && info.isAvailable()) {
					Intent service = new Intent(context, LocationService.class);
					startService(service);
				} else {
					Intent service = new Intent(context, LocationService.class);
					stopService(service);
				}
			}
		}
	};

	@Override
	public boolean onUnbind(Intent intent) {
		// TODO Auto-generated method stub
		return super.onUnbind(intent);
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		IntentFilter mFilter = new IntentFilter();
		mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
		registerReceiver(mReceiver, mFilter);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		unregisterReceiver(mReceiver);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return super.onStartCommand(intent, flags, startId);
	}

}



如有必要加上开机启动
package com.mobovip.app;

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

/**
 * BootReceiver
 * 
 * @author NGJ
 * 
 */
public class BootReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		Intent i = new Intent(context, NetworkStateService.class);
		i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		context.startService(i);
	}

}


以上service,BroadcastReceiver都需要注册,再加上网络权限等
<service android:enabled="true" android:name="com.mobovip.app.NetworkStateService" />
        <service android:enabled="true" android:name="com.mobovip.app.LocationService" />
        <!-- 
        <receiver android:name="com.mobovip.app.BootReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
         -->
分享到:
评论

相关推荐

    Android使用GPS获取用户地理位置并监听位置变化的方法

    在Android开发中,获取用户地理位置并监听位置变化是常见的需求,尤其在地图应用、导航服务以及定位相关的功能中。本文将详细介绍如何通过GPS提供者在Android中实现这一功能。 首先,我们需要了解Android中的定位...

    《Android项目开发实训》项目总结报告[归类].pdf

    - 使用LocationListener监听位置变化,当位置变化满足用户设定的触发条件时,启动AlarmManager安排闹钟事件。 **第六章 结论** 通过这次实训,学生不仅能掌握Android开发的基本技能,还能深入了解位置服务的实现...

    android中定时定位的实现

    (1)定时功能的实现,调用系统当前时间,使用...(2)当前位置的获取,使用GPS功能获取当前位置,并且显示出经度和纬度,并且使用位置监听事件LocationListener监听位置变化,当位置改变时,获取新的经纬度,并显。

    GPS获取当前位置

    当设备的位置发生变化时,`LocationManager`会调用`LocationListener`中的方法来通知应用。 - **`Location`**:表示一个具体的位置信息,包含经纬度、海拔、速度等数据。 #### 实现步骤 1. **添加权限** 在`...

    Android获取位置坐标

    第一个参数是定位提供者(这里是GPS),第二个参数是更新间隔时间(单位为毫秒,0表示立即更新),第三个参数是距离变化阈值(单位为米,0表示任何距离变化都会触发更新),第四个参数是我们之前定义的...

    android使用GPS获取当前地理位置

    通常,推荐在Activity的`onCreate`方法中进行,以便在应用启动时就准备好监听位置变化。实现`LocationListener`的四个回调方法: 1. `onLocationChanged(Location loc)`:当GPS位置更新时,系统会调用此方法,提供...

    Android 利用GPS获取当前位置

    LocationListener是一个接口,包含onLocationChanged()方法,当位置发生变化时,这个方法会被调用。这里我们定义一个内部类实现LocationListener: ```java LocationListener locationListener = new ...

    获取当前位置—Obtaining the Current Location.

    每次位置发生变化时,LocationManager都会调用onLocationChanged()方法,并传入一个Location对象,该对象包含了更新后的位置信息。 在LocationListener的onLocationChanged()方法中,可以编写处理位置信息的代码。...

    Android安卓经典设计例程源代码-ProximityAlertSample.rar

    在源代码中,开发者会注册一个`LocationListener`来监听位置更新,并设置`ProximityAlert`,当设备进入或离开特定地理区域时触发警报。 1. **Proximity Alert的创建**:在Android中,`addProximityAlert()`方法用于...

    google地图定位

    4. `new TestLocationListener(myloctionController,mapOverlays, firstOverlay)`:一个实现了LocationListener接口的对象,当位置发生变化时,该监听器会接收到通知。 LocationListener接口包含四个方法,其中最...

    Android GPRS获取位置信息DEMO

    当位置改变时,`onLocationChanged`方法会被调用,这里可以获取到新的Location对象,其中包含了经纬度坐标、海拔、速度、时间和精度等信息。开发者可以根据这些信息进行相应的处理,比如显示在地图上,或者发送给...

    android studio获取当前经纬度的简单实例

    在这个实例中,我们首先检查了运行时权限,然后设置了LocationListener来监听位置变化。当位置发生变化时,`onLocationChanged` 方法会被调用,从中我们可以获取到最新的经纬度。记得在暂停和恢复Activity时管理位置...

    Android_GPS如何获取经纬度

    这会持续监听位置变化,当满足特定条件(如时间间隔或距离变化)时触发回调。例如,每2秒更新一次,当位置变化超过10米时: ```java // 创建位置监听器 LocationListener locationListener = new LocationListener...

    Android应用源码之ProximityAlertSample.zip

    - **触发距离**:在设置Proximity Alert时,你需要指定一个阈值,当设备与目标位置的距离小于这个值时,警报会被触发。这个值通常以米为单位。 - **移除警报**:为了节省系统资源,应用可能需要在不再需要Proximity...

    Android 获取Gps信息的程序源码.rar

    这里的参数分别代表:位置提供者(GPS)、最小时间间隔(毫秒,0表示立即更新)、最小距离变化(米,0表示任何距离变化都触发更新)和LocationListener实例。 为了获取一次当前位置,你可以调用LocationManager的`...

    Android 打开GPS导航并获取位置信息.doc

    这里的参数分别是位置提供者(GPS)、最小时间间隔(毫秒)、最小距离变化(米)和`LocationListener`实例。当位置发生变化时,`onLocationChanged()`方法会被调用。 当你不再需要位置更新时,记得移除监听器: ``...

    Android的Gps定位

    接下来,我们需要创建一个LocationListener来监听GPS位置的变化。在Android SDK中,我们可以使用`LocationManager`来注册和管理这个监听器: ```java LocationManager locationManager = (LocationManager) ...

    Android-定期跟踪用户在后台的位置

    在Android开发中,实现“定期跟踪用户在后台的位置”是一个常见的需求,特别是在构建导航、健身应用或者提供基于位置服务的应用时。以下将详细介绍这个过程涉及的关键知识点和步骤。 首先,理解Android系统的权限...

    Android开发之百度地图定位打卡

    需要开启定位服务,并设置LocationListener监听位置变化。在LocationListener中,我们可以获取到经纬度、速度、精度等定位信息。 为了实现打卡功能,我们需要判断用户是否在特定范围内。这通常通过计算用户当前位置...

Global site tag (gtag.js) - Google Analytics