高德定位(问题)

前言

于AndroidStudio中仅实现定位功能。

步骤

准备

Key获取

高德地图Key添加之SHA1

SDK
  • 下载
  • 配置
    • libs
    • gradle(app)
      android {
          ......
          sourceSets {
              main {
                  /*环信-没用默认jniLibs目录*/
                  jniLibs.srcDirs = ['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精度最高结果
            // truesetOnceLocation(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;
        }
    }
}
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值