實現地圖實時定位,拯救“路痴”

華為開發者論壇發表於2021-08-13

實時定位,已經成為應用必備能力之一,尤其是導航應用,更需要快速準確定位使用者實時位置。

 

華為定位服務能夠賦予應用程式快速、精準地獲取使用者位置資訊的能力,同時定位服務助力全球開發者實現個性化地圖呈現與互動,全面提升應用的 LBS體驗。

 

下面為您詳細解析,華為定位服務與地圖服務如何實現應用實時定位。

 

預期功能  

獲取實時定位,並且在地圖上顯示位置點,首次啟動跳轉當前位置點,並且位置改變當前位置點和地圖視角隨之改變。


 

使用能力

華為定位服務 基礎定位

華為地圖服務:地圖顯示

 

實現原理

使用華為定位服務獲取實時位置,在地圖上顯示“我的位置”按鈕,在位置變化時,跳轉地圖到當前定位。

 

準備工作

AGC賬號註冊,專案建立

1.     註冊成為開發者

註冊地址:

https://developer.huawei.com/consumer/cn/service/josp/agc/index.html ?ha__source=hms1

2.   建立應用,新增sha256,開啟map/site開關,下載json檔案


https://developer.huawei.com/consumer/cn/doc/development/AppGallery-connect-Guides/agc-get-started?ha__source=hms1


3.     配置 android studio工程

1)     將“ agconnect-services.json”檔案複製到應用級根目錄下

·       allprojects > repositories中配置 HMS Core SDKMaven倉地址。

·       buildscript > repositories中配置 HMS Core SDKMaven倉地址。

·       如果 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/consumer/cn/forum/topic/0203580993493730287?fid=18

原作者: HMS Core官方帳號

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69970551/viewspace-2786749/,如需轉載,請註明出處,否則將追究法律責任。

相關文章