高德地图定位

     在开发中很多时候我们都会用到定位功能,现在介绍一下如何在项目中使用高德地图sdk进行定位。

   1.首先我们在Android Studio上创建一个应用,需要其包名以及SSH1

 

   SHA1的获取方式:SHA1获取方式

   代码获取SHA1:

public static String sHA1(Context context) {
    try {
        PackageInfo info = context.getPackageManager().getPackageInfo(
                context.getPackageName(), PackageManager.GET_SIGNATURES);
        byte[] cert = info.signatures[0].toByteArray();
        MessageDigest md = MessageDigest.getInstance("SHA1");
        byte[] publicKey = md.digest(cert);
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < publicKey.length; i++) {
            String appendString = Integer.toHexString(0xFF & publicKey[i])
                    .toUpperCase(Locale.US);
            if (appendString.length() == 1)
                hexString.append("0");
            hexString.append(appendString);
            hexString.append(":");
        }
        String result= hexString.toString();
        return result.substring(0, result.length()-1);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return null;
}


   2.登录高德地图开发者平台新建项目,获取Appid

    A.进入高德地图开发者平台,进行登录;若没有开发者帐号,请进行注册。链接:高德地图开发者平台链接

  


  B.登陆后点击“控制台”进入控制台界面



 c。点击“创建新应用”,创建应用

 


  点击“完成”后如下


点击“添加新密钥”,获得appKey,在这里需要我们之前的应用包名以及SHA1。

完成之后,我们就可以获得该应用的对应高德地图的appKey

 

3.我们已经获得appkey,接下来我们需要下载高德地图的sdk。

点击“开发文档”下载,下载你所需的功能所对应的sdk



4.将jar包导入项目中



5.在清单文件中配置所需权限

<!--用于进行网络定位-->
<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>
<!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<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>

在清单文件中配置appKey

    <!--高德地图配置appkey-->
    <meta-data
        android:name="com.amap.api.v2.apikey"
        android:value="f3fc5c728bdc900bb9078e6e1f09fd50"/>
    <service android:name="com.amap.api.location.APSService"></service>

7.我们启动一个广播监听器来监听系统是否有网络,有网络,进行定位;无网络,不进行定位,需在清单文件中声明

import android.content.BroadcastReceiver;

import android.content.Context; import android.content.Intent;

import android.net.ConnectivityManager;

import android.net.NetworkInfo;

import android.util.Log;

import com.project.map.utils.HnConstant;

import com.project.map.utils.HnUtil;

import static com.project.map.utils.HnConstant.SETTING.NETWORK;

public class NetWorkStatusReceiver extends BroadcastReceiver {

private ConnectivityManager mConnectivityManager;
private String TAG="NetWorkStatusReceiver";
@Override
public void onReceive(Context context, Intent intent) {
     String action=intent.getAction();
     if(ConnectivityManager.CONNECTIVITY_ACTION.equals(action)){//获取网络状态改变广播
         Log.i(TAG,"接收到网络状态改变广播");
         mConnectivityManager= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
         NetworkInfo  mNetworkInfo=mConnectivityManager.getActiveNetworkInfo();
         if(mNetworkInfo!=null&&mNetworkInfo.isAvailable()){
             HnUtil.sendBroadCastReceiver(context, NETWORK);
         }else{
             HnUtil.sendBroadCastReceiver(context, HnConstant.SETTING.NOT_NETWORK);
         }
     }
}

}}


8.启动服务,在后台进行定位。需在清单文件中声明

package com.project.map.server;

import android.app.Service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Handler;

import android.os.IBinder;

import android.os.Message;

import android.support.annotation.Nullable;

import android.text.TextUtils;

import android.util.Log;

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 com.project.map.utils.HnConstant;

import java.text.DecimalFormat;

import java.text.SimpleDateFormat;

import java.util.Locale;

public class HnLocationService extends Service {

private static String TAG="HnLocationService";
private AMapLocationClient locationClient;//定位客户端
private AMapLocationClientOption locationOption = new AMapLocationClientOption();//参数配置
private static SimpleDateFormat sdf = null;
private MyReceiver receiver;


private static  int  stop_location=1;//停止定位
private Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what){
            case 0:

                break;
            case 1:
                if(locationClient!=null){
                    locationClient.stopLocation();
                    locationClient.onDestroy();
                    locationClient=null;
                    locationListener=null;
                }
                Log.e(TAG,"停止定位");
                break;
        }

    }
};


