HMS Core定位服務在生活服務類App中可以自動填寫收貨地址啦

HMSCore發表於2022-03-31

在涉及團購、外賣、快遞、家政、物流、搬家等生活服務類的App、小程式中,填寫收貨地址是使用者高頻使用的功能。這一功能通常採取讓使用者手動填寫的解決方案,例如上下拉動選擇浙江省-->杭州市-->西湖區-->西溪街道,再切換到姓名輸入框輸入姓名-->電話輸入框輸入電話等一系列的操作。從中我們不難發現手動輸入地址不僅費時費力,而且一不小心還會出現選錯地址的現象。

那有沒有什麼方法能幫助使用者又快又準確的填寫地址呢?藉助HMS Core 定位服務的融合定位+地理編碼能力,生活服務類App可以自動定位獲取使用者當前位置資訊或某地的行政區劃資訊、街道資訊,並準確填寫至位址列中。使用者無需自己手動輸入,減少了操作時間,並且不用再擔心填錯地址。以下是我們提供的示例程式碼,開發者們按照步驟嘗試,就可以輕鬆體驗這個功能啦~

效果展示

開發實戰

開發步驟

一、 開發準備

1. 登入AppGallery Connect網站,點選“我的專案”。找到您的專案在API管理開啟location開關,在專案中點選需要配置簽名證書指紋的應用。在“專案設定 > 常規”頁面的“應用”區域,點選“SHA256證書指紋”後的“新增證書指紋”,輸入生成的SHA256指紋。

2. 在“專案設定 > 常規”頁面的“應用”區域,點選“agconnect-services.json”下載配置檔案。將“agconnect-services.json”檔案拷貝到應用級根目錄下。

3. 專案級“build.gradle”檔案

buildscript {
    repositories {
        google()
        jcenter()
        maven { url 'https://developer.huawei.com/repo/' }
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.1.2'
        classpath 'com.huawei.agconnect:agcp:1.6.0.300'
    }
}

allprojects {
    repositories {
        maven { url 'https://developer.huawei.com/repo/' }
        google()
        jcenter()
        mavenCentral()
    }
}

應用級的“build.gradle”檔案

plugins {
    id 'com.android.application'
    id 'com.huawei.agconnect'
}

在“dependencies ”中新增如下編譯依賴

implementation 'com.huawei.hms:location:6.3.0.300'

二、 許可權檢查

1. 在“AndroidManifest.xml”檔案中配置許可權ACCESS_COARSE_LOCATION(粗略的位置許可權),ACCESS_FINE_LOCATION(精確的位置許可權)和ACCESS_BACKGROUND_LOCATION許可權

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

2. 動態申請定位相關許可權(Android 6.0及以上版本危險許可權要求)

    Log.i(TAG, "android sdk < 28 Q");
    if (ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        String[] strings =
                {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
        ActivityCompat.requestPermissions(this, strings, 1);
    }
} else {
    if (ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this,
            "android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
        String[] strings = {Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                "android.permission.ACCESS_BACKGROUND_LOCATION"};
        ActivityCompat.requestPermissions(this, strings, 2);
    }
}

三、 獲取定位結果

1. 設定定位引數,包括位置更新的間隔,定位型別等

mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
mSettingsClient = LocationServices.getSettingsClient(this);
mLocationRequest = new LocationRequest();
// Sets the interval for location update (unit: Millisecond)
mLocationRequest.setInterval(5000);
// Sets the priority
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

2. 呼叫getSettingsClient()介面獲取SettingsClient例項。呼叫呼叫checkLocationSettings()檢查裝置開關設定

LocationSettingsRequest locationSettingsRequest = builder.build();
// Before requesting location update, invoke checkLocationSettings to check device settings.
Task<LocationSettingsResponse> locationSettingsResponseTask =
        mSettingsClient.checkLocationSettings(locationSettingsRequest);

檢查開關開啟之後 ,呼叫requestLocationUpdates()進行定位

locationSettingsResponseTask.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
    @Override
    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
        Log.i(TAG, "check location settings success");
        mFusedLocationProviderClient
                .requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        Log.i(TAG, "requestLocationUpdatesWithCallback onSuccess");
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(Exception e) {
                        Log.e(TAG, "requestLocationUpdatesWithCallback onFailure:" + e.getMessage());
                    }
                });
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(Exception e) {
        Log.e(TAG, "checkLocationSetting onFailure:" + e.getMessage());
        int statusCode = 0;
        if (e instanceof ApiException) {
            statusCode = ((ApiException) e).getStatusCode();
        }
        switch (statusCode) {
            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                try {
                    // When the startResolutionForResult is invoked, a dialog box is displayed, asking you
                    // to open the corresponding permission.
                    if (e instanceof ResolvableApiException) {
                        ResolvableApiException rae = (ResolvableApiException) e;
                        rae.startResolutionForResult(MainActivity.this, 0);
                    }
                } catch (IntentSender.SendIntentException sie) {
                    Log.e(TAG, "PendingIntent unable to execute request.");
                }
                break;
            default:
                break;
        }
    }
});

四、 逆地理編碼獲取當前位置

成功獲取定位資訊的經緯度之後,將經緯度資訊傳遞給使用地理編碼服務(GeocoderService)獲得地理編碼請求物件,然後呼叫請求逆地理編碼方法(getFromLocation),設定請求(GetFromLocationRequest)引數,獲取逆地理編碼資訊回撥。

if (null == mLocationCallback) {
    mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            if (locationResult != null) {
                List<Location> locations = locationResult.getLocations();
                if (!locations.isEmpty()) {
                    ExecutorUtil.getInstance().execute(new Runnable() {
                        @Override
                        public void run() {
                            Locale locale = new Locale("zh", "CN");
                            GeocoderService geocoderService = LocationServices.getGeocoderService(MainActivity.this, locale);
                            GetFromLocationRequest getFromLocationRequest = new GetFromLocationRequest(locations.get(0).getLatitude(), locations.get(0).getLongitude(), 1);
                            geocoderService.getFromLocation(getFromLocationRequest)
                                    .addOnSuccessListener(new OnSuccessListener<List<HWLocation>>() {
                                        @Override
                                        public void onSuccess(List<HWLocation> hwLocation) {
                                            printGeocoderResult(hwLocation);
                                        }
                                    })
                                    .addOnFailureListener(new OnFailureListener() {
                                        @Override
                                        public void onFailure(Exception e) {
                                            Log.i(TAG, e.getMessage());
                                        }
                                    });
                        }
                    });
                }
            }
        }
        @Override
        public void onLocationAvailability(LocationAvailability locationAvailability) {
            if (locationAvailability != null) {
                boolean flag = locationAvailability.isLocationAvailable();
                Log.i(TAG, "onLocationAvailability isLocationAvailable:" + flag);
            }
        }
    };
}

最後將獲取到的結果顯示在介面上即可。

瞭解更多詳情>>

訪問華為開發者聯盟官網
獲取開發指導文件
華為移動服務開源倉庫地址:GitHubGitee

關注我們,第一時間瞭解 HMS Core 最新技術資訊~

相關文章