android API——LocationManager获取位置信息
标签(空格分隔): Android开发
LocationManager
需要用到的类就是LocationManager。
首先看SDK的介绍:
java.lang.Object
↳ android.location.LocationManagerThis 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).
Unless noted, all Location API methods require the ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permissions.
LocationManager这个类可以访问系统的定位服务,应用可以周期性地获得设备地理位置的更新。
获得LocationManager对象的方法:Context.getSystemService(Context.LOCATION_SERVICE)
需要权限:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
requestLocationUpdates()
requestLocationUpdates()是我们要获取位置信息的关键方法了,此方法重载了5次。
1. requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)
2. requestLocationUpdates(long minTime, float minDistance, Criteria criteria, LocationListener listener, Looper looper)
3. requestLocationUpdates(long minTime, float minDistance, Criteria criteria, PendingIntent intent)
4. requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener, Looper looper)
5. requestLocationUpdates(String provider, long minTime, float minDistance, PendingIntent intent)
第1个方法比较常用,它通过provider来注册位置更新。
* @param provider the name of the provider with which to register
* @param minTime minimum time interval between location updates, in milliseconds
* @param minDistance minimum distance between location updates, in meters
* @param listener a {@link LocationListener} whose
* {@link LocationListener#onLocationChanged} method will be called for
* each location update
第4个方法在第1个方法的基础上,多了一个Looper变量。默认没有指定Looper则运行在主线程,如果指定Looper则运行在Looper线程。
第5个方法,增加了一个PendingIntent。
provider: 有以下几种
name | description |
---|---|
NETWORK_PROVIDER | This provider determines location based on availability of cell tower and WiFi access points. |
GPS_PROVIDER | This provider determines location using satellites |
PASSIVE_PROVIDER | 通过其它应用发送的位置请求,被动接收位置更新。 |
FUSED_PROVIDER | 隐藏API,混合模式 |
LocationListener
Used for receiving notifications from the LocationManager when
the location has changed.
需要重写4个回调方法,方法的作用如名字一样直白。
void onLocationChanged(Location location);
void onStatusChanged(String provider, int status, Bundle extras);
void onProviderEnabled(String provider);
void onProviderDisabled(String provider);
Geocoder
Geocoder经纬度解码者可用于将经纬度转为详细位置信息:国家,城市,街道名称等
Geocoder gc = new Geocoder(this, Locale.getDefault());
List<Address> locationList = null;
try {
locationList = gc.getFromLocation(latitude, longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}
Address address = locationList.get(0);//得到Address实例
//Log.i(TAG, "address =" + address);
String countryName = address.getCountryName();//得到国家名称,比如:中国
Log.i(TAG, "countryName = " + countryName);
String locality = address.getLocality();//得到城市名称,比如:北京市
Log.i(TAG, "locality = " + locality);
for (int i = 0; address.getAddressLine(i) != null; i++) {
String addressLine = address.getAddressLine(i);//得到周边信息,包括街道等,i=0,得到街道名称
Log.i(TAG, "addressLine = " + addressLine);
Demo
void getLocation(){
LocationManager mLocationManager = (LocationManager) getSystemService(getApplicationContext().LOCATION_SERVICE);
if (mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5*60*1000, 1, mLocationListener);
}
}
LocationListener mLocationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
6.0之后,还需要动态申请权限。
private String[] permissions = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
int i = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[0]);
if (i != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, permissions, 321);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 321) {
Log.d("weijie", "onRequestPermissionsResult: ");
getLocation();
}
}