在涉及团购、外卖、快递、家政、物流、搬家等生活服务类的App、小程序中,填写收货地址是用户高频使用的功能。这一功能通常采取让用户手动填写的解决方案,例如上下拉动选择浙江省-->杭州市-->西湖区-->西溪街道,再切换到姓名输入框输入姓名-->电话输入框输入电话等一系列的操作。从中我们不难发现手动输入地址不仅费时费力,而且一不小心还会出现选错地址的现象。

那有没有什么方法能帮助用户又快又准确的填写地址呢?借助HMS Core 定位服务的融合定位+地理编码能力,生活服务类App可以自动定位获取用户当前位置信息或某地的行政区划信息、街道信息,并准确填写至地址栏中。用户无需自己手动输入,减少了操作时间,并且不用再担心填错地址。以下是我们提供的示例代码,开发者们按照步骤尝试,就可以轻松体验这个功能啦~

效果展示

开发实战

开发步骤

一、 开发准备

1. 登录AppGallery Connect网站,点击“我的项目”。找到您的项目在API管理开启location开关,在项目中点击需要配置签名证书指纹的应用。在“项目设置 > 常规”页面的“应用”区域,点击“SHA256证书指纹”后的“添加证书指纹”,输入生成的SHA256指纹。

2. 在“项目设置 > 常规”页面的“应用”区域,点击“agconnect-services.json”下载配置文件。将“agconnect-services.json”文件拷贝到应用级根目录下。

3. 项目级“build.gradle”文件

buildscript {
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' }
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
}
} allprojects {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
google()
jcenter()
mavenCentral()
}
}

应用级的“build.gradle”文件

plugins {
id 'com.android.application'
id 'com.huawei.agconnect'
}

在“dependencies ”中添加如下编译依赖

implementation 'com.huawei.hms:location:6.3.0.300'

二、 权限检查

1. 在“AndroidManifest.xml”文件中配置权限ACCESS_COARSE_LOCATION(粗略的位置权限),ACCESS_FINE_LOCATION(精确的位置权限)和ACCESS_BACKGROUND_LOCATION权限

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

2. 动态申请定位相关权限(Android 6.0及以上版本危险权限要求)

    Log.i(TAG, "android sdk < 28 Q");
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
String[] strings =
{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
ActivityCompat.requestPermissions(this, strings, 1);
}
} else {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
"android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
String[] strings = {Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
"android.permission.ACCESS_BACKGROUND_LOCATION"};
ActivityCompat.requestPermissions(this, strings, 2);
}
}

三、 获取定位结果

1. 设置定位参数,包括位置更新的间隔,定位类型等

mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
mSettingsClient = LocationServices.getSettingsClient(this);
mLocationRequest = new LocationRequest();
// Sets the interval for location update (unit: Millisecond)
mLocationRequest.setInterval(5000);
// Sets the priority
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

2. 调用getSettingsClient()接口获取SettingsClient实例。调用调用checkLocationSettings()检查设备开关设置

