Luiz Felipe
Luiz Felipe

Reputation: 3

App's map stays blank in first run after asking for permissions, but works properly after closed and reopened

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:

Blue Map

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

Answers (1)

Dhaval Solanki
Dhaval Solanki

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

Related Questions