API上的文档,用翻译工具看的.记录一下
Quickview/快速查看
- The Network Location Provider provides good location data without using GPS
- Network Location Provider 在不使用GPS的情况下提供了良好的位置数据
- Obtaining user location can consume a lot of battery, so be careful how long you listen for updates
- 获取用户位置会消耗大量的电池,所以必须注意应该多久更新一次数据
In this document
- Challenges in Determining User Location / 确定用户位置的挑战
- Requesting Location Updates / 位置更新请求
- Requesting User Permissions / 位置更新请求的用户权限
- Defining a Model for the Best Performance / 定义一个模型的最佳性能
- Flow for obtaining user location / 对获取用户位置进行跟踪
- Deciding when to start listening for updates / 决定什么时候开始对更新进行监听
- Getting a fast fix with the last known location / 使用最后知道的位置信息来获得最快的修复
- Deciding when to stop listening for updates / 决定什么时候停止对更新进行监听
- Maintaining a current best estimate / 维持当前最佳的估计
- Adjusting the model to save battery and data exchange / 调整模式以节省电量和数据交换
- Providing Mock Location Data / 模拟位置的数据提供
Key classes
LocationManager
LocationListener
Requesting Location Updates
// Acquire a reference to the system Location ManagerLocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);// Define a listener that responds to location updatesLocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { // Called when a new location is found by the network location provider. makeUseOfNewLocation(location); }public void onStatusChanged(String provider, int status, Bundle extras) {}public void onProviderEnabled(String provider) {}public void onProviderDisabled(String provider) {} };// Register the listener with the Location Manager to receive location updateslocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
Requesting User Permissions
为了从
NETWORK_PROVIDER
或者GPS_PROVIDER 更新位置信息,必须向用户请求权限 ,
CCESS_COARSE_LOCATION
或者ACCESS_FINE_LOCATION
- 将它们加进Android manifest.
- 例
- < manifest ... > < uses-permission android:name ="android.permission.ACCESS_FINE_LOCATION" /> ... </ manifest >
如果不声明这些权限,就无法获得位置信息.
如果 NETWORK_PROVIDER
和 GPS_PROVIDER 这两个权限都使用到了 ,只需要声明ACCESS_FINE_LOCATION就可以了.它包含两个权限
The Best Location
private static final int TWO_MINUTES = 1000 * 60 * 2 ; /** Determines whether one Location reading is better than the current Location fix * @param location The new Location that you want to evaluate * @param currentBestLocation The current Location fix, to which you want to compare the new one */ protected boolean isBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null ) { // A new location is always better than no location return true ; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.getTime(); boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; boolean isSignificantlyOlder = timeDelta < - TWO_MINUTES; boolean isNewer = timeDelta > 0 ; // If it's been more than two minutes since the current location, use the new location // because the user has likely moved if (isSignificantlyNewer) { return true ; // If the new location is more than two minutes older, it must be worse } else if (isSignificantlyOlder) { return false ; } // Check whether the new location fix is more or less accurate int accuracyDelta = ( int ) (location.getAccuracy() - currentBestLocation.getAccuracy()); boolean isLessAccurate = accuracyDelta > 0 ; boolean isMoreAccurate = accuracyDelta < 0 ; boolean isSignificantlyLessAccurate = accuracyDelta > 200 ; // Check if the old and new location are from the same provider boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); // Determine location quality using a combination of timeliness and accuracy if (isMoreAccurate) { return true ; } else if (isNewer && ! isLessAccurate) { return true ; } else if (isNewer && ! isSignificantlyLessAccurate && isFromSameProvider) { return true ; } return false ;} /** Checks whether two providers are the same */ private boolean isSameProvider(String provider1, String provider2) { if (provider1 == null ) { return provider2 == null ; } return provider1.equals(provider2);
package tree.love.map.Location; import android.app.Activity; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationProvider; import android.os.Bundle; import android.util.Log; import android.widget.TextView; public class HomeActivity extends Activity{ /** * LocationManager可以用来获取当前的位置, * 追踪设备的移动路线,或设定敏感区域, * 在进入或离开敏感区域时设备会发出特定警报 */ private LocationManager locationManager = null ; /** * 提供的位置信息精度差,但速度较GPS定位快 */ private String networkProvider = null ; /** * 可以提供更加精确的位置信息,但定位速度和质量受到卫星数量和环境情况的影响 */ private String gpsProvider = null ; /** * Location对象中,包含了可以确定位置的信息,如经度、纬度和速度等 */ private Location lastKnownlocation = null ; /* 顯示位置信息 */ private TextView textResult = null ; /* 位置String */ private String locationStr = null ; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); textResult = (TextView) findViewById(R.id.textView_locationResult); // 指明获取的服务是位置服务 locationManager = (LocationManager) this .getSystemService(LOCATION_SERVICE); // 网络更新位置 networkProvider = LocationManager.NETWORK_PROVIDER; // GPS更新位置 gpsProvider = LocationManager.GPS_PROVIDER; lastKnownlocation = locationManager.getLastKnownLocation(gpsProvider); textResult.setText( " 位置信息更新+: " ); locationManager.requestLocationUpdates(gpsProvider, 0 , 0 , locationListener); // 当我们获得了正确的需要的信息的时候就移除监听 // locationManager.removeUpdates(locationListener); } /** * 显示location获得的位置信息 */ public void getLocationInfo(Location location) { if (location != null ) { locationStr = " 纬度-Latitude: " + location.getLatitude() + " \n经度-Longitude: " + location.getLongitude() + " \n精度-Accuracy: " + location.getAccuracy() + " \n标高-Latitude: " + location.getAltitude() + " \n时间-Time: " + location.getTime() + " \n速度-Speed: " + location.getSpeed() + " \n方位-Bearing: " + location.getBearing(); } else { locationStr = " Location is not found " ; } textResult.setText(locationStr); } private final LocationListener locationListener = new LocationListener() { @Override public void onStatusChanged(String provider, int status, Bundle extras) { /* * 在提供定位功能的硬件的状态改变时被调用 * 如从不可获取位置信息状态到可以获取位置信息的状态,反之亦然 */ switch (status) { case LocationProvider.AVAILABLE: Log.v( " Status " , " AVAILABLE " ); break ; case LocationProvider.OUT_OF_SERVICE: Log.v( " Status " , " OUT_OF_SERVICE " ); break ; case LocationProvider.TEMPORARILY_UNAVAILABLE: Log.v( " Status " , " TEMPORARILY_UNAVAILABLE " ); break ; } } @Override public void onProviderEnabled(String provider) { // 在用户启用具有定位功能的硬件时被调用 getLocationInfo( null ); } @Override public void onProviderDisabled(String provider) { // 用户禁用具有定位功能的硬件时被调用 getLocationInfo( null ); } @Override public void onLocationChanged(Location location) { // 在设备的位置改变时被调用 getLocationInfo(location); } };}