manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
if(!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) &&
!manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
askLocationSettings();
}
void askLocationSettings(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("开启位置服务");
builder.setMessage("本应用需要开启位置服务,是否去设置界面开启位置服务?");
builder.setPositiveButton("是", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Intent intent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainActivity.this.startActivity(intent);
}
});
builder.setNegativeButton("否", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Toast.makeText(MainActivity.this, "No location provider to use",
Toast.LENGTH_SHORT).show();
}
});
builder.show();
}
如果设备开启了位置服务,就可以创建一个位置信息监听器,在监听时需要传给LocationManager。在事件监听方法中将经度、纬度、高度、速度等位置信息输出。代码如下:
listener = new LocationListener(){
public void onLocationChanged(Location arg0) {
String txt = "Longitude:" + arg0.getLongitude()
+ ", Latitude:" + arg0.getLatitude()
+ ", Altitude" + arg0.getAltitude()
+ ", Speed:" + arg0.getSpeed();
// 经度,纬度,高度,速度
tvResult.append(txt + "\n");
}
public void onProviderDisabled(String arg0) {}
public void onProviderEnabled(String arg0) {}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {}
};
启动位置监听需要调用LocationManager的requestLocationUpdates()方法,方法的第一个参数是位置服务提供者。一个设备上可能有多个位置服务提供者,比如gps,wifi,北斗等,所以要先根据定位需求寻找一个最匹配的提供者,使用的方法是LocationManager的getBestProvider()方法。另外,获取当前位置需要一定的时间,而有些应用又已启动就需要一个定位信息,此时可以使用上次使用时的最后已知位置。该位置保存在缓存中,可以通过LocationManager的getLastKnownLocation()方法获得。具体代码如下:
void startListening(){
Criteria crt = new Criteria(); // 位置监听标准
crt.setHorizontalAccuracy(Criteria.ACCURACY_HIGH); // 水平精度高
crt.setAltitudeRequired(true); // 需要高度
String provider = manager.getBestProvider(crt, true); // 寻找最匹配的provider
Location l = manager.getLastKnownLocation(provider); // 取最后已知位置,即缓存中的位置
if(l!=null) tvResult.append(provider + "-LastKnown:" + l.toString() + "\n");
long period = Long.parseLong(etPeriod.getText().toString()); // 最小时间间隔
int distance = Integer.parseInt(etDistance.getText().toString()); // 最小距离
manager.requestLocationUpdates(provider, period*1000, distance, listener); // 开始监听
tvResult.append(provider + "-Location listener started.\n");
}
Android6.0以上系统需要应用运行时进行动态权限申请,所以在开始监听位置前需要检查权限,如果没有许可就进行询问。主要代码是:
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 101);
return;
}
停止位置监听使用LocationManager的removeUpdates()方法,代码如下:
manager.removeUpdates(listener);
tvResult.append("Location listener stoped.\n");
监听位置需要在配置文件里声明权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
例子中用到的相关类包括:
1)android.location.LocationManager类,方法有:
boolean isProviderEnabled(String provider):返回提供位置的provider是否开启,provider的取值一般为LocationManager.GPS_PROVIDER或LocationManager.NETWORK_PROVIDER
String getBestProvider(Criteria criteria, boolean enabledOnly):返回与要求最匹配的provider,criteria为精度等要求,enabledOnly为true时只匹配已开启的provider,返回值一般为LocationManager.GPS_PROVIDER、LocationManager.NETWORK_PROVIDER或LocationManager.PASSIVE_PROVIDER(从其他应用获得位置)
Location getLastKnownLocation(String provider):返回上次已知位置,是上次获取位置时存放在缓存中的,不一定准确反映现在位置。若provider未开启会返回null。
void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener):注册当前Activity来接收provider提供的位置信息。位置信息周期性产生,最小时间间隔为minTime毫秒,最小距离间隔为minDistance米,产生后会调用listener的onLocationChanged方法。minTime越小,位置服务搜索越频繁,耗电越多,最好不要小于60000毫秒。此方法必须在主线程中调用。
void removeUpdates(LocationListener listener):移除位置监听器
void requestLocationUpdates(String provider, long minTime, float minDistance, PendingIntent intent):位置变化后以广播PendingIntent的形式通知,可以在子线程中调用。
void removeUpdates(PendingIntent intent):移除位置通知广播
2)android.location.Criteria类,方法有:
void setHorizontalAccuracy(int accuracy):设置水平精度要求,accuracy取值为Criteria.ACCURACY_HIGH,ACCURACY_MEDIUM,ACCURACY_LOW
void setAltitudeRequired(boolean altitudeRequired):设置是否需要高度数据
3)android.location.Location类,方法有:
double getLongitude():返回经度
double getLatitude():返回纬度
double getAltitude():返回高度
float getSpeed():返回速度,单位米/秒
4)android.location.LocationListener接口,方法有:
void onLocationChanged(Location location):位置变化时调用
void onProviderDisabled(String provider):用户关闭provider时调用
void onProviderEnabled(String provider):用户开启provider时调用
void onStatusChanged(String provider, int status, Bundle extras):provider状态变化时调用,如GPS信号无法获得等
【参考连接】
Android定位功能开发(1)——获取位置