實時定位,已經成為應用必備能力之一,尤其是導航應用,更需要快速准確定位用戶實時位置。
華為定位服務能夠賦予應用程序快速、精准地獲取用戶位置信息的能力,同時定位服務助力全球開發者實現個性化地圖呈現與交互,全面提升應用的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官方帳號
