如何在安卓项目里使用高德地图
导入依赖
适用于AndroidStudio 4.x版本
根据自己的需求在bulid.gradle(Module)的dependencies添加对应的sdk
添加3d地图示例 implementation 'com.amap.api:3dmap:7.9.1'
结构为 implementation ‘包名:sdk:版本’
各sdk:
sdk |
引入代码 |
3d地图 |
implementation ‘com.amap.api:3dmap:latest.integration’ |
2d地图 |
implementation ‘com.amap.api:map2d:latest.integration’ |
导航 |
implementation ‘com.amap.api:navi-3dmap:latest.integration’ |
搜索 |
implementation ‘com.amap.api:search:latest.integration’ |
定位 |
implementation ‘com.amap.api:location:latest.integration’ |
使用latest.integration会自动下载最新版
建议使用3d地图,可以避免许多潜在的麻烦,关于高德的其他sdk的依赖名可以在官方指南里找到。2d地图和3d地图无法同时使用,存在冲突。
只需要添加依赖就行了,Gradle会自动下载需要的依赖。
而高德官方目前(2021-4)的文档里面仍然提供老版本的安卓项目的范例,对于初学者不是很友好。对于目前版本的使用者,不必要手动添加依赖。
关于Gradle的说明可见这:(尚未编写)
使用地图
在Activity中使用
说明:为了在Activity中使用地图,我们需要布置三个文件
- 在AndroidManifest中索取相应的权限,并添加高德key
- 展示地图的Activity
- 对应的布局文件layout
AndroidManifest
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| //地图SDK(包含其搜索功能)需要的基础权限
<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" />
|
在application标签中加入如下内容:
1 2 3
| <meta-data android:name="com.amap.api.v2.apikey" android:value="key"> //开发者申请的key </meta-data>
|
layout
使用包名+类就可以找到相应控件
![](/../images/%E9%AB%98%E5%BE%B7%E7%BB%84%E4%BB%B6.png)
1 2 3 4 5 6 7 8 9
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.amap.api.maps3d.MapView android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent"></com.amap.api.maps3d.MapView> </LinearLayout>
|
布置好布局后我们在对应的activity控制地图。
Activity
使用地图需要管理地图控件的生命周期,不过基本和Activity的生命周期是一样的,差任何一步都会造成恐惧无法打开。
获取地图控件的方法和View一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package com.anleeos.map;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.amap.api.maps3d.MapView;
public class MainActivity extends AppCompatActivity { MapView mMapView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map); mMapView = (MapView) findViewById(R.id.map); mMapView.onCreate(savedInstanceState); } @Override protected void onDestroy() { super.onDestroy(); mMapView.onDestroy(); } @Override protected void onResume() { super.onResume(); mMapView.onResume(); } @Override protected void onPause() { super.onPause(); mMapView.onPause(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mMapView.onSaveInstanceState(outState); } }
|
Fragment中使用高德地图
在实践过程中我们不仅仅需要在Activity中使用地图,有时候也需要在Fragment里面使用它。此时配置过程有些不太一样。
在Fragment里不能使用MapView,而使用TextureMapView。但是TextureMapView的性能要低不少,所以还是推荐单独在Activity里使用
来源高德官方示例文档,但是因为示例版本过老,不太符合当前环境,做了一些修改如下。
在fragment中我们在onActivityCreated中获取地图控件,其他生命周期与Activity类似。在fragment对应的组件中注册地图控件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider;
import com.amap.api.maps.AMap; import com.amap.api.maps.CameraUpdateFactory; import com.amap.api.maps.TextureMapView; import com.amap.api.maps.model.CameraPosition; import com.amap.api.maps.model.LatLng;
import java.lang.reflect.Field;
public class MapFragment extends Fragment {
private HomeViewModel homeViewModel; private TextureMapView textureMapView; private AMap aMap; public static final LatLng TIANJIN = new LatLng(39.13,117.2); protected static CameraPosition cameraPosition;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class); View root = inflater.inflate(R.layout.navigation_home, container, false); return root; } LatLng getTarget() { return TIANJIN; } CameraPosition getCameraPosition() { return cameraPosition; } void setCameraPosition(CameraPosition cameraPosition) { cameraPosition = cameraPosition; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); textureMapView = (TextureMapView) getView().findViewById(R.id.map);
if (textureMapView != null) { textureMapView.onCreate(savedInstanceState); aMap = textureMapView.getMap(); if (getCameraPosition() == null) { aMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(getTarget(), 10, 0, 0))); }else { aMap.moveCamera(CameraUpdateFactory.newCameraPosition(getCameraPosition())); } } } @Override public void onResume() { super.onResume(); textureMapView.onResume(); }
@Override public void onPause() { super.onPause(); textureMapView.onPause(); }
@Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); textureMapView.onSaveInstanceState(outState); }
@Override public void onDestroyView() { super.onDestroyView(); setCameraPosition(aMap.getCameraPosition()); super.onDestroy(); textureMapView.onDestroy(); } }
|
对应的xml
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/saswell_pink" tools:context=".ui.home.HomeFragment" > <com.amap.api.maps.TextureMapView android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent"/> </androidx.constraintlayout.widget.ConstraintLayout>
|
绘图
简介
在上一个代码中能看见使用了public static final LatLng TIANJIN = new LatLng(39.13,117.2);// 天津市经纬度
的代码。
LatLng(Latitude and Longitude)是一个地理坐标点类(纬度,经度)。我们使用LatLng对象在程序中表示一个地理点。
在高德地图(包括其他类似的地图)中使用Marker(标记)来管理地图上的点。创建一个Marker需要位置,可以设置标题,内容以及其他东西。
常用属性有:position,title,snippel,draggable,visible,anchor,alpha。
绘制一个点
新建一个Marker就可以在地图上显示一个点。
在我们想要绘制的地图上调用addMarker方法。
1 2 3 4 5
| LatLng latLng = new LatLng(39.906901,116.397972);
final Marker marker = aMap.addMarker(new MarkerOptions().position(latLng).title("北京").snippet("DefaultMarker"));
|
绘制线
用一系列的地理点就可以在地图上绘制轨迹,会将所有经纬度点连接。
在实际使用过程中只需要得到一个轨迹列表,就可以调用相应的方法绘制轨迹。
1 2 3 4 5 6 7 8
| List<LatLng> latLngs = new ArrayList<LatLng>(); latLngs.add(new LatLng(39.999391,116.135972)); latLngs.add(new LatLng(39.898323,116.057694)); latLngs.add(new LatLng(39.900430,116.265061)); latLngs.add(new LatLng(39.955192,116.140092)); polyline =AMap.addPolyline(new PolylineOptions(). addAll(latLngs).width(10).color(Color.argb(255, 1, 1, 1)));
|
更复杂的使用
待更