5
respostas

Crashe triplo ao pedir permissão de Mapa ao entrar na tela de Mapa

Olá, estou tentando inserir a permissão de Mapa ao Abrir a tela de Mapa, porém sempre que ele sobe a tela ele dá 3 crashes, ai fecha a aplicação aparece 3 janelas de permissão e depois que eu permito e abro a aplicação novamente ele abre o mapa e não crasha mais.

Segue as 3 classes e o crash.

package com.example.jaymecaironi.agenda;

import android.*;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.google.android.gms.maps.SupportMapFragment;

public class MapaActivity extends AppCompatActivity {

    private static final int REQUEST_PERMISSOES = 1;
    private MapaFragment mapaFragment;

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mapa);

        mapaFragment = new MapaFragment();

        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction tx = manager.beginTransaction();

        mapaFragment = new MapaFragment();

        tx.replace(R.id.frame_mapa, mapaFragment);
        tx.commit();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ActivityCompat.checkSelfPermission(MapaActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(MapaActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 123);

                String[] permissoes = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
                requestPermissions(permissoes, REQUEST_PERMISSOES);
            }
        }
    }

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == REQUEST_PERMISSOES) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                new Localizador(this, mapaFragment);
            }
        }
    }
}
package com.example.jaymecaironi.agenda;

import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;

import com.example.jaymecaironi.agenda.dao.AlunoDAO;
import com.example.jaymecaironi.agenda.modelo.Aluno;
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.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import java.io.IOException;
import java.util.List;

/**
 * Created by TI02 on 04/01/2017.
 */

public class MapaFragment extends SupportMapFragment implements OnMapReadyCallback {

    private GoogleMap mapa;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        this.mapa = googleMap;

        LatLng posicaoDaEscola = pegaCoordenadaDoEndereco("Rua Paraná 1621, Centro, Siqueira Campos, Paraná");
        if (posicaoDaEscola != null){

            centralizaEm(posicaoDaEscola);

            //CameraUpdate update = CameraUpdateFactory.newLatLngZoom(posicaoDaEscola, 17);
            //googleMap.moveCamera(update);
        }

        AlunoDAO alunoDAO = new AlunoDAO(getContext());
        for (Aluno aluno : alunoDAO.buscaAlunos()){
            LatLng coordenada = pegaCoordenadaDoEndereco(aluno.getEndereco());
            if (coordenada != null) {
                MarkerOptions marcador = new MarkerOptions();
                marcador.position(coordenada);
                marcador.title(aluno.getNome());
                marcador.snippet(String.valueOf(aluno.getNota()));
                mapa.addMarker(marcador);
            }
        }
        alunoDAO.close();

        new Localizador(getContext(), MapaFragment.this);

    }

    private LatLng pegaCoordenadaDoEndereco (String endereco){
        try{
            Geocoder geocoder = new Geocoder(getContext());
            List<Address> resultados = geocoder.getFromLocationName(endereco, 1);
            if (!resultados.isEmpty()){
                LatLng posicao = new LatLng(resultados.get(0).getLatitude(), resultados.get(0).getLongitude());
                return posicao;
            }

        } catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    public void centralizaEm(LatLng coordenada){
        if(mapa != null){
            CameraUpdate update = CameraUpdateFactory.newLatLngZoom(coordenada, 17);
            mapa.moveCamera(update);
        }
    }

}
package com.example.jaymecaironi.agenda;

import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.Nullable;

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
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.model.LatLng;

/**
 * Created by TI02 on 05/01/2017.
 */

public class Localizador implements GoogleApiClient.ConnectionCallbacks, LocationListener {

    private final GoogleApiClient client;
    private final MapaFragment mapaFragment;

    public Localizador(Context context, MapaFragment mapaFragment) {
        client = new GoogleApiClient.Builder(context).addApi(LocationServices.API).addConnectionCallbacks(this).build();

        client.connect();

        this.mapaFragment = mapaFragment;
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {

        LocationRequest request = new LocationRequest();
        request.setSmallestDisplacement(50);
        request.setInterval(1000);
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        LocationServices.FusedLocationApi.requestLocationUpdates(client, request, this);
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onLocationChanged(Location location) {
        LatLng coordenada = new LatLng(location.getLatitude(), location.getLongitude());
        mapaFragment.centralizaEm(coordenada);
    }
}

E o Erro:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.jaymecaironi.agenda, PID: 19921
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.jaymecaironi.agenda/com.example.jaymecaironi.agenda.MapaActivity}: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2426)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
                      at android.app.ActivityThread.access$900(ActivityThread.java:154)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:148)
                      at android.app.ActivityThread.main(ActivityThread.java:5443)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
                   Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
                      at com.example.jaymecaironi.agenda.MapaActivity.onRequestPermissionsResult(MapaActivity.java:51)
                      at android.app.Activity.requestPermissions(Activity.java:3827)
                      at com.example.jaymecaironi.agenda.MapaActivity.onCreate(MapaActivity.java:44)
                      at android.app.Activity.performCreate(Activity.java:6259)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490) 
                      at android.app.ActivityThread.access$900(ActivityThread.java:154) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:148) 
                      at android.app.ActivityThread.main(ActivityThread.java:5443) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
5 respostas

Oi Jayme, tudo bem ?

Tem alguns pontos de melhoria que podemos fazer, mas inicialmente o que tá rolando é o seguinte, no retorno das respostas de permissão você está pegando uma posição que não existe no array, o que está gerando a Exception.

O que eu recomendo você a fazer é, invés de manipular na mão o tamanho do array, deixar mais dinâmico, com um for por exemplo :


for(int i = 0; i < grantResults.length; i++){
    int resultado = grantResults[i];
    String permissao = permissions[i];

    System.out.println(permissao+ " está garantida : " + resultado == PackageManager.PERMISSION_GRANTED );

    // pode fazer sua regra de negócio 
}

Um ponto que não está no tópico e é um pouco perigoso é o uso da Annotation @RequiresApi(api = Build.VERSION_CODES.M). Imagino que você esteja utilizando um celular/emulador que esteja na versão 6.0, por isso que está funcionando. Em versões diferentes você terá problemas pois essa anotação fará que o seu método seja apenas processado nessa versão.

Espero ter ajudado.

Abraços

Na verdade eu tentei realizar a permissão de uma maneira mais simples, estilo da Ligação, porém tive um Exception também, então tentei utilizar o informado pelo instrutor realizando devidas adaptações, mas sem sucesso também

Desse jeito que te mostrei você conseguiu fazer funcionar sem levar Exception ?

Sim, talvez posso ter colocado o código informado no local errado.

Alguma ajuda?