Android 高德地图的定位功能,以及动态开启权限

配置工程

  1. Eclipse 配置工程:http://lbs.amap.com/api/android-location-sdk/guide/create-project/eclipse-create-project
  2. Android Studio 配置工程:http://lbs.amap.com/api/android-location-sdk/guide/create-project/android-studio-create-project

配置AndroidManifest.xml

1、权限


    
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION">uses-permission>
    
    <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>
    
    <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>

2.设置高德的key

  
        <meta-data
            android:name="com.amap.api.v2.apikey"
            android:value="您的key" />
        <service android:name="com.amap.api.location.APSService" />

获取key的帮助文档:http://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key

3.初始化定位

请在主线程中声明AMapLocationClient类对象,需要传Context类型的参数。推荐用getApplicationConext()方法获取全进程有效的context。



//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener = new AMapLocationListener();
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mLocationClient.setLocationListener(mLocationListener);

4.配置参数并启动定位

创建AMapLocationClientOption对象
AMapLocationClientOption对象用来设置发起定位的模式和相关参数等。

案例效果图

Android 高德地图的定位功能,以及动态开启权限_第1张图片

下面是具体代码:

MainActivity

public class MainActivity extends AppCompatActivity {


    Button btn;
    TextView tv;


    /**
     * 需要进行检测的权限数组
     */
    protected String[] needPermissions = {
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.READ_PHONE_STATE
    };

    private static final int PERMISSON_REQUESTCODE = 0;

    /**
     * 判断是否需要检测,防止不停的弹框
     */
    private boolean isNeedCheck = true;


    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient = null;
    //声明定位回调监听器
    //public AMapLocationListener mLocationListener = new AMapLocationListener();
    // public AMapLocationListener mLocationListener;
    //声明AMapLocationClientOption对象
    public AMapLocationClientOption mLocationOption = new AMapLocationClientOption();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.btn_get);
        tv = (TextView) findViewById(R.id.tv_text);


        //初始化定位

        initLocation();


        //设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //定位
                //启动定位
                //            mLocationClient.startLocation();

                //设置参数
                //    mLocationClient.setLocationOption(getDefaultOption());
                Log.e("进入", "点击事件" + "=========================================================================");
                //定位监听器
