Solucionado (ver solução)
Solucionado
(ver solução)
13
respostas

Não consigo abrir mapa dentro do onRequestPermissionsResult()

Por mais que eu implemente o método onRequestPermissionsResult() com as condições para as permissões, eu não consigo abrir o mapa logo após clicar em permitir, ou seja, tenho que clicar no mapa, clicar em permitir e depois em mapa de novo, para aí sim abrir o mapa.

O que estou fazendo de errado?

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case REQUEST_PERMISSOES:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){
                    chamaMapa();
                }
                break;
        }
    }

Segue também classe MapaActivity completa:

public class MapaActivity extends AppCompatActivity {

    private static final int REQUEST_PERMISSOES = 1;
    private FragmentManager manager;
    private FragmentTransaction tx;

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

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

private void chamaMapa() {
        manager = getSupportFragmentManager();
        tx = manager.beginTransaction();
        tx.replace(R.id.frame_mapa, new MapaFragment());
        tx.commit();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case REQUEST_PERMISSOES:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){
                    chamaMapa();
                }
                break;
        }
    }
}
13 respostas

Gilmar, tudo bem ?

Cara não entendi seu problema, vi seu código e mentalmente acho que a lógica está corretamente, consegue me dar um pouco mais de contexto

Com o código desta maneira está acontecendo o seguinte:

Clico no ícone do mapa, aí me pede a permissão, quando clico em permitir, nada acontece, aí tenho que clicar no ícone mapa novamente, para aí sim abrir o mapa.

Como eu queria que acontecesse:

Clico no ícone do mapa, aí me pede a permissão, quando clico em permitir, aí já abre o mapa. Sem que eu tenha que clicar no ícone mapa novamente.

De acordo com a atividade, assim que chamasse o método ActivityCompat.checkSelfPermission() e identificasse que não possuí as permissões iria chamar o método ActivityCompat.requestPermissions(), como fiz no código acima, aí assim que eu clicasse em "permitir", teria que chamar método onRequestPermissionsResult() e executar o que está la dentro, mas isso não está acontecendo, porque se estivesse chamando o método onRequestPermissionsResult() iria abrir o mapa assim que eu clicasse em "permitir".

Fiz mais alguns testes, e acho que possível causa de não chamar o mapa assim que eu clico em permitir seria a chamada do método finish(). No minha análise estaria acontecendo o seguinte:

Executa o método ActivityCompat.requestPermissions(), quando clico em "permitir" ele chama o método onRequestPermissionsResult() e quando termina, volta para dentro do if e chama o método finish() que mata a chamada ao mapa. Quando clico no ícone mapa novamente, uma vez que já tem a permissão, ele executa o método chamaMapa() fora do if (sem o finish()), aí sim consegue abrir o mapa.

O teste que fiz foi colocar o método finish() depois da chamada do método chamaMapa() fora do if, da seguinte forma:

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

Aí rodei a aplicação novamente, dei a permissão manualmente e cliquei no ícone mapa, nesse caso não entrou dentro do if (uma vez que já tinha a permissão), executando a chamada de método chamaMapa() e depois o método finish(). Se o problema não fosse o finish() teria que abrir o mapa, mas isso não aconteceu, quando cliquei no ícone mapa, mesmo com as permissões, não aconteceu nada.

Se o problema for mesmo o finish() eu não sei qual seria a solução, porque se eu tirar ele a aplicação vai abrir o pop-up requisitando a permissão e antes que eu clique em "permitir" a aplicação também vai tentar abrir o mapa, causando uma exception. Isto era o que estava acontecendo antes de eu usar o finish() (solução sugerida pelo instrutor Jeferson Silva na resposta de outra dúvida do forum).

Teria algum modo de contornar esse problema?

Gilmar,

O finish estava matando a activity logo após você fazer a chamada das permissões.

É interessante você não o chamar, apenas quando você quer matar de fato aquela activity.

Então Matheus, como complementei com a resposta acima, o problema é exatamente esse, se eu não chamar o finish() vou tomar uma exception.

A aplicação vai abrir o pop-up requisitando a permissão e antes que eu clique em "permitir" a aplicação também vai tentar abrir o mapa, causando a exception.

Me sugere algum modo de contornar essa exception, que não seja com o método finish()?

Gilmar, você tem que fazer o tratamento na volta :

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case REQUEST_PERMISSOES:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){
                    chamaMapa();
                } else {
                      finish();
            }
                break;
        }
    }

Matheus, coloquei o código assim como você indicou, mas resulta na mesma exception que eu recebia quando não usava o finish().

Quando clico no ícone do mapa, a aplicação chama o pop-up de permissão e antes que eu dê a permissão ele já tenta chamar o mapa e resulta na exception abaixo:

java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations.

Faz esse else :


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

Fiz como você indicou acima e retornou a seguinte uma exception diferente, segue abaixo:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=1, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {br.com.alura.agenda/br.com.alura.agenda.MapaActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

Me mostra o código de como está hoje, por favor.

public class MapaActivity extends AppCompatActivity {

    private static final int REQUEST_PERMISSOES = 1;
    private FragmentManager manager;
    private FragmentTransaction tx;

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

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

    }

    private void chamaMapa() {
        manager = getSupportFragmentManager();
        tx = manager.beginTransaction();
        tx.replace(R.id.frame_mapa, new MapaFragment());
        tx.commit();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case REQUEST_PERMISSOES:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){
                    chamaMapa();
                } else {
                    finish();
                }
                break;
        }
    }
}
solução!

Faz um teste para mim, por gentileza.


 private void chamaMapa() {
        manager = getSupportFragmentManager();
        tx = manager.beginTransaction();
        tx.replace(R.id.frame_mapa, new MapaFragment());
        tx.commitAllowingStateLoss();
    }

Funcionou Matheus, tudo ocorreu como esperado.

Ainda não entendi muito bem o por que estava acontecendo aquela ultima exception, mas vou pesquisar um pouco mais para poder esclarecer, e vou pesquisar também sobre o método commitAllowingStateLoss();

Muito obrigado por toda a ajuda e atenção.

Segue código completo da classe MapaActivity, caso seja dúvida de mais alguém.

public class MapaActivity extends AppCompatActivity {

    private static final int REQUEST_PERMISSOES = 1;
    private FragmentManager manager;
    private FragmentTransaction tx;

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

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

    }

    private void chamaMapa() {
        manager = getSupportFragmentManager();
        tx = manager.beginTransaction();
        tx.replace(R.id.frame_mapa, new MapaFragment());
        tx.commitAllowingStateLoss();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case REQUEST_PERMISSOES:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){
                    chamaMapa();
                } else {
                    finish();
                }
                break;
        }
    }
}

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software