LocationSettingsRequest locationSettingsRequest = builder.build();
// Before requesting location update, invoke checkLocationSettings to check device settings.
Task<LocationSettingsResponse> locationSettingsResponseTask =
mSettingsClient.checkLocationSettings(locationSettingsRequest);
``` 检查开关开启之后 ,调用requestLocationUpdates()进行定位

locationSettingsResponseTask.addOnSuccessListener(new OnSuccessListener() {

@Override

public void onSuccess(LocationSettingsResponse locationSettingsResponse) {

Log.i(TAG, "check location settings success");

mFusedLocationProviderClient

.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())

.addOnSuccessListener(new OnSuccessListener() {

@Override

public void onSuccess(Void aVoid) {

Log.i(TAG, "requestLocationUpdatesWithCallback onSuccess");

}

})

.addOnFailureListener(new OnFailureListener() {

@Override

public void onFailure(Exception e) {

Log.e(TAG, "requestLocationUpdatesWithCallback onFailure:" + e.getMessage());

}

});

}

}).addOnFailureListener(new OnFailureListener() {

@Override

public void onFailure(Exception e) {

Log.e(TAG, "checkLocationSetting onFailure:" + e.getMessage());

int statusCode = 0;

if (e instanceof ApiException) {

statusCode = ((ApiException) e).getStatusCode();

}

switch (statusCode) {

case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:

try {

// When the startResolutionForResult is invoked, a dialog box is displayed, asking you

// to open the corresponding permission.

if (e instanceof ResolvableApiException) {

ResolvableApiException rae = (ResolvableApiException) e;

rae.startResolutionForResult(MainActivity.this, 0);

}

} catch (IntentSender.SendIntentException sie) {

Log.e(TAG, "PendingIntent unable to execute request.");

}

break;

default:

break;

}

}

});

### 四、	逆地理编码获取当前位置

成功获取定位信息的经纬度之后,将经纬度信息传递给使用地理编码服务(GeocoderService)获得地理编码请求对象,然后调用请求逆地理编码方法(getFromLocation),设置请求(GetFromLocationRequest)参数,获取逆地理编码信息回调。

if (null == mLocationCallback) {

mLocationCallback = new LocationCallback() {

@Override

public void onLocationResult(LocationResult locationResult) {

if (locationResult != null) {

List locations = locationResult.getLocations();

if (!locations.isEmpty()) {

ExecutorUtil.getInstance().execute(new Runnable() {

@Override

public void run() {

Locale locale = new Locale("zh", "CN");

GeocoderService geocoderService = LocationServices.getGeocoderService(MainActivity.this, locale);

GetFromLocationRequest getFromLocationRequest = new GetFromLocationRequest(locations.get(0).getLatitude(), locations.get(0).getLongitude(), 1);

geocoderService.getFromLocation(getFromLocationRequest)

.addOnSuccessListener(new OnSuccessListener<List>() {

@Override

public void onSuccess(List hwLocation) {

printGeocoderResult(hwLocation);

}

})

.addOnFailureListener(new OnFailureListener() {

@Override

public void onFailure(Exception e) {

Log.i(TAG, e.getMessage());

}

});

}

});

}

}

}

@Override

public void onLocationAvailability(LocationAvailability locationAvailability) {

if (locationAvailability != null) {

boolean flag = locationAvailability.isLocationAvailable();

Log.i(TAG, "onLocationAvailability isLocationAvailable:" + flag);

}

}

};

}

最后将获取到的结果显示在界面上即可。

**了解更多详情>>**

访问[华为开发者联盟官网](http://developer.huawei.com/consumer/cn/hms?ha_source=hms1)
获取[开发指导文档](http://developer.huawei.com/consumer/cn/doc/development?ha_source=hms1)
华为移动服务开源仓库地址:[GitHub](http://github.com/HMS-Core)、[Gitee](http://gitee.com/hms-core) **关注我们,第一时间了解 HMS Core 最新技术资讯~**

HMS Core定位服务在生活服务类App中可以自动填写收货地址啦的更多相关文章

  1. 如何用HMS Core位置和地图服务实现附近地点路径规划功能

    日常出行中,路径规划是很重要的部分.用户想要去往某个地点,获取到该地点的所有路径,再根据预估出行时间自行选择合适的路线,极大方便出行.平时生活中也存在大量使用场景,在出行类App中,根据乘客的目的地可 ...

  2. HMS Core音频编辑服务支持7种音频特效,助力一站式音频处理

    多媒体时代,音频作为内容传播中的重要形式,因其不受空间限制.认知负担小.声音元素多样化等特点,广泛应用于短视频制作.儿童在线教育.有声阅读.游戏等领域产品,在各种形式的音频呈现过程中,合理添加音效能够 ...

  3. 码上来战!探索“智”感生活,HMS Core线上Codelabs挑战赛第4期开始!

    HMS Core线上Codelabs挑战赛第4期正式开始!我们向所有实践力超强.创新力满满的开发者发出邀请,用你的超级"码"力,解锁更多应用价值! 生活里,我们被手机"秒 ...

  4. 放码来战!HMS Core线上Codelabs挑战赛正式开始

    亲爱的开发者,在1024程序员节即将到来之际,HMS Core准备了一场线上Codelabs挑战赛,现向你发出诚挚邀请,希望你能将新奇的想法和对产品的思考融入代码,用技术与世界对话. HMS Core ...

  5. 华为在HDC2021发布全新HMS Core 6 宣布跨OS能力开放

    [2021年10月22日·东莞]华为开发者大会 2021(Together)于今天正式开幕,华为在主题演讲中正式发布全新的HMS Core 6,向全球开发者开放7大领域的69个Kit和21,738个A ...

  6. HMS Core助力宝宝巴士为全球开发者展现高品质儿童数字内容

    本文分享于HMS Core开发者论坛<宝宝巴士携HMS Core为全球家庭用户提供优质儿童数字内容>采访稿整理 宝宝巴士是国内有着十多年出海经验的开发者,其旗下有超过200多款儿童益智互动 ...

  7. HMS Core挑战赛故事:鞋、街景、手办、玩具,原来这些都可以3D建模

    HMS Core线上Codelabs挑战赛第3期中,开发者通过学习和运用HMS Core开发的3D建模服务,生成3D建模应用demo,再使用demo为自己身边的一个实物完成建模.在提交的作品中,小编发 ...

  8. 【原】Github系列之一:一起做仿天气类应用中的实时模糊效果LiveBlur

    从本文开始,我将专门开辟一个Github Code系列,开源自己写的一部分有意思而且实用的demo,共同学习.以前都发布在git OSChina上,后面有空会陆陆续续整理到Github上.OSChin ...

  9. 电商、商城类APP常用标签"hot"--第三方开源--LabelView

    LabelView是在github上一个开源的标签库.其项目主页是:https://github.com/linger1216//labelview LabelView为一个TextView,Imag ...

随机推荐

  1. 【C# IO 操作 】编程对缓冲区的理解

      什么是缓冲区缓冲区又称为缓存,它是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区.缓冲区根据其对应的是输入设备还是 ...

  2. Python常用内建模块和第三方库

    目录 内建模块 1  datetime模块(处理日期和时间的标准库) datetime与timestamp转换 str与datetime转换 datetime时间加减,使用timedelta这个类 转 ...

  3. 在shell脚本里使用sftp批量传送文件

    转至:https://blog.csdn.net/istronger/article/details/52141530?utm_medium=distribute.pc_relevant.none-t ...

  4. WPS:字母自动变大写的解决办法

    设置中:

  5. MySQL第四讲

    昨日内容回顾 表与表之间建关系(外键) """ 表与表之间最多只有四种关系 一对多 多对多 一对一 没有关系 在确定表与表之间的关系的时候记住一句话 换位思考 " ...

  6. PHP之cURL(爬虫)

    public static function SendDataByCurl($url,$data=array()){ //对空格进行转义 $url = str_replace(' ','+',$url ...

  7. JZ-043-左旋转字符串

    左旋转字符串 题目描述 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S, 请你把其循环左移K位后的序列输出.例如,字符 ...

  8. JVM上篇:JVM与Java体系结构

    JVM笔记 JVM传言 Java不是最强大的语言,但是JVM是最强大的虚拟机 虚拟机分类 系统虚拟机 类似VMware,就属于系统虚拟机,它提供了一个可运行完整操作系统的平台 程序虚拟机 Java虚拟 ...

  9. linux 配置redis密码

    1.打开redis配置文件 vi /usr/local/redis/etc/redis.conf 添加requirepass 密码    将bind 127.0.0.1 ::1前的#去掉 保存退出 2 ...

  10. 『现学现忘』Docker常用命令 — 19、容器常用命令(一)

    目录 1.新建并启动容器 2.列出当前所有正在运行的容器 3.退出容器 4.启动容器 5.重启容器 6.停止容器 7.强制停止容器 8.删除已停止的容器 有镜像才能创建容器,这是根本前提. 我们下载一 ...