获取用户位置
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 Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener 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 updates
locationManager.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);
}
};
}