众所周知,定位有多种方式,GPS,Network,Wifi,基站定位。其实最好的用户体验就是把这四种定位方式融合,除非手机没有卡(当然也不开wifi&&gps),不然总是能找到一个相对的位置给你。
然而最近我手头的项目中就需要定位,测试机是vivo x9 最新款(什么款似乎没什么卵用,都一样),为了方便,只使用了gps与网络定位的融合。通过我们自己的理解,网络定位快,不准确;GPS定位慢,准确。所以最常见的定位就是gps&net融合。然而不幸的事情发生了,当我打开gps关闭net点击定位,起初是没有的,等两分钟会出现位置,正常,没问题;当打开net关闭gps,点击定位,没用;当都打开时,也能定位。
下面粗略看下代码:
private void setLocationPermission() {
boolean isGps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);//gps服务
boolean isNet = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);//网络服务
if (isGps) {
if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) &&
PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION)) {
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
0);
} else {
Log.d("TAG", "setLocationPermission: "+"初次启动获取地址GPS");
mLocation = locationManager.getLastKnownLocation(locationManager.GPS_PROVIDER);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,2000, 20, locationListener);
}
}else if (isNet){
Log.d("TAG", "setLocationPermission: "+"初次启动获取地址NET");
mLocation = locationManager.getLastKnownLocation(locationManager.NETWORK_PROVIDER);
locationManager.requestLocationUpdates(locationManager.NETWORK_PROVIDER, 2000, 20, locationListener);
}
}
当我关闭gps也就是上面第二种情况时,isGps和isNet返回都是false;我实在是不能理解。
后来换了测试机华为,更令我奇怪的是居然成功了。百思不得其解,查了一些资料,现在手机商把Android底层修改的已经不成样子了。可能某些方法在这个手机适用,换个守旧就不好用了。我问过vivo公司,但是没有回复!
后来想了想,我只是需要定位信息,难道没有办法了?然后我选择了高德API。
用来只获取定位信息:
首先导包 定位SDK
public class ToolLocation implements AMapLocationListener {
private AMapLocationClient locationClient = null;
private AMapLocationClientOption locationOption = null;
private Activity mActivity;
private AMapLocation loc;
private static ToolLocation geoLocationUtil;
/**
* 开始定位
*/
public final static int MSG_LOCATION_START = 0;
/**
* 定位完成
*/
public final static int MSG_LOCATION_FINISH = 1;
private ToolLocation() {}
public static ToolLocation getInstnce(){
if (geoLocationUtil == null){
geoLocationUtil = new ToolLocation();
}
return geoLocationUtil;
}
public void setActivity(Activity activity) {//定位前必须要设置
mActivity = activity;
}
public void initLocation(){//定位前必须调用
setLocationPermission();
Location();
}
private void setLocationPermission(){
if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) &&
PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION)) {
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
0);
}
}
public void Location() {
// TODO Auto-generated method stub
try {
locationClient = new AMapLocationClient(mActivity);
locationOption = new AMapLocationClientOption();
// 设置定位模式为低功耗模式
locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
// 设置定位监听
locationClient.setLocationListener(this);
// locationOption.setOnceLocation(true);//设置为单次定位
locationOption.setInterval(5000);
locationClient.setLocationOption(locationOption);// 设置定位参数
// 启动定位
locationClient.startLocation();
mHandler.sendEmptyMessage(MSG_LOCATION_START);
} catch (Exception e) {
Toast.makeText(mActivity, "定位失败", Toast.LENGTH_LONG).show();
}
}
Handler mHandler = new Handler() {
public void dispatchMessage(android.os.Message msg) {
switch (msg.what) {
//定位完成
case MSG_LOCATION_FINISH:
try {
loc = (AMapLocation) msg.obj;
} catch (Exception e) {
Toast.makeText(mActivity, "定位失败", Toast.LENGTH_LONG).show();
}
break;
default:
break;
}
}
};
@Override
public void onLocationChanged(AMapLocation loc) {
if (null != loc) {
Message msg = mHandler.obtainMessage();
msg.obj = loc;
msg.what = MSG_LOCATION_FINISH;
mHandler.sendMessage(msg);
}
}
public AMapLocation getLocation(){
if (loc.getLatitude() == 0.0&&loc.getLongitude() == 0.0){
Toast.makeText(mActivity, "正在定位,请稍等", Toast.LENGTH_SHORT).show();
}
return loc;
}
}
此时,在你的app中就可以随时调用getLocation来获取经纬度,海拔,高度,速度,方向等属性了。