如何在安卓项目里使用高德地图

如何在安卓项目里使用高德地图

导入依赖

适用于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中使用地图,我们需要布置三个文件

  1. 在AndroidManifest中索取相应的权限,并添加高德key
  2. 展示地图的Activity
  3. 对应的布局文件layout

AndroidManifest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//地图SDK(包含其搜索功能)需要的基础权限

<!--允许程序打开网络套接字-->
<uses-permission android:name="android.permission.INTERNET" />
<!--允许程序设置内置sd卡的写权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--允许程序获取网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允许程序访问WiFi网络信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--允许程序读写手机状态和身份-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--允许程序访问CellID或WiFi热点来获取粗略的位置-->
<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

使用包名+类就可以找到相应控件

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();
//在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
mMapView.onPause();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//在activity执行onSaveInstanceState时执行mMapView.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"));
//aMAp是对应的地图控件,获取方法见上面的文章

绘制线

用一系列的地理点就可以在地图上绘制轨迹,会将所有经纬度点连接。

在实际使用过程中只需要得到一个轨迹列表,就可以调用相应的方法绘制轨迹。

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)));

更复杂的使用

待更

文章目录
  1. 1. 如何在安卓项目里使用高德地图
    1. 1.1. 导入依赖
    2. 1.2. 使用地图
      1. 1.2.1. 在Activity中使用
        1. 1.2.1.1. AndroidManifest
        2. 1.2.1.2. layout
        3. 1.2.1.3. Activity
      2. 1.2.2. Fragment中使用高德地图
    3. 1.3. 绘图
      1. 1.3.1. 简介
      2. 1.3.2. 绘制一个点
      3. 1.3.3. 绘制线
    4. 1.4. 更复杂的使用
|