欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发之高德地图实现定位

程序员文章站 2022-05-20 22:45:23
在应用开发中,地图开发是经常需要使用的“组件”,google map虽然有官方教程,无奈用不起来,原因你懂的~~那么国内比较出名的是就是百度地图和高德地图,由于个人喜好,所...

在应用开发中,地图开发是经常需要使用的“组件”,google map虽然有官方教程,无奈用不起来,原因你懂的~~那么国内比较出名的是就是百度地图和高德地图,由于个人喜好,所以选择了高德地图lbs,废话不说,上干货。

1、注册开发者,创建应用

这个几乎是所有开放平台都通用的做法,无外乎注册帐号,成为开发者,然后创建一个android应用,会为你分配一个key绑定你的服务。

Android开发之高德地图实现定位

注册key.png

2、下载sdk,导入jar包,add to library

Android开发之高德地图实现定位

jar包.png

第一个是2d地图的jar包,因为最后定位以后我要在地图上标出来位置

第二个是用于定位的jar包

注意:如果使用的是3d地图,那么地图sdk和导航sdk需要引入so库文件,先在app/src/main/目录下新建一个jnilibs目录,将so放到此目录下

3、配置androidmainfest.xml文件

<!-- 申请必要的权限-->
<uses-permission android:name="android.permission.internet" />
<uses-permission android:name="android.permission.write_external_storage" />
<uses-permission android:name="android.permission.access_network_state" />
<uses-permission android:name="android.permission.access_wifi_state" />
<uses-permission android:name="android.permission.read_phone_state" />
<uses-permission android:name="android.permission.access_coarse_location" />
<uses-permission android:name="android.permission.access_fine_location" />
<uses-permission android:name="android.permission.access_location_extra_commands" />
<uses-permission android:name="android.permission.access_mock_location" />
<uses-permission android:name="android.permission.change_wifi_state" />

<application
  android:icon="@mipmap/ic_launcher"
  android:label="@string/app_name"
  android:theme="@style/apptheme"

  >
  <!--设置key-->
  <meta-data
   android:name="com.amap.api.v2.apikey"
   android:value="这里填写第一步你申请的那个key" />
  <!--声明定位service-->
  <service android:name="com.amap.api.location.apsservice"></service>
</application>

4、activity的布局文件

<com.amap.api.maps2d.mapview
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/map"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent" />

很简单,就一个2d的地图

5、activity,注释非常详细

//监听定位和定位变化
public class mainactivity extends appcompatactivity implements locationsource, amaplocationlistener {

 //显示地图需要的变量
 private mapview mapview;//地图控件
 private amap amap;//地图对象

 //定位需要的声明
 private amaplocationclient mlocationclient = null;//定位发起端
 private amaplocationclientoption mlocationoption = null;//定位参数
 private onlocationchangedlistener mlistener = null;//定位监听器

