首页 > 解决方案 > Android Google Map SDK - 仅在应用程序通过 adb 启动时工作

问题描述

我正在编写一个应用程序,我必须在其中显示谷歌地图标准片段并在其上绘制移动设备的更新位置(此应用程序中的GCS)。该应用程序似乎只有在远程设备上通过Android Studio启动时才能正常工作。如果我尝试直接从设备本身启动它,地图永远不会准备好:它会显示但细节非常少。

package myapp.activities;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentActivity;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.material.snackbar.Snackbar;

import java.util.ArrayList;
import java.util.List;

import myapp.R;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, ActivityCompat.OnRequestPermissionsResultCallback, LocationListener {
    private static final int PERMISSION_REQUEST_LOCATION = 11;
    private static final int LOCATION_UPDATE_DELAY = 1000;

    private final String gps_provider = LocationManager.GPS_PROVIDER;

    private GoogleMap map;
    private Location location;
    private LocationManager location_manager;
    private View layout;
    private BitmapDescriptor base_icon;
    private MarkerOptions base_marker_options;
    private Marker base_marker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);

        if (mapFragment != null)
            mapFragment.getMapAsync(this);

        //USER CODE

        layout = findViewById(R.id.map);
        assert layout != null;
   
        location = new Location(getString(R.string.location_provider));
        location.isFromMockProvider();

        base_icon = BitmapDescriptorFactory.fromResource(R.drawable.base);

        base_marker_options = new MarkerOptions().title(getString(R.string.destination_base_label)).icon(base_icon);

        initLocalization();
        //
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_LOCATION) {
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Snackbar.make(layout, R.string.fine_location_access_granted, Snackbar.LENGTH_SHORT).show();
                startLocalization();
            } else {
                Snackbar.make(layout, R.string.denied_fine_location_access_rationale, Snackbar.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        map = googleMap;

        map.getUiSettings().setZoomControlsEnabled(true);
        map.getUiSettings().setCompassEnabled(true);
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        stopTelemetry();
    }

    @Override
    public void onLocationChanged(Location location) {
        this.location.set(location);

        if (map != null) {
            updateGCS(location);
        }
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {
    }

    @Override
    public void onProviderEnabled(String s) {
    }

    @Override
    public void onProviderDisabled(String s) {
    }
    
private void updateGCS(final Location location) {
    if(map==null)
        return;

    final LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());

    if (base_marker == null) {
        base_marker_options.position(latLng);
        base_marker = map.addMarker(base_marker_options);
    } else
        base_marker.setPosition(latLng);

    final float _zoom = map.getCameraPosition().zoom;

    final CameraPosition _cp = new CameraPosition.Builder().target(latLng).zoom(_zoom).build();
    final CameraUpdate _cu = CameraUpdateFactory.newCameraPosition(_cp);

    map.animateCamera(_cu);
}
    
    private void requestLocationPermission() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {
            Snackbar.make(layout, R.string.denied_fine_location_access_rationale,
                    Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok, new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    ActivityCompat.requestPermissions(MapsActivity.this,
                            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                            PERMISSION_REQUEST_LOCATION);
                }
            }).show();

        } else {
            Snackbar.make(layout, R.string.denied_fine_location_access_warning, Snackbar.LENGTH_SHORT).show();
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_LOCATION);
        }
    }

    private void initLocalization() {
        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            Snackbar.make(layout,
                    R.string.fine_location_access_granted,
                    Snackbar.LENGTH_SHORT).show();
            startLocalization();
        } else {
            requestLocationPermission();
        }
    }

    @SuppressLint("MissingPermission")
    private void startLocalization() {
        try {
            location_manager = (LocationManager) getSystemService(LOCATION_SERVICE);

            if (!location_manager.isProviderEnabled(gps_provider)) {
                Intent gpsOptionsIntent = new Intent(
                        android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(gpsOptionsIntent);
            } else {
                location_manager.requestLocationUpdates(gps_provider, LOCATION_UPDATE_DELAY, 2, this);
            }
        } catch (Throwable e) {
            Log.e(getClass().getName(), "Exception: " + e.getMessage());
        }
    }   
}

标签: javaandroidgoogle-maps

解决方案


这就是释放密钥的问题。您已经使用调试密钥设置了配置,但您还需要发布密钥配置。有几个步骤。您需要 Api 密钥,如果没有,请检查链接https://developers.google.com/maps/documentation/android-sdk/get-api-key 如果您仅将其用于 Android 而不是限制Android SDK 的密钥 对于调试和发布密钥,请检查链接https://developer.android.com/studio/publish/app-signing#debug-mode 注意:您必须提供调试、发布和 Google Play 控制台 SHA- 1 指纹证书。如果您需要帮助,请查看此答案如何在 Android Studio 中获取 SHA-1 指纹证书以进行调试模式? 配置它并享受。


推荐阅读