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

标签: locationlistener 监听 位置 | 发表时间:2014-08-19 15:03 | 作者:gundumw100
出处:http://www.iteye.com
项目中需要这样的要求:
启动一个服务一直在背后监听当前位置变化,如果进入到离某个地点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>
         -->


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [locationlistener 监听 位置] 推荐:

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

- - 移动开发 - ITeye博客
项目中需要这样的要求:. 启动一个服务一直在背后监听当前位置变化,如果进入到离某个地点n千米内,发出一个Notification提醒用户附近有什么什么. 这里我采用的策略是这样的:. 首先监听网络,如果联网了就启动距离监听服务,否则关闭距离监听服务. 因为网络一旦断了,何谈距离变化. 其次,是否需要开机自启动网络监听,这样也就等于启动了距离监听服务.

监听短信

- - CSDN博客推荐文章
在监听短信在这个功能中,通知观察者的工作已经有别人做好,我们只需要注册一个观察者即可. System.out.println( new Date(date)+" 您收到 " + address +"给你发的一封短信,短信内容为: \n" +body );. 最后千万别忘了在清单文件上加上所需要的相应权限.

监听文本框输入

- - 博客园_Ruby's Louvre
Firefox、Chrome、IE9,IE10 均支持 oninput 事件,此外所有版本的 IE 均支持 onpropertychange 事件. oninput 事件在用户输入、退格(backspace)、删除(delete)、剪切(ctrl + x)、粘贴(ctrl + v)及鼠标剪切与粘贴时触发(在 IE9 中只在输入、粘贴、鼠标粘贴时触发).

ACTIVITI 学习笔记 - 监听

- - 企业架构 - ITeye博客
ACTIVITI 学习笔记 - 监听. 所有分发的事件都是org.activiti.engine.delegate.event.ActivitiEvent的子类. 监听器监听的流程引擎已经创建完毕,并准备好接受API调用. 监听器监听的流程引擎已经关闭,不再接受API调用. 创建了一个新实体,初始化也完成了.

智能电视变成监听工具

- - Solidot
NCC Groupp的安全专家演示了如何将智能电视变成监听工具. 智能电视内置了扬声器和存储器,可以被恶意程序利用记录会话. 间谍程序可通过物理接触或恶意应用下载安装到电视机上. NCC Group是通过物理接触方式安装间谍软件,该公司的安全专家认为恶意应用可伪装成合法应用通过设备制造商的应用商店安装到电视机上,智能电视支持自动更新,因此恶意应用可释出恶意更新将合法应用变成间谍软件.

简析几种常用的Web监听

- - CSDN博客Web前端推荐文章
我们通常可以部署一些特殊的Servlet类来监听Web应用的上下文信息、Servlet会话信息,Servlet请求信息等. 通过这些监听,我们可以自动执行某些程序. 例如,我们可以把利用监听会话信息,来统计在线人数. 我们可以监听ServletContext,来初始化一些系统常量,初始化一些工厂等.

手机是否可以被监听?

- - 知乎每日精选
手机监听的部分内容可以见我在 电影《窃听风云》中情报人员通过对方的手机(前提不拆下电池)进行监听是否真实. 不开启加密选项网络的GSM和CDMA手机可以轻易被监听,前者技术门槛更低. 由于手机发射功率远比基站小,因此靠被动式设备(即纯接收手机发射的无线电波)获取到的语音绝大多数为单向语音. 而双向语音的价值远远大于单向语音,因此找出手机位置,接近目标拿到双向语音,才是一个完整的监听过程.

Fragment或WebView里监听返回键

- - 移动开发 - ITeye博客
思路主要是在onResume事件里处理按钮事件并进行判断. 如果使用了WebView则在onKey里处理返回按钮事件. 已有 0 人发表留言,猛击->> 这里<<-参与讨论. —软件人才免语言低担保 赴美带薪读研.

Android 监听锁屏/开屏事件

- - CSDN博客推荐文章
(1) 监听BroadcastReceiver. (2)获取PowerManager事件. Intent.ACTION_SCREEN_ON : 屏幕点亮 Intent.ACTION_SCREEN_OFF :屏幕关闭 Intent.ACTION_USER_PRESENT: 用户解锁. 监听用户解锁需要在AndroidManifest中注册权限.

位置预测系列(一)

- - CSDN博客互联网推荐文章
关于位置预测,在每年的顶级会议上都有很多文章出炉. 下面就简单说说ubicomp'13年录用的一篇论文:. 基于用户移动行为的规律性,现有的位置预测方法都能够获得一个很高的预测精度. 然而,目前的方法未能够有效地检测出用户在两个不同位置间的转移. 精确地预测出用户在不同位置间的转移行为是非常重要的,比如在智能家居服务中,需要有效地检测出用户是离开家还是回到家,以便智能地关闭或开启某些服务.