I'm writing an app where I have to show a Google Map standard fragment and draw on it the updated position of the mobile device (GCS in this app). The app seems to work fine only if launched trough Android Studio on the remote device. If I try to launch it straight from the device itself the map never get ready: it shows up but with very low details.
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());
}
}
}