實時定位,已經成為應用必備能力之一,尤其是導航應用,更需要快速准確定位用戶實時位置。
華為定位服務能夠賦予應用程序快速、精准地獲取用戶位置信息的能力,同時定位服務助力全球開發者實現個性化地圖呈現與交互,全面提升應用的LBS體驗。
下面為您詳細解析,華為定位服務與地圖服務如何實現應用實時定位。
預期功能
獲取實時定位,並且在地圖上顯示位置點,首次啟動跳轉當前位置點,並且位置改變當前位置點和地圖視角隨之改變。
使用能力
華為定位服務: 基礎定位
華為地圖服務:地圖顯示
實現原理
使用華為定位服務獲取實時位置,在地圖上顯示“我的位置”按鈕,在位置變化時,跳轉地圖到當前定位。
准備工作
AGC賬號注冊,項目創建
1. 注冊成為開發者
注冊地址:
https://developer.huawei.com/consumer/cn/service/josp/agc/index.html?ha__source=hms1
2. 創建應用,添加sha256,開啟map/site開關,下載json文件
3. 配置android studio工程
1) 將“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() } }
2) 在“dependencies ”中添加如下編譯依賴
dependencies { implementation 'com.huawei.hms:maps:{version}' implementation 'com.huawei.hms:location:{version}' }
3) 在文件頭添加配置
apply plugin: 'com.huawei.agconnect'
4) 在android中配置簽名。將生成簽名證書指紋生成的簽名文件復制到您工程的app目錄下,並在“build.gradle”文件中配置簽名
signingConfigs { release { // 簽名證書 storeFile file("**.**") // 密鑰庫口令 storePassword "******" // 別名 keyAlias "******" // 密鑰口令 keyPassword "******" v2SigningEnabled true v2SigningEnabled true } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' debuggable true } debug { debuggable true } }
關鍵代碼實現
1) 編寫一個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); } }
2) 在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更多詳情,請參閱:
>>華為開發者聯盟官網
>>獲取開發指導文檔
>>參與開發者討論請到CSDN社區或者Reddit社區
>>下載demo和示例代碼請到Github或者Gitee
>>解決集成問題請到Stack Overflow
原文鏈接:https://developer.huawei.com/...
原作者:HMS Core官方帳號