android 通过GPS获取用户地理位置并监听位置变化
1 Location Manager 管理服务
2 Location Provider 提供数据的content provider
方式一:GPS 特点:精度高,耗电量大,不耗费流量 权限<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
方式二:NETWORK 特点:精度低,省电,需要网络访问 权限<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
或者权限<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
方式三PASSIVE_PROVIDER 资料比较少,只用于特定的情景下,SDK的解释是,并不自己实例化去获取地理位置,而是通过getProvider获取其他的服务或者activity更新位置,被动的获取更新。
操作基本步骤:
1 在manifest.xml文件中设置权限
2 获取LocaionManager
3 选择provider
4 创建listener
/**********************************************************************************************************************/
第一部分 权限
android的安全服务机制,如果应用要访问本地的资源例如联系人列表、拨号、GPS或者其他应用程序的数据,需要许可。所以要使用地理位置信息的服务需要在<manifest>标签下添加android:name="android.permission.ACCESS_FINE_LOCATION"/>获得许可
也可通过单击manifest.xml文件的permission标签可视化的添加许可
/**********************************************************************************************************************/
第二部分 认识LocationManager
官方SDK解释“This class provides access to the system location services. These services allow applications to obtain periodic updates of the device's geographical location, or to fire an application-specified Intent
when the device enters the proximity of a given geographical location.
You do not instantiate this class directly; instead, retrieve it through Context.getSystemService(Context.LOCATION_SERVICE). ”
翻译一下大概意思是“LocationManager这个类提供了对系统位置服务的访问,这些服务允许应用程序获取设备地理位置的定期的更新,也可以在设备接近一个指定的地理位置的时候发起一个指定activity的intent。你不需要创建LocationManager的实例,取而代之的是通过Context.getSystemService(Context.LOCATION_SERVICE)获取。”
重要的方法:来自官方SDK(附上我的翻译注释)
-----------------------------------------------------------------------------------------------------------------------------------------------
public Location getLastKnownLocation (String provider)
Since: API Level 1
Returns a Location indicating the data from the last known location fix obtained from the given provider. This can be done without starting the provider. Note that this location could be out-of-date, for example
if the device was turned off and moved to another location.
//返回一个Location,这个location标明从给定provider获得最后已知的位置,也就是最近获取的位置。这个操作可以不必要启动provider,注意这个地址可能是已经过期的,例如使用的设备可能已经被关闭或者转向了另一个位置。
If the provider is currently disabled, null is returned.
//如果当前的provider被禁用,函数返回null
Parameters
provider the name of the provider
Returns
the last known location for the provider, or null
Throws
SecurityException if no suitable permission is present for the provider. //前面提到的权限的问题,没有允许会抛出安全性的异常,android系统的机制
IllegalArgumentException if provider is null or doesn't exist //非法参数异常,表示provider为null,或者不存在
------------------------------------------------------------------------------------------------------------------------------------------------
一些补充:
认识Location类
官方SDK解释 :“A class representing a geographic location sensed at a particular time (a "fix"). A location consists of a latitude and longitude, a UTC timestamp. and optionally information on altitude, speed, and bearing.
大致的意思是:“这个类用来表示在一个特定时间被感应的地理位置信息(我们叫一个fix//感觉有点聚焦的意思,呵呵),一个location包括一个经度,纬度,一个世界时间戳还有一些关于海拔,速度和方向的可选信息。 “
可以通过getLatitude() getLongitude() getProvider()等函数来获取封装信息中的经度纬度和提供信息的provider,这个比较简单。
-----------------------------------------------------------------------------------------------------------------------------------------------
public void requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener)
Since: API Level 1
Registers the current activity to be notified periodically by the named provider. Periodically, the supplied LocationListener will be called with the current Location or with status updates.
//注册当前的activity定时的被provider的被通知。相当于注册事件。每隔一段时间,LocationListenner会被调用,同时当前的位置或者状态进行更新。
It may take a while to receive the most recent location. If an immediate location is required, applications may use the getLastKnownLocation(String) method.
//接受最新的位置信息可能会花费一会时间,如果需要立刻获得位置信息,程序可以使用上面讲的getLastKonwnLocation方法
In case the provider is disabled by the user, updates will stop, and the onProviderDisabled(String) method will be called. As soon as the provider is enabled again, the onProviderEnabled(String) method will be called and location
updates will start again.
//假如provider被用户停止,(比如关闭GPS等),更新会停止。并且onProviderDisabled方法(监听器中一个需要复写的方法)会被调用,只要provider再次变为可用状态,onProviderEnable方法会被调用,并且更新操作立刻开始。
The frequency of notification may be controlled using the minTime and minDistance parameters. If minTime is greater than 0, the LocationManager could potentially rest for minTime milliseconds between location updates to conserve
power. If minDistance is greater than 0, a location will only be broadcasted if the device moves by minDistance meters. To obtain notifications as frequently as possible, set both parameters to 0.
//通知(更新)的频率可以通过使用minTime(最小更新时间 单位:毫秒)和minDistance(单位:米)参数,如果minTime大于0,LocationManager能够在minTime时间内休息来保存电量,如果minDistance大于0,每变化这个距离就会进行一次更新,如果希望尽可能频繁的更新的数据,则把两个参数均设置为0.
Background services should be careful about setting a sufficiently high minTime so that the device doesn't consume too much power by
keeping the GPS or wireless radios on all the time. In particular, values under 60000ms are not recommended.
//后台的服务应该注意,设置一个合理的minTime使得设备一直保持GPS或者WIFI的时候不耗费太多的电量。不推荐使用6000ms的minTime值
The calling thread must be a Looper thread such as the main thread of the calling Activity.
//使用该方法的线程必须时开启消息循环的线程,例如被调用activity的主线程(可以参考Android线程机制,默认新建的线程是没有开启消息循环的,主线程开启消息循环,可以参考SDK的Looper类)
Parameters
provider the name of the provider with which to register
minTime the minimum time interval for notifications, in milliseconds. This field is only used as a hint to conserve power, and actual time between location updates may be greater or lesser than this value.
minDistance the minimum distance interval for notifications, in meters
listener a {#link LocationListener} whose onLocationChanged(Location) method will be called for each location update//这是事件监听器
Throws
IllegalArgumentException if provider or listener is null
RuntimeException if the calling thread has no Looper //运行时异常,在未开启消息循环的线程中运行
SecurityException if no suitable permission is present for the provider.
-----------------------------------------------------------------------------------------------------------------------------------------------
代码如下:
【Based Aandroid】android 通过GPS获取用户地理位置并监听位置变化
1 LocationActivity.java
2 /* LocationActivity.java
3 * @author octobershiner
4 * 2011 7 22
5 * SE.HIT
6 * 一个演示定位用户的位置并且监听位置变化的代码
7 * */
8 package uni.location;
9
10 import android.app.Activity;
11 import android.content.Context;
12 import android.location.Location;
13 import android.location.LocationListener;
14 import android.location.LocationManager;
15 import android.os.Bundle;
16 import android.os.Vibrator;
17 import android.util.Log;
18 import android.widget.TextView;
19
20 public class LocationActivity extends Activity {
21 /** Called when the activity is first created. */
22 //创建lcoationManager对象
23 private LocationManager manager;
24 private static final String TAG = "LOCATION DEMO";
25 @Override
26 public void onCreate(Bundle savedInstanceState) {
27 super.onCreate(savedInstanceState);
28 setContentView(R.layout.main);
29 //获取系统的服务,
30 manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
31 Location location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
32 //第一次获得设备的位置
33 updateLocation(location);
34 //重要函数,监听数据测试
35 manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 6000, 10,
36 locationListener);
37
38 }
39 /*此处更新一下,当activity不处于活动状态时取消GPS的监听*/
40 public void onPause(){
41 super.onPause();
42 locationManager.removeListener(locationListener);
43 }
44
45 //创建一个事件监听器
46 private final LocationListener locationListener = new LocationListener() {
47 public void onLocationChanged(Location location) {
48 updateLocation(location);
49 }
50 public void onProviderDisabled(String provider){
51 updateLocation(null);
52 Log.i(TAG, "Provider now is disabled..");
53 }
54 public void onProviderEnabled(String provider){
55 Log.i(TAG, "Provider now is enabled..");
56 }
57 public void onStatusChanged(String provider, int status,Bundle extras){ }
58 };
59
60 //获取用户位置的函数,利用Log显示
61 private void updateLocation(Location location) {
62 String latLng;
63 if (location != null) {
64 double lat = location.getLatitude();
65 double lng = location.getLongitude();
66
67 latLng = "Latitude:" + lat + " Longitude:" + lng;
68 } else {
69 latLng = "Can't access your location";
70 }
71 Log.i(TAG, "The location has changed..");
72 Log.i(TAG, "Your Location:" +latLng);
73 }
74
75 }
只修改activity文件是不够的,因为android系统的安全性,对服务采用授权的机制,所以需要修改manifest.xml文件
1 <?xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="uni.location"
4 android:versionCode="1"
5 android:versionName="1.0">
6 <uses-sdk android:minSdkVersion="8" />
7
8 <application android:icon="@drawable/icon" android:label="@string/app_name">
9 <activity android:name=".LocationActivity"
10 android:label="@string/app_name">
11 <intent-filter>
12 <action android:name="android.intent.action.MAIN" />
13 <category android:name="android.intent.category.LAUNCHER" />
14 </intent-filter>
15 </activity>
16
17 </application>
18 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
19 </manifest>
很多朋友可能会有疑问,那就是GPS定位在android虚拟机上的调试问题,其实是可以模拟的,大家启动虚拟机,然后打开DDMS的界面,左侧device栏目会动态显示虚拟机上各项服务启动的情况,待出虚拟机现解锁界面后,单机device栏目下面的emulator行,这时会发现下面的emulator control下面会有 location control ,打开里面的manual标签,哈哈相信你已经看到了经纬度,你可以更改。运行你的程序,然后单击刚才经纬度设置的send按钮就可以模拟接受到新的地理位置了。
在这个demo中 我用到了Log显示状态,推荐使用这种方法,很好用,想了解的朋友可以参考一下我的另一篇文章,学会巧妙的使用Log,跟推荐大家搜一下sundyzlh的教学视频。
关于LOG的使用 单击链接
最终的效果