//                mLocationListener = new AMapLocationListener() {
//                    @Override
//                    public void onLocationChanged(AMapLocation aMapLocation) {
//                        //
//                        Log.e("进入", "回调" + "=========================================================================");
//                        if (aMapLocation != null) {
//                            if (aMapLocation.getErrorCode() == 0) {
//                                //可在其中解析amapLocation获取相应内容。
//                                Log.e("进入", "回调返回" + "aMapLocation != null=========================================================================");
//                                aMapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表
//                                aMapLocation.getLatitude();//获取纬度
//                                aMapLocation.getLongitude();//获取经度
//                                aMapLocation.getAccuracy();//获取精度信息
//                                aMapLocation.getAddress();//地址,如果option中设置isNeedAddress为false,则没有此结果,网络定位结果中会有地址信息,GPS定位不返回地址信息。
//                                aMapLocation.getCountry();//国家信息
//                                aMapLocation.getProvince();//省信息
//                                aMapLocation.getCity();//城市信息
//                                aMapLocation.getDistrict();//城区信息
//                                aMapLocation.getStreet();//街道信息
//                                aMapLocation.getStreetNum();//街道门牌号信息
//                                aMapLocation.getCityCode();//城市编码
//                                aMapLocation.getAdCode();//地区编码
//                                aMapLocation.getAoiName();//获取当前定位点的AOI信息
//                                aMapLocation.getBuildingId();//获取当前室内定位的建筑物Id
//                                aMapLocation.getFloor();//获取当前室内定位的楼层
//                                //   aMapLocation.getGpsStatus();//获取GPS的当前状态
//                                //获取定位时间
//                                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//                                Date date = new Date(aMapLocation.getTime());
//                                df.format(date);
//                                tv.setText(aMapLocation.getAddress());
//
//                                String s = aMapLocation.getAddress();
//                                Log.e("定位成功,", "地址" + aMapLocation.getAddress());
////                                if (!TextUtils.isEmpty(s)) {
////                                    stopLocation();
////                                }
//
//
//                            } else {
//                                //定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
//                                Log.e("AmapError", "location Error, ErrCode:"
//                                        + aMapLocation.getErrorCode() + ", errInfo:"
//                                        + aMapLocation.getErrorInfo());
//                            }
//                        }
//                    }
//                };

                //开始定位
                startLocation();

            }
        });

    }

    private void startLocation() {
        //根据控件的选择,重新设置定位参数
        //resetOption();
        // 设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
        // 启动定位
        mLocationClient.startLocation();
    }

    private void initLocation() {
        //初始化client
        mLocationClient = new AMapLocationClient(this.getApplicationContext());
        //设置定位参数
        mLocationClient.setLocationOption(getDefaultOption());
        // 设置定位监听
        mLocationClient.setLocationListener(mLocationListener);
    }

    /**
     * 停止定位
     *
     * @author
     * @since 2.8.0
     */
    private void stopLocation() {
        // 停止定位
        mLocationClient.stopLocation();
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        destroyLocation();
    }

    private void destroyLocation() {
        if (null != mLocationClient) {
            mLocationClient.onDestroy();
            mLocationClient = null;
            mLocationOption = null;


        }
    }

    /**
     * 默认的定位参数
     *
     * @author
     * @since 2.8.0
     */
    private AMapLocationClientOption getDefaultOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setGpsFirst(false);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭
        //mOption.setHttpTimeOut(30000);//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        //   mOption.setInterval(2000);//可选,设置定位间隔。默认为2秒
        mOption.setNeedAddress(true);//可选,设置是否返回逆地理地址信息。默认是true
        //   mOption.setOnceLocation(false);//可选,设置是否单次定位。默认是false
        mLocationOption.setOnceLocation(true);  //获取一次定位结果:
        mOption.setOnceLocationLatest(false);//可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.setSensorEnable(false);//可选,设置是否使用传感器。默认是false
        mOption.setWifiScan(true); //可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差
        mOption.setLocationCacheEnable(true); //可选,设置是否使用缓存定位,默认为true
        return mOption;
    }

    /**
     * 定位监听
     */

    AMapLocationListener mLocationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation aMapLocation) {
            if (null != aMapLocation) {
                //解析定位结果
                String result = Utils.getLocationStr(aMapLocation);
                tv.setText(result);
                Log.e("定位", "aMapLocation is null" + result);
            } else {
                tv.setText("定位失败,aMapLocation is null");
                Log.e("定位失败", "aMapLocation is null");
            }
        }
    };


    //----------以下动态获取权限---------
    @Override
    protected void onResume() {
        super.onResume();
        if (isNeedCheck) {
            checkPermissions(needPermissions);
        }
    }


    /**
     * 检查权限
     *
     * @param
     * @since 2.5.0
     */
    private void checkPermissions(String... permissions) {
        //获取权限列表
        List needRequestPermissonList = findDeniedPermissions(permissions);
        if (null != needRequestPermissonList
                && needRequestPermissonList.size() > 0) {
            //list.toarray将集合转化为数组
            ActivityCompat.requestPermissions(this,
                    needRequestPermissonList.toArray(new String[needRequestPermissonList.size()]),
                    PERMISSON_REQUESTCODE);
        }
    }


    /**
     * 获取权限集中需要申请权限的列表
     *
     * @param permissions
     * @return
     * @since 2.5.0
     */
    private List findDeniedPermissions(String[] permissions) {
        List needRequestPermissonList = new ArrayList();
        //for (循环变量类型 循环变量名称 : 要被遍历的对象)
        for (String perm : permissions) {
            if (ContextCompat.checkSelfPermission(this,
                    perm) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.shouldShowRequestPermissionRationale(
                    this, perm)) {
                needRequestPermissonList.add(perm);
            }
        }
        return needRequestPermissonList;
    }

    /**
     * 检测是否说有的权限都已经授权
     *
     * @param grantResults
     * @return
     * @since 2.5.0
     */
    private boolean verifyPermissions(int[] grantResults) {
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String[] permissions, int[] paramArrayOfInt) {
        if (requestCode == PERMISSON_REQUESTCODE) {
            if (!verifyPermissions(paramArrayOfInt)) {      //没有授权
                showMissingPermissionDialog();              //显示提示信息
                isNeedCheck = false;
            }
        }
    }

    /**
     * 显示提示信息
     *
     * @since 2.5.0
     */
    private void showMissingPermissionDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.notifyTitle);
        builder.setMessage(R.string.notifyMsg);

        // 拒绝, 退出应用
        builder.setNegativeButton(R.string.cancel,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                });

        builder.setPositiveButton(R.string.setting,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startAppSettings();
                    }
                });

        builder.setCancelable(false);

        builder.show();
    }


    /**
     * 启动应用的设置
     *
     * @since 2.5.0
     */
    private void startAppSettings() {
        Intent intent = new Intent(
                Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivity(intent);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            this.finish();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

}

Utils

public class Utils {
    /**
     *  开始定位
     */
    public final static int MSG_LOCATION_START = 0;
    /**
     * 定位完成
     */
    public final static int MSG_LOCATION_FINISH = 1;
    /**
     * 停止定位
     */
    public final static int MSG_LOCATION_STOP= 2;

    public final static String KEY_URL = "URL";
    public final static String URL_H5LOCATION = "file:///android_asset/location.html";
    /**
     * 根据定位结果返回定位信息的字符串
     * @param loc
     * @return
     */
    public synchronized static String getLocationStr(AMapLocation location){
        if(null == location){
            return null;
        }
        StringBuffer sb = new StringBuffer();
        //errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
        if(location.getErrorCode() == 0){
            sb.append("定位成功" + "\n");
            sb.append("定位类型: " + location.getLocationType() + "\n");
            sb.append("经    度    : " + location.getLongitude() + "\n");
            sb.append("纬    度    : " + location.getLatitude() + "\n");
            sb.append("精    度    : " + location.getAccuracy() + "米" + "\n");
            sb.append("提供者    : " + location.getProvider() + "\n");

            sb.append("速    度    : " + location.getSpeed() + "米/秒" + "\n");
            sb.append("角    度    : " + location.getBearing() + "\n");
            // 获取当前提供定位服务的卫星个数
            sb.append("星    数    : " + location.getSatellites() + "\n");
            sb.append("国    家    : " + location.getCountry() + "\n");
            sb.append("省            : " + location.getProvince() + "\n");
            sb.append("市            : " + location.getCity() + "\n");
            sb.append("城市编码 : " + location.getCityCode() + "\n");
            sb.append("区            : " + location.getDistrict() + "\n");
            sb.append("区域 码   : " + location.getAdCode() + "\n");
            sb.append("地    址    : " + location.getAddress() + "\n");
            sb.append("兴趣点    : " + location.getPoiName() + "\n");
            //定位完成的时间
            sb.append("定位时间: " + formatUTC(location.getTime(), "yyyy-MM-dd HH:mm:ss") + "\n");
        } else {
            //定位失败
            sb.append("定位失败" + "\n");
            sb.append("错误码:" + location.getErrorCode() + "\n");
            sb.append("错误信息:" + location.getErrorInfo() + "\n");
            sb.append("错误描述:" + location.getLocationDetail() + "\n");
        }
        //定位之后的回调时间
        sb.append("回调时间: " + formatUTC(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss") + "\n");
        return sb.toString();
    }

    private static SimpleDateFormat sdf = null;
    public synchronized static String formatUTC(long l, String strPattern) {
        if (TextUtils.isEmpty(strPattern)) {
            strPattern = "yyyy-MM-dd HH:mm:ss";
        }
        if (sdf == null) {
            try {
                sdf = new SimpleDateFormat(strPattern, Locale.CHINA);
            } catch (Throwable e) {
            }
        } else {
            sdf.applyPattern(strPattern);
        }
        return sdf == null ? "NULL" : sdf.format(l);
    }
}

几个String

 <string name="notifyTitle">提示string>
    <string name="notifyMsg">当前应用缺少必要权限。\n\n请点击\"设置\"-\"权限\"-打开所需权限。string>
    <string name="gpsNotifyMsg">当前应用需要打开定位功能。\n\n请点击\"设置\"-\"定位服务\"-打开定位功能。string>
    <string name="setting">设置string>
    <string name="cancel">取消string>

关于动态权限

1.检查限限,如果没有就申请,申请权限的方法如下:
ActivityCompat.requestPermissions(this,needRequestPermissonList.toArray(newString[needRequestPermissonList.size()]),PERMISSON_REQUESTCODE);
第一个参数是activity,第二个参数是权限的数组,是数组的格式,,第三个参数是requestCode,requestPermissions()方法内部已经做了判断
2.回调方法
onRequestPermissionsResult(int requestCode,String[] permissions, int[] paramArrayOfInt)
通过判断int[] paramArrayOfInt返回的结果是否 == PackageManager.PERMISSION_GRANTED
如果不等于,则是没有授权,弹出对话框,进行用户选择 如果==于,则说明已经授权完成

你可能感兴趣的:(地图)