初次见面
在国内,说到集成地图服务,大多用的是高德和百度地图提供的相关接口。自从华为开始做地图服务以后(目前华为地图服务还不支持中国大陆区域,但愿不久的将来华为地图能够融入我们日常生活的方方面面吧~),迅速就有一大批开发者参与进来,其开放平台也提供了地图服务相关的接口和文档,那么今天就和华为地图来一次美丽的邂逅吧🤪
首先,我们先来打开【华为开发者平台-地图服务】的部分,可以看到下面内容:
业务简介
地图服务(Map Kit)给开发者提供一套地图开发调用的SDK,地图数据覆盖超过200个国家和地区,支持数十种语言,方便开发者轻松地在应用中集成地图相关的功能,全方位提升用户体验。
从支持的国家和地区的数量来看,华为一开始的目标就是针对全球提供服务的,直接对标谷歌地图,这很华为!!!
再来看版本更新说明,最近一次的更新在2020年9月18日,距离今天也是刚刚发布不久,版本号是5.0.2.300,不知不觉已经更新到5.x版本了,厉害了!
附上官方GitHub地址:HMS-Core/hms-mapkit-demo-java
集成准备
不同的地图服务,它的集成方式肯定是不完全一样的,那么我们先按照官网的文档来进行集成工作。ok,先来看一下开发准备相关的内容吧。
从文档我们可以看到,一共分为四个部分,分别为:
- 配置AppGallery Connect
- 集成HMS Core SDK
- 配置混淆脚本
- 添加权限
1. 配置AppGallery Connect
注册成为开发者
首先,要使用华为地图服务的能力,必须注册成为开发者并完成实名认证,这一步我之前就已经做好了,所以此过程就不赘述了,注册过程都大同小异很简单,注册网址:华为开发者联盟网站
创建应用
登录成功以后开始创建应用(先创建项目,再在项目下面创建应用),这里我包名注册为:com.test.hellohuaweimaps,截图如下:
创建成功以后,信息如下:
接着,我们点击agconnect-services.json的下载按钮,下载一个json文件,控油备用。可以先来看下这个文件内容是什么,其实就是我们刚才创建项目的一些信息,appid和包名这些之类的,打开如下:
{
"client":{
"cp_id":"260086000054571879",
"product_id":"736430079244623765",
"client_id":"444159260570420352",
"client_secret":"E02F4B50235CFD06F5B1A629B9A4E1FF6E51C5D9712FE9203A4FC3F26DC8CDF1",
"app_id":"102999311",
"package_name":"com.test.hellohuaweimaps",
"api_key":"CgB6e3x9LlZu7CzGeBgFTFlfnN3HEIEkSZSYEudrrDlhlqfQNlQbPOhsy3W/BZbkXpxZDyqqMkdyrtC36iYZ2I31"
},
"configuration_version":"1.0"
}
-
配置签名证书指纹
那么,为什么要配置这个签名证书呢,原因很简单,我们来看官网的描述是这样的:
签名证书指纹用于在通过华为HMS Core SDK调用HMS Core(APK)时,校验应用的真实性。开发者在使用HMS Core(APK)前必须将签名证书指纹配置到AppGallery Connect,在配置前需要根据签名证书在本地生成签名证书指纹。
原因就是为了做一个合法检验了,为了过滤掉一些未签名的不法应用。OK,那我们先来生成签名证书指纹,你需要准备一个签名文件(keystore或者jks类型的文件),和配置好环境了的JDK,然后很简单一个命令就搞定了:
命令:keytool -list -v -keystore <签名文件路径>
zhuyongdeMacBook-Pro:~ zhuyong$ keytool -list -v -keystore /Users/zhuyong/Desktop/keystore/hwmapdemo.jks
输入密钥库口令:
密钥库类型: jks
密钥库提供方: SUN
您的密钥库包含 1 个条目
别名: bravejoy
创建日期: 2020-9-4
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=bravejoy
发布者: CN=bravejoy
序列号: 6c406261
有效期为 Fri Sep 04 20:03:09 CST 2020 至 Tue Aug 29 20:03:09 CST 2045
证书指纹:
MD5: F6:0E:41:C0:01:44:E5:C8:4E:D3:C7:4F:EE:A8:81:17
SHA1: EB:82:61:B1:84:07:C4:F7:CD:A0:56:31:9E:6B:74:A1:17:0E:52:94
SHA256: 76:20:FD:9A:18:DA:AB:B9:51:D7:9B:B8:00:4F:B9:3D:59:CD:86:24:4F:13:A3:70:16:3E:D7:7C:04:3C:D7:1A
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3
复制其中的SHA256数据,然后粘贴到对应位置即可,我这里生成配置如下:
2. 集成HMS Core SDK
-
打开Android Studio,新建项目
ps:注意包名要和上面一致,我这里为:com.test.hellohuaweimaps
新建项目以后,把刚才下载的json文件放至如下位置:
-
配置AGC插件和SDK的Maven仓库地址
打开项目根目录build.gradle文件,配置如下:
buildscript {
repositories {
google()
jcenter()
//agconnect插件maven仓地址,必须配置
maven {url 'https://developer.huawei.com/repo/'}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.1'
////agconnect插件
classpath 'com.huawei.agconnect:agcp:1.3.1.300'
}
}
allprojects {
repositories {
google()
jcenter()
//maven仓地址,下载地图sdk
maven {url 'https://developer.huawei.com/repo/'}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
-
依赖地图SDK
打开app目录下的build.gradle文件,配置如下:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'//agc相关插件
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.test.hellohuaweimaps"
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
//华为地图SDK
implementation 'com.huawei.hms:maps:5.0.2.300'
}
- 执行sync,同步成功
3. 配置混淆脚本
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
4. 添加权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
初次握手
到这里其实我们已经做了很多工作了,那么从现在开始我们就要开始真正地使用地图API了。
-
使用MapView控件
打开activity_main文件,引用MapView控件如下:
<?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"
tools:context=".MainActivity">
<com.huawei.hms.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 在Activity中声明并使用
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
private MapView mMapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMapView = findViewById(R.id.mapView);
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle("MapViewBundleKey");
}
mMapView.onCreate(mapViewBundle);
mMapView.getMapAsync(this);
}
/**
* 当地图准备完成以后,会回调次方法
*
* @param huaweiMap 地图对象
*/
@Override
public void onMapReady(HuaweiMap huaweiMap) {
}
@Override
protected void onStart() {
super.onStart();
mMapView.onStart();
}
@Override
protected void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mMapView.onPause();
}
@Override
protected void onStop() {
super.onStop();
mMapView.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
}
-
运行项目
然后看到的效果是这样的,只有一些网格状的东西,根本看不到地图,脑瓜子嗡嗡的:
想一下,我们刚才在官网配置的签名证书指纹貌似还没有派上用场,问题肯定是出在这里了,来看一下有没有报错的日志信息,从日志里我们可以看到下面这样一句error日志,告诉我们证书指纹无效,因为我们并没有对apk进行签名。
HmsMapKit_AuthenticateClient_319: responseBody is returnCode: 010002;
resultInfo : the certificate fingerprint is invalid.
先不配置签名,我们先来用签名文件打包一个apk试一下,然后手动安装运行:
果不其然,地图出来了哦!!!
备注:使用华为地图服务需要在手机提前安装HmsCore【华为移动服务】。
好吧,既然已经确定了原因所在,那我们就在gradle里配置一下apk签名吧,打开app目下的build.gradle文件,在android{}内增加如下配置:
signingConfigs {
release {
//将签名文件放至app根目录下,和 agconnect-services.json在同一个目录下
storeFile file("hwmapdemo.jks")
storePassword "123456"
keyAlias "bravejoy"
keyPassword "123456"
v2SigningEnabled true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
//此配置是为了debug模式下也能够对apk进行签名,方便运行调试。
signingConfig signingConfigs.release
}
}
执行Sync,然后卸载手机app,再次直接点击运行,地图成功显示。
初次互动
既然地图都已经出来了,那就再小小地互动一下吧。
-
移动相机视角
移动到北京的位置(经纬度:39.909736,116.397400) -
添加一个marker,并增加点击事件
在onMapReady回调方法中添加以下代码:
/**
* 当地图准备完成以后,会回调次方法
*
* @param huaweiMap 地图对象
*/
@Override
public void onMapReady(HuaweiMap huaweiMap) {
//构造一个经纬度坐标对象
LatLng latLng = new LatLng(39.909736, 116.397400);
//移动相机到指定位置
huaweiMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 3));
//在地图上添加Marker
huaweiMap.addMarker(new MarkerOptions()
.position(latLng)
.icon(BitmapDescriptorFactory.defaultMarker())
.title("I'm Beijing")
.snippet("I'm Beijing"));
//添加Marker点击事件监听器
huaweiMap.setOnMarkerClickListener(new HuaweiMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
Toast.makeText(MainActivity.this, "This is Beijing", Toast.LENGTH_SHORT).show();
return false;
}
});
}
好了,到这里就算是跟华为地图真的认识了,以后愿她会认识更多的开发者,也希望她会越来越好,成为世界第一!!!