@Override
public void onCreate() {
    super.onCreate();
    registerBroadBreceiver();
    initLocation();
    startLocation();
    Log.e(TAG,"定位服务启动");
}

private void registerBroadBreceiver() {
    receiver=new  MyReceiver();
    IntentFilter  filter=new IntentFilter();
    filter.addAction(HnConstant.SETTING.NETWORK);
    filter.addAction(HnConstant.SETTING.NOT_NETWORK);
    registerReceiver(receiver,filter);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return Service.START_STICKY;
}


@Override
public void onDestroy() {
    unregisterReceiver(receiver);
    super.onDestroy();
    Log.e(TAG,"定位服务销毁");
}


/**
 * 初始化定位
 *
 * @since 2.8.0
 * @author hongming.wang
 *
 */
private void initLocation(){
    //初始化client
    locationClient = new AMapLocationClient(this.getApplicationContext());
    //初始化定位参数
    AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
    //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
    mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
    //设置定位间隔,单位毫秒,默认为2000ms
    mLocationOption.setInterval(20*1000);
    //设置定位参数
    locationClient.setLocationOption(mLocationOption);
    // 设置定位监听
    locationClient.setLocationListener(locationListener);

}
/**
 * 默认的定位参数
 * @since 2.8.0
 * @author hongming.wang
 *
 */
private AMapLocationClientOption getDefaultOption(){
    AMapLocationClientOption mOption = new AMapLocationClientOption();
    mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
    mOption.setGpsFirst(false);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭
    mOption.setHttpTimeOut(30000);//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
    mOption.setInterval(3000);//可选,设置定位间隔。默认为3秒
    mOption.setNeedAddress(true);//可选,设置是否返回逆地理地址信息。默认是ture
    mOption.setOnceLocation(false);//可选,设置是否单次定位。默认是false
    return mOption;
}

/**
 * 定位监听
 */
AMapLocationListener locationListener = new AMapLocationListener() {
    @Override
    public void onLocationChanged(AMapLocation loc) {
        if (null != loc) {
            //解析定位结果
            getLocationStr(loc);
        } else {
            Log.d(TAG,"定位失败");
        }
    }
};
/**
 * 开始定位
 *
 * @since 2.8.0
 * @author hongming.wang
 *
 */
private void startLocation(){
    // 设置定位参数
    locationClient.setLocationOption(locationOption);
    // 启动定位
    locationClient.startLocation();

}

/**
 * 根据定位结果返回定位信息的字符串
 * @param
 * @return
 */
public synchronized 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");

        if (location.getProvider().equalsIgnoreCase(
                android.location.LocationManager.GPS_PROVIDER)) {
            // 以下信息只有提供者是GPS时才会有
            sb.append("速    度    : " + location.getSpeed() + "米/秒" + "\n");
            sb.append("角    度    : " + location.getBearing() + "\n");
            // 获取当前提供定位服务的卫星个数
            sb.append("星    数    : "
                    + location.getSatellites() + "\n");
        } else {
            // 提供者是GPS时是没有以下信息的
            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:sss") + "\n");
        }
        String city=location.getCity();
        String pro=location.getProvider();

        DecimalFormat df   = new DecimalFormat("######0.000000");
        double   latitude=   location.getLatitude();
        double   longitude= (float) location.getLongitude();
        String latitudeResult=df.format(latitude);
        String longitudeResult=df.format(longitude);
        //停止定位
         stopLocation();


    } 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:sss") + "\n");
     Log.e(TAG,"定位信息:"+sb.toString());
    return sb.toString();
}


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);
    }
    if (l <= 0l) {
        l = System.currentTimeMillis();
    }
    return sdf == null ? "NULL" : sdf.format(l);
}


/**
 *广播接收器
 */
class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String action=intent.getAction();
        Log.i(TAG,"接后到的广播:"+action);
        if(HnConstant.SETTING.NETWORK.equals(action)){//接收到有网络状态
               rsetLocaton();
        }else if(HnConstant.SETTING.NOT_NETWORK.equals(action)){//无网络状态


        } 
    }
}

/**
 * 定位地址
 */
private void rsetLocaton() {
        initLocation();
        startLocation();

}

/**
 * 停止定位
 */
public void stopLocation(){
    Message msg = handler.obtainMessage(stop_location);
    handler.sendMessage(msg);
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

}}


说明:this服务在获取到城市定位数据后通过stopLocation()来停止定位,否则将会隔隔3秒进行一次定位;通过网络状态改变来进行重新的定位/断开定位


9.在MainActivity.class主界面启动服务,运行即可




源码下载地址




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值