 //标识,用于判断是否只显示一次定位信息和用户重新定位
 private boolean isfirstloc = true;

 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);

  //显示地图
  mapview = (mapview) findviewbyid(r.id.map);
  //必须要写
  mapview.oncreate(savedinstancestate);
  //获取地图对象
  amap = mapview.getmap();

  //设置显示定位按钮 并且可以点击
  uisettings settings = amap.getuisettings();
  //设置定位监听
  amap.setlocationsource(this);
  // 是否显示定位按钮
  settings.setmylocationbuttonenabled(true);
  // 是否可触发定位并显示定位层
  amap.setmylocationenabled(true);

  //定位的小图标 默认是蓝点 这里自定义一团火,其实就是一张图片
  mylocationstyle mylocationstyle = new mylocationstyle();
  mylocationstyle.mylocationicon(bitmapdescriptorfactory.fromresource(r.mipmap.firetwo));
  mylocationstyle.radiusfillcolor(android.r.color.transparent);
  mylocationstyle.strokecolor(android.r.color.transparent);
  amap.setmylocationstyle(mylocationstyle);
  //开始定位
  initloc();
 }
 //定位
 private void initloc() {
  //初始化定位
  mlocationclient = new amaplocationclient(getapplicationcontext());
  //设置定位回调监听
  mlocationclient.setlocationlistener(this);
  //初始化定位参数
  mlocationoption = new amaplocationclientoption();
  //设置定位模式为高精度模式,battery_saving为低功耗模式,device_sensors是仅设备模式
  mlocationoption.setlocationmode(amaplocationclientoption.amaplocationmode.hight_accuracy);
  //设置是否返回地址信息(默认返回地址信息)
  mlocationoption.setneedaddress(true);
  //设置是否只定位一次,默认为false
  mlocationoption.setoncelocation(false);
  //设置是否强制刷新wifi,默认为强制刷新
  mlocationoption.setwifiactivescan(true);
  //设置是否允许模拟位置,默认为false,不允许模拟位置
  mlocationoption.setmockenable(false);
  //设置定位间隔,单位毫秒,默认为2000ms
  mlocationoption.setinterval(2000);
  //给定位客户端对象设置定位参数
  mlocationclient.setlocationoption(mlocationoption);
  //启动定位
  mlocationclient.startlocation();
 }

 //定位回调函数
 @override
 public void onlocationchanged(amaplocation amaplocation) {
  if (amaplocation != null) {
   if (amaplocation.geterrorcode() == 0) {
    //定位成功回调信息,设置相关消息
    amaplocation.getlocationtype();//获取当前定位结果来源,如网络定位结果,详见官方定位类型表
    amaplocation.getlatitude();//获取纬度
    amaplocation.getlongitude();//获取经度
    amaplocation.getaccuracy();//获取精度信息
    simpledateformat df = new simpledateformat("yyyy-mm-dd hh:mm:ss");
    date date = new date(amaplocation.gettime());
    df.format(date);//定位时间
    amaplocation.getaddress();//地址,如果option中设置isneedaddress为false,则没有此结果,网络定位结果中会有地址信息,gps定位不返回地址信息。
    amaplocation.getcountry();//国家信息
    amaplocation.getprovince();//省信息
    amaplocation.getcity();//城市信息
    amaplocation.getdistrict();//城区信息
    amaplocation.getstreet();//街道信息
    amaplocation.getstreetnum();//街道门牌号信息
    amaplocation.getcitycode();//城市编码
    amaplocation.getadcode();//地区编码

    // 如果不设置标志位,此时再拖动地图时,它会不断将地图移动到当前的位置
    if (isfirstloc) {
     //设置缩放级别
     amap.movecamera(cameraupdatefactory.zoomto(17));
     //将地图移动到定位点
     amap.movecamera(cameraupdatefactory.changelatlng(new latlng(amaplocation.getlatitude(), amaplocation.getlongitude())));
     //点击定位按钮 能够将地图的中心移动到定位点
     mlistener.onlocationchanged(amaplocation);
     //添加图钉
     amap.addmarker(getmarkeroptions(amaplocation));
     //获取定位信息
     stringbuffer buffer = new stringbuffer();
     buffer.append(amaplocation.getcountry() + "" + amaplocation.getprovince() + "" + amaplocation.getcity() + "" + amaplocation.getprovince() + "" + amaplocation.getdistrict() + "" + amaplocation.getstreet() + "" + amaplocation.getstreetnum());
     toast.maketext(getapplicationcontext(), buffer.tostring(), toast.length_long).show();
     isfirstloc = false;
    }

   } else {
    //显示错误信息errcode是错误码,errinfo是错误信息,详见错误码表。
    log.e("amaperror", "location error, errcode:"
      + amaplocation.geterrorcode() + ", errinfo:"
      + amaplocation.geterrorinfo());

    toast.maketext(getapplicationcontext(), "定位失败", toast.length_long).show();
   }
  }
 }

 //自定义一个图钉,并且设置图标,当我们点击图钉时,显示设置的信息
 private markeroptions getmarkeroptions(amaplocation amaplocation) {
   //设置图钉选项
  markeroptions options = new markeroptions();
  //图标
  options.icon(bitmapdescriptorfactory.fromresource(r.mipmap.fire));
  //位置
  options.position(new latlng(amaplocation.getlatitude(), amaplocation.getlongitude()));
  stringbuffer buffer = new stringbuffer();
  buffer.append(amaplocation.getcountry() + "" + amaplocation.getprovince() + "" + amaplocation.getcity() + "" + amaplocation.getdistrict() + "" + amaplocation.getstreet() + "" + amaplocation.getstreetnum());
  //标题
  options.title(buffer.tostring());
  //子标题
  options.snippet("这里好火");
  //设置多少帧刷新一次图片资源
  options.period(60);
  return options;

 }
 //激活定位
 @override
 public void activate(onlocationchangedlistener listener) {
  mlistener = listener;
 }

 //停止定位
 @override
 public void deactivate() {
  mlistener = null;
 }

 /**
  * 方法必须重写
  */
 @override
 protected void onresume() {
  super.onresume();
  mapview.onresume();
 }

 /**
  * 方法必须重写
  */
 @override
 protected void onpause() {
  super.onpause();
  mapview.onpause();
 }

 /**
  * 方法必须重写
  */
 @override
 protected void onsaveinstancestate(bundle outstate) {
  super.onsaveinstancestate(outstate);
  mapview.onsaveinstancestate(outstate);
 }

 /**
  * 方法必须重写
  */
 @override
 protected void ondestroy() {
  super.ondestroy();
  mapview.ondestroy();
 }
}

