Reputation: 3
I'm making an app that shows you a map and you can add custom markers with some info. I'm still working on connecting it into a DB to save everything.
So, every time I run my app and it doesn't have the permissions allowed, it asks for them. Afterwards, it should then center and zoom the map on the current location. However, it doesn't do anything, and if you click the screen it just turns blue. If I close the app and reopen it, it works properly.
I'm not sure if it's because the permission asking is async and the map just fails and stops asking for locations, because when I take a look at the logcat it shows "Successfully inserted 1 locations" from time to time, it just never adds the standard blue dot marker or the myLocation button on the corner, the map just turns blue and shows me nothing.
This my code for the main class:
package com.example.lipel.mapeador003;
import android.Manifest;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Handler;
import android.os.Looper;
import android.os.ResultReceiver;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatCallback;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.view.ActionMode;
import android.util.Log;
import android.view.Menu;
import android.support.v7.widget.Toolbar;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.SettingsClient;
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.UiSettings;
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.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import static com.google.android.gms.location.LocationServices.getFusedLocationProviderClient;
public class Mapa extends FragmentActivity implements OnMapReadyCallback, AppCompatCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, GoogleMap.OnMyLocationButtonClickListener {
public static final String TAG = Mapa.class.getSimpleName(); //Tag de log para verificar no Run
private static final int MY_PERMISSIONS_ACCESS_FINE_LOCATION = 1; //Variável que permite identificar se aplicativo é autorizado a utilizar localização pelo usuário
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 1000; //Variável que faz request de o que fazer com Google Play API caso haja falha
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private AppCompatDelegate delegate; //Para resolver problemas de implementação
private GoogleMap mMap; //Mapa do aplicativo
private FusedLocationProviderClient mFusedLocationClient; //Cliente que puxa a localização atual do celular
private Location mLocalizacaoAtual; //Objeto que salva localização atual para marcador
private Marker mark; //Marcador da localização atual
private LocationRequest locReq; //Objeto que permite puxar localização contínua
private GoogleApiClient googleAPI; //API google para puxar localizações contínuas
private GoogleApiAvailability gAAPI; //Verifica se a API do google está instalada ou funcionando
private LocationCallback loccall;
static final int ADICIONAR_MARCADOR = 1;
private static final long INTERVAL = 10000; //Número que permite definir com facilidade o intervalo de chamada de localização
private static final long FASTEST_INTERVAL = 5000; //Número que permite definir com facilidade o mínimo intervalo de chamada de localização
// Configura os pedidos de localização: seus intervalos e precisão
protected void createLocationRequest() {
locReq = new LocationRequest();
locReq.setInterval(INTERVAL);
locReq.setFastestInterval(FASTEST_INTERVAL);
locReq.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
//Checa o status do Google Play Services
private boolean checkPlayServices() {
gAAPI = GoogleApiAvailability.getInstance();
int resultAAPI = gAAPI.isGooglePlayServicesAvailable(this);
if (resultAAPI != ConnectionResult.SUCCESS) {
//Verifica se é um erro que pode ser resolvido na aplicação ou pelo usuário
if (gAAPI.isUserResolvableError(resultAAPI)) {
gAAPI.getErrorDialog(this, resultAAPI, PLAY_SERVICES_RESOLUTION_REQUEST).show();
}
//retorna falso se não puder ser resolvido
return false;
}
//retorna verdadeiro se não encontra erro, ou seja, se tiver sucesso
return true;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Verifica se o Google Play Services está funcionando. Se não, dá finish na OnCreate e não continua
if (!checkPlayServices()) {
finish();
}
// Coloca o mapa na activity
setContentView(R.layout.activity_mapa);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
// Habilita a API de localização do Google que permite encontrar última localização
mFusedLocationClient = getFusedLocationProviderClient(this);
//Adiciona suporte para barra de ferramentas, permitindo multiplos implement
delegate = AppCompatDelegate.create(this, this);
delegate.onCreate(savedInstanceState);
Toolbar myToolbar = findViewById(R.id.toolbar);
delegate.setSupportActionBar(myToolbar);
//Utilizado para iniciar o aplicativo na tela de ativar localização
/*Intent gpsOptionsIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(gpsOptionsIntent);*/
}
private boolean checkPermissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED)
return true;
else {
requestPermissions();
}
return false;
}
//Pede as permissões
private void requestPermissions() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_ACCESS_FINE_LOCATION);
}
//Verifica as permissões do aplicativo
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_ACCESS_FINE_LOCATION: {
// Coloca as permissões em ordem e checa se elas estão habilitadas.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Se aplicativo não foi permitido depois de perguntar, o fecha
} else {
moveTaskToBack(true);
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
return;
}
}
}
//Inicia o app com a localização atual
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//Pede permissões
if (checkPermissions()) {
mMap.setMyLocationEnabled(true);
}
//Cria um listener para pegar última localização do celular
mFusedLocationClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
//Se encontra a localização (App autorizado e localização ligada), aplica tal localização no mapa
if (location != null) {
LatLng rj1 = new LatLng(location.getLatitude(), location.getLongitude());
//mark = mMap.addMarker(new MarkerOptions().position(rj1).title("Posição Atual"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(rj1));
mMap.setMinZoomPreference(15);
//Salva localização atual em um objeto Location
mLocalizacaoAtual = new Location("");
mLocalizacaoAtual.setLatitude(location.getLatitude());
mLocalizacaoAtual.setLongitude(location.getLongitude());
mMap.animateCamera(CameraUpdateFactory.zoomTo(18));
mMap.getUiSettings().setCompassEnabled(true);
mMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
@Override
public boolean onMyLocationButtonClick() {
mMap.moveCamera(CameraUpdateFactory.newLatLng(getLatLng()));
mMap.animateCamera(CameraUpdateFactory.zoomTo(20));
return true;
}
});
}
}
});
}
//Inicia o serviço de atualização constante de localização
protected void startLocationUpdates() {
Log.v("LocationUpdates","ok");
//Inicia o serviço de localização contínuo e adiciona o que ele utilizará para localizar, depois o construindo
createLocationRequest();
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); //Builder que permite configurar intervalos, etc de pedidos de localização
builder.addLocationRequest(locReq);
LocationSettingsRequest locSetReq = builder.build();
SettingsClient settingsClient = LocationServices.getSettingsClient(this);
settingsClient.checkLocationSettings(locSetReq);
getFusedLocationProviderClient(this).requestLocationUpdates(locReq, loccall = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult != null){
onLocationChanged(locationResult.getLastLocation());
}
}
}, Looper.myLooper());
}
@Override
public void onLocationChanged(Location location){
if (location != null){
if (checkPermissions()){
mLocalizacaoAtual = new Location("");
}
mLocalizacaoAtual.setLatitude(location.getLatitude());
mLocalizacaoAtual.setLongitude(location.getLongitude());
mMap.setMinZoomPreference(15);
}
else
{
mLocalizacaoAtual.setLatitude(0.00);
mLocalizacaoAtual.setLongitude(0.00);
}
//if (mark != null)
// mark.remove();
LatLng Ll = new LatLng(location.getLatitude(), location.getLongitude());
//MarkerOptions mpo = new MarkerOptions();
//mpo.position(Ll);
//mpo.title("Posição Atual");
//mark = mMap.addMarker(mpo);
}
@Override
public void onStart() {
super.onStart();
googleAPI = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
googleAPI.connect();
Log.v("onStart","ok");
}
@Override
public void onStop() {
super.onStop();
googleAPI.disconnect();
}
@Override
public void onConnected(Bundle bundle) {
Task<Location> loc = LocationServices.getFusedLocationProviderClient(this).getLastLocation();
startLocationUpdates();
Log.v("onConnected","ok");
}
private void handleNewLocation(Task<Location> location){
Log.d(TAG, location.toString());
}
private void handleNewLocation (Location location){
Log.d(TAG, location.toString());
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onResume(){
super.onResume();
googleAPI.connect();
}
@Override
public void onPause(){
super.onPause();
googleAPI.disconnect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
// Tenta corrigir o erro
connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "Conexão falhou com código: " + connectionResult.getErrorCode());
}
}
@Override
public void onSupportActionModeStarted(ActionMode actionMode) {
}
@Override
public void onSupportActionModeFinished(ActionMode actionMode) {
}
@Nullable
@Override
public ActionMode onWindowStartingSupportActionMode(ActionMode.Callback callback) {
return null;
}
@Override
public void onPointerCaptureChanged(boolean hasCapture) {
}
//Permite pegar os itens da barra de ferramenta de seu XML
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_items, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.adicionar:
Bundle args = new Bundle();
args.putDouble("long_dataProvider", getLongitude());
args.putDouble("lat_dataProvider", getLatitude());
Intent adInt = new Intent(this, Adicionar.class);
adInt.putExtras(args);
startActivityForResult(adInt, ADICIONAR_MARCADOR);
return true;
case R.id.lista:
Intent listInt = new Intent(this, Lista.class);
startActivity(listInt);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
protected LatLng getLatLng(){
return new LatLng(mLocalizacaoAtual.getLatitude(),mLocalizacaoAtual.getLongitude());
}
protected double getLatitude(){
return mLocalizacaoAtual.getLatitude();
}
protected double getLongitude(){
return mLocalizacaoAtual.getLongitude();
}
protected GoogleMap getMap(){return mMap;}
protected Location getCurrLoc(){return mLocalizacaoAtual;}
@Override
protected void onActivityResult(int reqCode, int resCode, Intent resultIntent){
if (reqCode == ADICIONAR_MARCADOR) {
if (resCode == RESULT_OK){
String markNom = resultIntent.getStringExtra("nome");
String markDescr = resultIntent.getStringExtra("descr");
Double markLat = resultIntent.getDoubleExtra("lat", getLatitude());
Double markLong = resultIntent.getDoubleExtra("long", getLongitude());
//Call function to add marker into DB and then from the DB to the map
//For now, testing directly here
mMap.addMarker(new MarkerOptions()
.position(new LatLng(markLat,markLong))
.title(markNom)
.snippet(markDescr)
);
//Do stuff with intent. Get the title, lat, long, nome, descrição
}
}
}
@Override
public boolean onMyLocationButtonClick(){
mMap.animateCamera(CameraUpdateFactory.zoomTo(20));
return true;
}
//protected void zoomCamera (View view){
// mMap.moveCamera(CameraUpdateFactory.newLatLng(getLatLng()));
// mMap.animateCamera(CameraUpdateFactory.zoomTo(20));
// mMap.getCameraPosition();
// CameraPosition.Builder camPos = new CameraPosition.Builder().target(getLatLng()).bearing(0);
//}
}
this is my xml for the main:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Mapa">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@+id/map"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:title="@string/app_name" />
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
tools:context=".Mapa" />
</android.support.constraint.ConstraintLayout>
This is how the map shows in the first run after asking for permissions:
The weirdest thing is that it used to work before. Then I added something, it broke. I removed this thing that I added using the history tool from Android Studio and it still was broken.
Upvotes: 0
Views: 61
Reputation: 4705
Hi try by changing the bellow code or method, also one more thing the blue screen is not the problem with the map but its showing in the default location (means any where in the ocean):
//Verifica as permissões do aplicativo
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_ACCESS_FINE_LOCATION: {
// Coloca as permissões em ordem e checa se elas estão habilitadas.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (mMap!=null && checkPermissions()) {
mMap.setMyLocationEnabled(true);
}
//Se aplicativo não foi permitido depois de perguntar, o fecha
} else {
moveTaskToBack(true);
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
return;
}
}
}
Upvotes: 1