在涉及团购、外卖、快递、家政、物流、搬家等生活服务类的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. Map<String, String> map按key值排序

    private static String buildMd5Params(Map<String, String> map) { StringBuilder result = new Str ...

  2. linux批量修改root密码脚本

    转至:https://blog.csdn.net/onionm/article/details/100514892?utm_medium=distribute.pc_relevant_download ...

  3. @vue/cli的配置知道多少-publicPath,outputDir,assetsDir,indexPath,filenameHashing,configureWebpack,productionSourceMap

    vue.config.js的简单介绍 vue.config.js 是一个可选的配置文件, 在项目的 (和 package.json 同级的) 根目录中存在这个文件. 默认情况没有这个文件需要我们手动去 ...

  4. VS 返回值被忽略的解决方法

    •问题 用 Visual Studio 编写 C++ 代码的时候,一旦用到 scanf , freopen 等函数的时候,编译器总会不合时宜的给你提示 "返回值被忽略",那么该如何 ...

  5. POJ2723 题解

    WA了半天才发现居然是因为没看见这道题有多组数据,wzfl... 题目大意:有N对钥匙,对于每一对钥匙,如果使用了其中一把,另一把钥匙就会消失.接下来有M扇门,每扇门上有两把锁,分别对应两把钥匙(锁会 ...

  6. 「BUAA OO Unit 1 HW1」面向测试小白的简易评测机

    「BUAA OO Unit 1 HW1」面向测试小白的简易评测机 声明:本评测机所使用数据生成来自郭鸿宇同学,这对本评测机非常重要 目录 「BUAA OO Unit 1 HW1」面向测试小白的简易评测 ...

  7. 前端好用API之getBoundingClientRect

    前情 在前端开发需求中,经常需要获取元素的尺寸位置相关的属性,以往的做法是调用不同api获取相关属性的. getBoundingClientRect介绍 getBoundingClientRect() ...

  8. 微信小程序表单验证(WxValidate使用)

    参考博客: https://www.cnblogs.com/zhangxiaoyong/p/10166951.html https://github.com/wux-weapp/wx-extend/b ...

  9. MySQL-DB-封装-简易版

    <?php class DB{ private $link; public function __construct($host,$user,$password,$dbname,$port) { ...

  10. Windows原理深入学习系列-Windows内核提权

    这是[信安成长计划]的第 22 篇文章 0x00 目录 0x01 介绍 0x02 替换 Token 0x03 编辑 ACL 0x04 修改 Privileges 0x05 参考文章 继续纠正网上文章中 ...