實現地圖實時定位,拯救“路痴”
實時定位,已經成為應用必備能力之一,尤其是導航應用,更需要快速準確定位使用者實時位置。
華為定位服務能夠賦予應用程式快速、精準地獲取使用者位置資訊的能力,同時定位服務助力全球開發者實現個性化地圖呈現與互動,全面提升應用的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)在檔案頭新增配置
applyplugin:'com.huawei.agconnect'
4)在android中配置簽名。將生成簽名證書指紋生成的簽名檔案複製到您工程的app目錄下,並在“build.gradle”檔案中配置簽名
signingConfigs{ release{ //簽名證書 storeFilefile("**.**") //金鑰庫口令 storePassword"******" //別名 keyAlias"******" //金鑰口令 keyPassword"******" v2SigningEnabledtrue v2SigningEnabledtrue } } buildTypes{ release{ minifyEnabledfalse proguardFilesgetDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro' debuggabletrue } debug{ debuggabletrue } }
關鍵程式碼實現
1) 編寫一個service獲取實時定位。
publicclassLocationServiceextendsService{ privatefinalStringTAG=this.getClass().getSimpleName(); List<ILocationChangedLister>locationChangedList=newArrayList<>(); //location privateFusedLocationProviderClientfusedLocationProviderClient; privateLocationRequestmLocationRequest; privatefinalLocationCallbackmLocationCallback=newLocationCallback(){ @Override publicvoidonLocationResult(LocationResultlocationResult){ super.onLocationResult(locationResult); locationResult.getLocations(); Log.d(TAG,"onLocationResult:"+locationResult); Locationlocation=locationResult.getLocations().get(0); Log.w(TAG,"onLocationResult:Latitude"+location.getLatitude()); Log.w(TAG,"onLocationResult:Longitude"+location.getLongitude()); for(ILocationChangedListerlocationChanged:locationChangedList){ locationChanged.locationChanged(newLatLng(location.getLatitude(),location.getLongitude())); } } @Override publicvoidonLocationAvailability(LocationAvailabilitylocationAvailability){ super.onLocationAvailability(locationAvailability); Log.d(TAG,"onLocationAvailability:"+locationAvailability.toString()); } }; privatefinalMyBinderbinder=newMyBinder(); privatefinalRandomgenerator=newRandom(); @Nullable @Override publicIBinderonBind(Intentintent){ returnbinder; } @Override publicvoidonCreate(){ Log.i("DemoLog","TestService->onCreate,Thread:"+Thread.currentThread().getName()); super.onCreate(); } @Override publicintonStartCommand(Intentintent,intflags,intstartId){ Log.i("DemoLog", "TestService->onStartCommand,startId:"+startId+",Thread:"+Thread.currentThread().getName()); returnSTART_NOT_STICKY; } @Override publicbooleanonUnbind(Intentintent){ Log.i("DemoLog","TestService->onUnbind,from:"+intent.getStringExtra("from")); returnfalse; } @Override publicvoidonDestroy(){ Log.i("DemoLog","TestService->onDestroy,Thread:"+Thread.currentThread().getName()); super.onDestroy(); } publicintgetRandomNumber(){ returngenerator.nextInt(); } publicvoidaddLocationChangedlister(ILocationChangedListeriLocationChangedLister){ locationChangedList.add(iLocationChangedLister); } publicvoidgetMyLoction(){ Log.d(TAG,"getMyLoction:"); fusedLocationProviderClient=LocationServices.getFusedLocationProviderClient(this); SettingsClientsettingsClient=LocationServices.getSettingsClient(this); LocationSettingsRequest.Builderbuilder=newLocationSettingsRequest.Builder(); mLocationRequest=newLocationRequest(); builder.addLocationRequest(mLocationRequest); LocationSettingsRequestlocationSettingsRequest=builder.build(); //locationsetting settingsClient.checkLocationSettings(locationSettingsRequest) .addOnSuccessListener(locationSettingsResponse->fusedLocationProviderClient .requestLocationUpdates(mLocationRequest,mLocationCallback,Looper.getMainLooper()) .addOnSuccessListener(aVoid->Log.d(TAG,"onSuccess:"+aVoid))) .addOnFailureListener(Throwable::printStackTrace); } publicclassMyBinderextendsBinder{ publicLocationServicegetService(){ returnLocationService.this; } } publicinterfaceILocationChangedLister{ /** *Updatethelocationinformation * *@paramlatLngThenewlocationinformation */ publicvoidlocationChanged(LatLnglatLng); } }
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 publicvoidonMapReady(HuaweiMaphuaweiMap){ hMap=huaweiMap; hMap.setMyLocationEnabled(true); }
設定定位服務繫結監聽
privateServiceConnectionconn=newServiceConnection(){ @Override publicvoidonServiceConnected(ComponentNamename,IBinderbinder){ isBound=true; if(binderinstanceofLocationService.MyBinder){ LocationService.MyBindermyBinder=(LocationService.MyBinder)binder; locationService=myBinder.getService(); Log.i(TAG,"ActivityAonServiceConnected"); locationService.addLocationChangedlister(iLocationChangedLister); locationService.getMyLoction(); } } @Override publicvoidonServiceDisconnected(ComponentNamename){ isBound=false; locationService=null; Log.i(TAG,"ActivityAonServiceDisconnected"); } };
繫結到LocationService:
privatevoidbindLocationService(){ Intentintent=newIntent(mActivity,LocationService.class); intent.putExtra("from","ActivityA"); Log.i(TAG,"-------------------------------------------------------------"); Log.i(TAG,"bindServicetoActivityA"); mActivity.bindService(intent,conn,Context.BIND_AUTO_CREATE); }
在位置變化監聽中處理 位置改變
LocationService.ILocationChangedListeriLocationChangedLister=newLocationService.ILocationChangedLister(){ @Override publicvoidlocationChanged(LatLnglatLng){ Log.d(TAG,"locationChanged:"+latLng.latitude); Log.d(TAG,"locationChanged:"+latLng.longitude); updateLocation(latLng); } };
更新地圖 經緯度視角
privatevoidupdateLocation(LatLnglatLng){ mLatLng=latLng; hMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,1)); }
測試
使用模擬位置軟體改變模擬位置,地圖視角和我的位置按鈕可以隨之跳動。功能實現。
欲瞭解HMS Core更多詳情,請參閱:
>>華為開發者聯盟官網
>>獲取開發指導文件
>>參與開發者討論請到CSDN社群或者Reddit社群
>>下載demo和示例程式碼請到Github或者Gitee
>>解決整合問題請到Stack Overflow
原文連結:https://developer.huawei.com/...
原作者:HMS Core官方帳號