HarmonyOS 鸿蒙Next中实现地图实时定位,拯救“路痴”
HarmonyOS 鸿蒙Next中实现地图实时定位,拯救“路痴” 实时定位,已经成为应用必备能力之一,尤其是导航应用,更需要快速准确定位用户实时位置。
华为定位服务能够赋予应用程序快速、精准地获取用户位置信息的能力,同时定位服务助力全球开发者实现个性化地图呈现与交互,全面提升应用的LBS体验。
下面为您详细解析,华为定位服务与地图服务如何实现应用实时定位。
预期功能
获取实时定位,并且在地图上显示位置点,首次启动跳转当前位置点,并且位置改变当前位置点和地图视角随之改变。
使用能力
- 华为定位服务 : 基础定位
- 华为地图服务:地图显示
实现原理
使用华为定位服务获取实时位置,在地图上显示“我的位置”按钮,在位置变化时,跳转地图到当前定位。
准备工作
AGC账号注册,项目创建
-
注册成为开发者
-
创建应用,添加sha256,开启map/site开关,下载json文件
-
配置Android Studio工程
- 将“agconnect-services.json”文件拷贝到应用级根目录下
- 在“allprojects > repositories”中配置HMS Core SDK的Maven仓地址。
- 在“buildscript > repositories”中配置HMS Core SDK的Maven仓地址。
- 如果App中添加了“agconnect-services.json”文件则需要在“buildscript > dependencies”中增加agcp配置。
buildscript { repositories { maven { url 'https://developer.huawei.com/repo/' } google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.3.2' classpath 'com.huawei.agconnect:agcp:1.3.1.300' } } allprojects { repositories { maven { url 'https://developer.huawei.com/repo/' } google() jcenter() } }
- 在“dependencies”中添加如下编译依赖
dependencies { implementation 'com.huawei.hms:maps:{version}' implementation 'com.huawei.hms:location:{version}' }
- 在文件头添加配置
apply plugin: 'com.huawei.agconnect'
- 在android中配置签名。将生成签名证书指纹生成的签名文件复制到您工程的app目录下,并在“build.gradle”文件中配置签名
signingConfigs { release { // 签名证书 storeFile file("**.**") // 密钥库口令 storePassword "******" // 别名 keyAlias "******" // 密钥口令 keyPassword "******" v2SigningEnabled true } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' debuggable true } debug { debuggable true } }
- 将“agconnect-services.json”文件拷贝到应用级根目录下
关键代码实现
-
编写一个service获取实时定位。
public class LocationService extends Service { private final String TAG = this.getClass().getSimpleName(); List<ILocationChangedLister> locationChangedList = new ArrayList<>(); // location private FusedLocationProviderClient fusedLocationProviderClient; private LocationRequest mLocationRequest; private final LocationCallback mLocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { super.onLocationResult(locationResult); locationResult.getLocations(); Log.d(TAG, "onLocationResult:" + locationResult); Location location = locationResult.getLocations().get(0); Log.w(TAG, "onLocationResult:Latitude " + location.getLatitude()); Log.w(TAG, "onLocationResult:Longitude " + location.getLongitude()); for (ILocationChangedLister locationChanged : locationChangedList) { locationChanged.locationChanged(new LatLng(location.getLatitude(), location.getLongitude())); } } @Override public void onLocationAvailability(LocationAvailability locationAvailability) { super.onLocationAvailability(locationAvailability); Log.d(TAG, "onLocationAvailability:" + locationAvailability.toString()); } }; private final MyBinder binder = new MyBinder(); private final Random generator = new Random(); @Nullable @Override public IBinder onBind(Intent intent) { return binder; } @Override public void onCreate() { Log.i("DemoLog", "TestService -> onCreate, Thread:" + Thread.currentThread().getName()); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("DemoLog", "TestService -> onStartCommand, startId:" + startId + ", Thread:" + Thread.currentThread().getName()); return START_NOT_STICKY; } @Override public boolean onUnbind(Intent intent) { Log.i("DemoLog", "TestService -> onUnbind, from:" + intent.getStringExtra("from")); return false; } @Override public void onDestroy() { Log.i("DemoLog", "TestService -> onDestroy, Thread:" + Thread.currentThread().getName()); super.onDestroy(); } public int getRandomNumber() { return generator.nextInt(); } public void addLocationChangedlister(ILocationChangedLister iLocationChangedLister) { locationChangedList.add(iLocationChangedLister); } public void getMyLoction() { Log.d(TAG, "getMyLoction:"); fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this); SettingsClient settingsClient = LocationServices.getSettingsClient(this); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); mLocationRequest = new LocationRequest(); builder.addLocationRequest(mLocationRequest); LocationSettingsRequest locationSettingsRequest = builder.build(); // location setting settingsClient.checkLocationSettings(locationSettingsRequest) .addOnSuccessListener(locationSettingsResponse -> fusedLocationProviderClient .requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper()) .addOnSuccessListener(aVoid -> Log.d(TAG, "onSuccess:" + aVoid))) .addOnFailureListener(Throwable::printStackTrace); } public class MyBinder extends Binder { public LocationService getService() { return LocationService.this; } } public interface ILocationChangedLister { /** * Update the location information * * @param latLng The new location information */ public void locationChanged(LatLng latLng); } }
-
在Activity中绘制地图,监听实时位置
Xml中添加地图:
<com.huawei.hms.maps.MapView android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" />
activity地图绘制:
mapView.onCreate(null); mapView.getMapAsync(this);
绘制是打开我的位置 按钮显示
@Override public void onMapReady(HuaweiMap huaweiMap) { hMap = huaweiMap; hMap.setMyLocationEnabled(true); }
设置定位服务绑定监听
private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder binder) { isBound = true; if (binder instanceof LocationService.MyBinder) { LocationService.MyBinder myBinder = (LocationService.MyBinder) binder; locationService = myBinder.getService(); Log.i(TAG, "ActivityA onServiceConnected"); locationService.addLocationChangedlister(iLocationChangedLister); locationService.getMyLoction(); } } @Override public void onServiceDisconnected(ComponentName name) { isBound = false; locationService = null; Log.i(TAG, "ActivityA onServiceDisconnected"); } };
绑定到LocationService:
private void bindLocationService() { Intent intent = new Intent(mActivity, LocationService.class); intent.putExtra("from", "ActivityA"); Log.i(TAG, "-------------------------------------------------------------"); Log.i(TAG, "bindService to ActivityA"); mActivity.bindService(intent, conn, Context.BIND_AUTO_CREATE); }
在位置变化监听中处理位置改变
LocationService.ILocationChangedLister iLocationChangedLister = new LocationService.ILocationChangedLister() { @Override public void locationChanged(LatLng latLng) { Log.d(TAG, "locationChanged:" + latLng.latitude); Log.d(TAG, "locationChanged:" + latLng.longitude); updateLocation(latLng); } };
更新地图经纬度视角
private void updateLocation(LatLng latLng) { mLatLng = latLng; hMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 1)); }
测试
使用模拟位置软件改变模拟位置,地图视角和我的位置按钮可以随之跳动。功能实现。
欲了解HMS Core更多详情,请参阅:
更多关于HarmonyOS 鸿蒙Next中实现地图实时定位,拯救“路痴”的实战教程也可以访问 https://www.itying.com/category-93-b0.html
请问这个源码的具体地址在哪里?文中https://gitee.com/hms-core没有找到。
更多关于HarmonyOS 鸿蒙Next中实现地图实时定位,拯救“路痴”的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中实现地图实时定位,可以通过以下步骤:
-
集成地图SDK:首先,集成华为地图服务(HMS Map Kit),确保在
build.gradle
中添加依赖。 -
获取定位权限:在
config.json
中声明定位权限,并在运行时动态请求用户授权。 -
初始化地图:在Activity或Ability中初始化地图,并设置地图类型和位置显示。
-
实时定位:使用
LocationManager
获取实时位置,并通过Map
对象更新用户位置。 -
处理位置更新:通过
LocationListener
监听位置变化,实时更新地图上的标记。 -
优化用户体验:添加指南针、缩放控件等,帮助用户更好地导航。
通过这些步骤,你可以在鸿蒙Next中实现高效的地图实时定位功能,帮助用户轻松找到目的地。