簡體   English   中英

谷歌地圖海拔API android工作室

[英]Google Maps Elevation API android studio

我正在創建一個 android 應用程序來使用 Google 地圖 SDK 和 Google Play 服務位置 API 記錄用戶的活動。 我正在嘗試根據給定的緯度和經度檢索用戶的海拔高度。 我最初使用 Location#getAltitude() 但后來意識到這並沒有給出海拔高度。

我使用以下查詢字符串繼續使用開放式高程 API:

String url = "https://api.open-elevation.com/api/v1/lookup?locations=" + latLng.latitude + "," + latLng.longitude;

但是,API 在生成響應方面似乎太慢了。 然后我找到了 Google Maps Elevation API,我們也可以使用 URL 提出請求。 但是,我們需要傳遞一個 API 密鑰,我不想在 URL 字符串中傳遞這個 API 密鑰並最終將其提交到遠程存儲庫。

In this repo ( https://github.com/googlemaps/google-maps-services-java ) I found the class: /src/main/java/com/google/maps/ElevationApi.java which I thought I could use to避免弄亂 http 請求。

在我的 gradle 中,我包含了這個依賴項:

implementation 'com.google.maps:google-maps-services:0.18.0'

目前,檢索高程的代碼如下:

ElevationApi.getByPoint(new GeoApiContext.Builder().apiKey(API_KEY).build(), latLng)
            .setCallback(new PendingResult.Callback<ElevationResult>() {
                @Override
                public void onResult(ElevationResult result) {
                    consumer.doAction(result.elevation);
                }

                @Override
                public void onFailure(Throwable e) {
                    e.printStackTrace();
                }
            });

既然我不想將它提交到存儲庫,我應該在這里為 API_KEY 傳遞什么? 我在 local.properties 中為地圖定義了一個 api 鍵,但是,如下所示:

MAPS_API_KEY=<API_KEY_HERE>

基本上,我的問題是,我可以在未提交給 GitHub 的屬性文件中定義一個 API 鍵,然后在代碼中引用它嗎?

謝謝你的幫助。

更新:我已經設法使用 gradle 從 local.properties 讀取 API 密鑰,但從 ElevationApi 得到一個異常,說 API 21+ 預期,但是是 3。 所以我回到開放高度 API 並提出以下 Volley 請求:

/**
 * Calculates elevation gain for the provided recording service
 * @param recordingService the recording service to calculate elevation gain for
 * @param response the handler to consume the elevation gain with
 */
public static void calculateElevationGain(RecordingService recordingService, ActionHandlerConsumer<Double> response) {
    ArrayList<Location> locations = recordingService.getLocations();
    JSONArray array = constructLocations(locations);

    try {
        if (array != null) {
            RequestQueue requestQueue = Volley.newRequestQueue(recordingService);
            String url = "https://api.open-elevation.com/api/v1/lookup";
            JSONObject requestHeader = new JSONObject(); // TODO this seems very slow
            requestHeader.put("locations", array);
            JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, requestHeader,
                    response1 -> handleSuccessfulResponse(response1, response), RecordingUtils::handleErrorResponse);
            request.setRetryPolicy(new DefaultRetryPolicy(500000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
            requestQueue.add(request);
        }
    } catch (JSONException ex) {
        ex.printStackTrace();
    }
}

我不得不將超時設置為一個很大的數字,不確定它應該有多高,因為由於響應時間慢,我收到了 Volley 超時錯誤。

還有其他方法可以檢索有關海平面的高度嗎?

是的,open-elevation.com 存在超時和延遲的間歇性問題。

在這個 GIS 堆棧交換問題Seeking Alternative to Google Maps Elevation API中列出了一些替代方案。 我是Open Topo Data的開發人員,這是那里投票最多的答案。 您可以使用 docker 托管您自己的服務器,我還有一個免費的公共 API,它具有相當好的延遲和正常運行時間。

還有GPXZ作為具有更高質量數據的 Google Elevation API 的替代品,但它需要 API 密鑰,因此與 Google 地圖存在相同的問題。

我建議一個不同的方向:繼續使用 Google 和 API 密鑰,但采用有關機密和源存儲庫的最佳實踐。 由於您處理的是 Android 應用程序而不是 web 應用程序,因此您的密鑰在您的應用程序二進制文件中可能有些安全(與 web 部署的應用程序中的密鑰相比)。

投注做法:

  1. 不要提交 API 密鑰。 實現這一點的最佳方法是從源代碼管理存儲庫中排除包含密鑰的文件。 這可以簡單地用.gitignore來完成。 例如,這個 Codelab 有一個帶有 secret 的文件,但它有一個虛擬值,通常應該從源中排除這個文件。 它只是在那里,因為那是一個教育代碼實驗室。
  2. 作為一項安全措施,請利用GitGuardian掃描您的存儲庫,以防您意外按下 API 密鑰。 在這種情況下,您會收到通知。 至於我,我分叉了 Geospatial API 代碼實驗室,看到密鑰文件在 gitignore 中,我不小心按下了一個鍵。
  3. 如果您在提交時不小心按下了某個鍵,僅撤銷提交並刪除文件是不夠的。 清道夫機器人仍會在您的 git 歷史記錄中找到信息。 而是立即禁用密鑰並生成另一個密鑰。
  4. 如果您正在處理 web 應用程序,您可以將 API 密鑰使用限制在您的 web 應用程序的域中。 同樣,您也可以將密鑰限制為特定的 Android 應用程序簽名(不要忘記添加您的開發人員環境的簽名)。 這保證了即使有人竊取了密鑰,他們也可能無法使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM