前言
于AndroidStudio中仅实现定位功能。
步骤
准备
SDK
- 下载
- 配置
- libs
- gradle(app)
android { ...... sourceSets { main { /*环信-没用默认jniLibs目录*/ jniLibs.srcDirs = ['libs'] } } } 复制代码
- libs
清单文件
- 权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> <!--GPS定位--> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <!--调用A-GPS模块--> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission> <!--获取蓝牙信息室内定位--> <uses-permission android:name="android.permission.BLUETOOTH"></uses-permission> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission> 复制代码
- 配置
<!--GD_LOCATION-配置key--> <meta-data android:name="com.amap.api.v2.apikey" android:value="xxx"></meta-data> 复制代码
- 服务
<!--GD_LOCATION-声明service组件--> <service android:name="com.amap.api.location.APSService"></service> 复制代码
代码
- 工具类
package util; import android.content.Context; import com.amap.api.location.AMapLocation; import com.amap.api.location.AMapLocationClient; import com.amap.api.location.AMapLocationClientOption; import com.amap.api.location.AMapLocationListener; /** * Created on 2017/12/5. * * @desc 高德定位 */ public class GdLocation { /** * 客户端 */ private static AMapLocationClient aMapLocationClient = null; /** * 参数 */ private static AMapLocationClientOption aMapLocationClientOption = null; /** * 监听设置标志 */ private static boolean setListener; /** * 定位初始化(Application之onCreate调一次) * * @param context */ public static void init(Context context) { // 客户端 aMapLocationClient = new AMapLocationClient(context); // 参数 aMapLocationClientOption = new AMapLocationClientOption(); // 高精度定位模式 aMapLocationClientOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); // setOnceLocationLatest(boolean b)接口true,定位SDK返回近3s精度最高结果 // true则setOnceLocation(boolean b)接口被设true,反之不,默认false aMapLocationClientOption.setOnceLocationLatest(true); // 定位间隔默认2000ms,最低1000 aMapLocationClientOption.setInterval(2000); // 返回地址信息(默认返回) aMapLocationClientOption.setNeedAddress(true); // 允许模拟位置(默认true) aMapLocationClientOption.setMockEnable(true); // 超时默认30000ms,建议不低8000 aMapLocationClientOption.setHttpTimeOut(20000); // 关闭缓存机制 aMapLocationClientOption.setLocationCacheEnable(false); // 强制刷新WIFI(默认强制) aMapLocationClientOption.setWifiScan(true); // 传感器 aMapLocationClientOption.setSensorEnable(true); // 客户端设参数 aMapLocationClient.setLocationOption(aMapLocationClientOption); } /** * 定位结果回调 */ public interface MyLocationListener { /** * result * * @param location */ void result(AMapLocation location); } /** * 位置获取(重发获取请求) * * @param listener */ public static void getCurrentLocation(final MyLocationListener listener) { if (aMapLocationClient == null) { return; } // 仅设一次防多设致结果重复输出 if (!setListener) { aMapLocationClient.setLocationListener(new AMapLocationListener() { @Override public void onLocationChanged(AMapLocation location) { if (location != null) { aMapLocationClient.stopLocation(); listener.result(location); } } }); setListener = true; } // 启动定位 aMapLocationClient.startLocation(); } /** * 客户端销毁(退出程序调用防定位异常) */ public static void destroy() { aMapLocationClient.onDestroy(); } } 复制代码
- Application
// 初始化高德定位 GdLocation.init(this); 复制代码
- BaseActivity
// 定位客户端销毁 GdLocation.destroy(); // 退出程序 ActivitySuperviseUtils.appExit(); 复制代码
- Activity或Fragment
GdLocation.getCurrentLocation(new GdLocation.MyLocationListener() { @Override public void result(AMapLocation location) { // 处理 }); 复制代码
结果来源
分类
- 移动网络和WIFI关闭
检查网络是否畅通
- 移动网络开启,WIFI关闭
6 基站定位结果 单纯依赖移动、联通、电信等移动网络定位,精度500米-5000米
- WIFI打开,移动网络关闭
5 Wifi定位结果 网络定位,精度较高且较基站更好,5米-200米
- WIFI和移动网络打开
5 Wifi定位结果 网络定位,精度较高且较基站更好,5米-200米
其它
- 0
定位失败 通过AMapLocation.getErrorCode()获取错误码并参考错误码对照表进行问题排查
- 1
GPS定位结果 通过设备GPS定位模块返定位结果,精度较高,10米-100米左右
- 2
前次定位结果 网络定位请求低于1秒或两次定位间设备位置变化非常小时返回,设备位移通过传感器感知
- 4
缓存定位结果 返回一段时间前设备在同位置缓存网络定位结果
- 8
离线定位结果 -
注意
- 工具类中添监听前判断防添多监听致定位结果重复输出。如第一次定位输出一结果,第二次定位输出两结果,以此类推。
- 工具类
destroy
方法于应用退出即BaseAcitvity相应处调用。别处调用因全局仅一定位客户端对象(Application之OnCreate
初始化)致定位异常。
问题
定位客户端对象于Application之OnCreate
初始化,退出程序销毁。再次打开应用Application不执行onCreate
方法致定位不可用。
问题
定位客户端对象于Application之OnCreate
初始化,退出程序销毁。再次打开应用Application不执行onCreate
方法致定位不可用。
解决
抛弃工具类,直在Activity或Fragment初始化等操作。
package com.self.zsp.rd;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import java.util.ArrayList;
import java.util.List;
import adapter.LocationAdapter;
import base.BaseActivity;
import entity.LocationBean;
/**
* @decs: location
* @date: 2017/12/6 14:22
* @version: v 1.0
*/
public class LocationActivity extends BaseActivity implements View.OnClickListener, AMapLocationListener {
/**
* 控件
*/
private ImageView locationBack;
private ProgressBar locationProgress;
private ListView locationListView;
/**
* 客户端
*/
private AMapLocationClient aMapLocationClient = null;
/**
* 参数
*/
private AMapLocationClientOption aMapLocationClientOption = null;
private List<LocationBean> list;
private LocationAdapter locationAdapter;
@Override
protected void initContentView(Bundle savedInstanceState) {
setContentView(R.layout.activity_location);
}
@Override
protected void stepUI() {
locationBack = findViewById(R.id.locationBack);
locationProgress = findViewById(R.id.locationProgress);
locationListView = findViewById(R.id.locationListView);
}
@Override
protected void initConfiguration() {
initGd();
list = new ArrayList<>();
locationAdapter = new LocationAdapter();
}
/**
* 定位初始化
*/
private void initGd() {
// 客户端
aMapLocationClient = new AMapLocationClient(LocationActivity.this);
// 参数
aMapLocationClientOption = new AMapLocationClientOption();
// 高精度定位模式
aMapLocationClientOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
// setOnceLocationLatest(boolean b)接口true,定位SDK返近3s精度最高结果
// true则setOnceLocation(boolean b)接口被设true,反之不(默false)
aMapLocationClientOption.setOnceLocationLatest(true);
// 定位间隔最低1000(默2000ms)
aMapLocationClientOption.setInterval(2000);
// 返回地址信息(默返)
aMapLocationClientOption.setNeedAddress(true);
// 允许模拟位置(默开)
aMapLocationClientOption.setMockEnable(true);
// 超时建议不低8000(默30000ms)
aMapLocationClientOption.setHttpTimeOut(20000);
// 关闭缓存机制
aMapLocationClientOption.setLocationCacheEnable(false);
// 强制刷新WIFI(默强)
aMapLocationClientOption.setWifiScan(true);
// 传感器
aMapLocationClientOption.setSensorEnable(true);
// 客户端设参数
aMapLocationClient.setLocationOption(aMapLocationClientOption);
}
@Override
protected void initData() {
}
@Override
protected void startLogic() {
aMapLocationClient.startLocation();
}
@Override
protected void setListener() {
locationBack.setOnClickListener(this);
aMapLocationClient.setLocationListener(this);
/**
* Item短点
*/
locationListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
toastShort(String.valueOf(position));
}
});
/**
* Item内短点
*/
locationAdapter.setOnItemInnerOnClickListener(new LocationAdapter.ItemInnerOnClickListener() {
@Override
public void itemClick(View v) {
toastShort(String.valueOf(v.getTag()) + "内部");
}
});
}
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (aMapLocation != null) {
locationProgress.setVisibility(View.GONE);
aMapLocationClient.stopLocation();
switch (aMapLocation.getErrorCode()) {
// 定位成功
case 0:
// 结果来源
aMapLocation.getLocationType();
// 纬度
aMapLocation.getLatitude();
// 经度
aMapLocation.getLongitude();
// 精度
aMapLocation.getAccuracy();
// isNeedAddress设false无结果(网络定位结果有地址信息,GPS定位不返地址信息)
String address = aMapLocation.getAddress();
// 国家信息
aMapLocation.getCountry();
// 省信息
aMapLocation.getProvince();
// 城市信息
String city = aMapLocation.getCity();
// 城区信息
String district = aMapLocation.getDistrict();
// 街道信息
String street = aMapLocation.getStreet();
// 街道门牌号
String streetNum = aMapLocation.getStreetNum();
// 城市编码
aMapLocation.getCityCode();
// 地区编码
aMapLocation.getAdCode();
// 定位点AOI信息
String aoiName = aMapLocation.getAoiName();
// 室内定位建筑物Id
aMapLocation.getBuildingId();
// 室内定位楼层
aMapLocation.getFloor();
// GPS状态
aMapLocation.getGpsAccuracyStatus();
/*Log.e("定位结果", "结果来源-" +
aMapLocation.getLocationType() + "|" +
"纬度-" +
aMapLocation.getLatitude() + "|" +
"经度-" +
aMapLocation.getLongitude() + "|" +
"精度-" +
aMapLocation.getAccuracy() + "|" +
"地址信息-" +
aMapLocation.getAddress() + "|" +
"国家信息-" +
aMapLocation.getCountry() + "|" +
"省信息-" +
aMapLocation.getProvince() + "|" +
"城市信息-" +
aMapLocation.getCity() + "|" +
"城区信息-" +
aMapLocation.getDistrict() + "|" +
"街道信息-" +
aMapLocation.getStreet() + "|" +
"街道门牌号-" +
aMapLocation.getStreetNum() + "|" +
"城市编码-" +
aMapLocation.getCityCode() + "|" +
"地区编码-" +
aMapLocation.getAdCode() + "|" +
"定位点AOI信息-" +
aMapLocation.getAoiName() + "|" +
"室内定位建筑物Id-" +
aMapLocation.getBuildingId() + "|" +
"室内定位楼层-" +
aMapLocation.getFloor() + "|" +
"GPS状态-" +
aMapLocation.getGpsAccuracyStatus());*/
list.add(new LocationBean(city));
list.add(new LocationBean(city + district));
list.add(new LocationBean(city + district + street));
list.add(new LocationBean(city + district + street + streetNum));
list.add(new LocationBean(city + district + street + aoiName));
list.add(new LocationBean(address));
locationAdapter.setData(list);
locationListView.setAdapter(locationAdapter);
break;
case 2:
toastShort("扫描到单个WIFI,无基站信息,请重新尝试");
break;
case 3:
toastShort("请检查网络连接");
break;
case 4:
toastShort("请检查网络是否畅通");
break;
case 5:
toastShort("请检查网络是否异常");
break;
case 9:
toastShort("请重新启动定位");
break;
case 11:
toastShort("请检查是否安装SIM卡");
break;
case 12:
toastShort("请开启位置权限");
break;
case 13:
toastShort("请打开WIFI、GPS或插入SIM卡");
break;
case 14:
toastShort("请于开阔地带尝试");
break;
case 18:
toastShort("建议关闭飞行模式,打开WIFI");
break;
case 19:
toastShort("建议插入SIM卡,打开WIFI");
break;
default:
break;
}
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
/**
* 返回
*/
case R.id.locationBack:
finish();
break;
default:
break;
}
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
switch (level) {
/**
* 所有UI组件不可见
* 释放资源
*/
case TRIM_MEMORY_UI_HIDDEN:
// 销毁
aMapLocationClient.onDestroy();
break;
default:
break;
}
}
}
复制代码