6、运行程序,点击自定义的 “火” 图钉,效果图如下:

Android开发之高德地图实现定位

location result.png

7、长按地图截图并保存图片

activity实现amap.onmaplongclicklistener和amap.onmaplongclicklistener接口,

然后activity的声明变为:

public class mainactivity extends appcompatactivity implements amap.onmaplongclicklistener, amap.onmapscreenshotlistener, locationsource, amaplocationlistener

分别实现下列两个的方法

 /**
  * 长按地图进行截屏
  *
  * @param latlng
  */
 @override
 public void onmaplongclick(latlng latlng) {

  // 设置截屏监听接口,截取地图可视区域
  // 需要传入一个 amap.onmaplongclicklistener 接口的实现者
  amap.getmapscreenshot(this);
 }
 /**
  * 截屏回调方法 保存截图
  */

 @override
 public void onmapscreenshot(bitmap bitmap) {
  simpledateformat sdf = new simpledateformat("yyyymmddhhmmss");
  try {
   // 保存在sd卡根目录下,图片为png格式。
   fileoutputstream fos = new fileoutputstream(
     environment.getexternalstoragedirectory() + "/test_"
       + sdf.format(new date()) + ".png");
   boolean b = bitmap.compress(bitmap.compressformat.png, 100, fos);
   try {
    fos.flush();
   } catch (ioexception e) {
    e.printstacktrace();
   }
   try {
    fos.close();
   } catch (ioexception e) {
    e.printstacktrace();
   }
   if (b)

    toast.maketext(mainactivity.this, "截屏成功", toast.length_long).show();
   else {
    toast.maketext(mainactivity.this, "截屏失败", toast.length_long).show();
   }
  } catch (filenotfoundexception e) {
   e.printstacktrace();
  }
 }

2016.8.26 补充

有很多简友按照如上过程走下来,发现实现不了我的效果,因此我总结了可能的原因:

1、androidmainfest.xml 里一定要将自己申请的key放进去;

2、申请key时有个sha-1的,千万不能错,错了也不能定位,因为一旦错了,就无法识别是你当前的应用了;

3、如果你使用的是3d的图,务必要将3d的库导进项目,我的案例是2d的;

4、一定要在真机测试。

有无法定位的朋友,请按照上述错误原因来排查。希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!