onRequestPermissionsResult não está sendo chamado no fragmento se definido no fragmento e na atividade


167

Eu tenho um fragmento no qual tenho uma visão de reciclagem e definindo dados nessa visão de reciclagem usando o adaptador de visão de reciclagem.

Agora, estou com um botão no item de lista do adaptador clicando no qual preciso verificar a permissão READ_EXTERNAL_STORAGE no android para obter um novo modelo de permissão no android.

Eu criei uma nova função no fragmento deste adaptador para verificar se a permissão foi concedida ou não e, se já não tiver sido concedida, solicitar a permissão.

Passei MyFragment.this como um parâmetro no adaptador e, chamando o método do fragmento no botão, clique no adaptador.

Eu usei o código abaixo para chamar requestPermission no fragmento.

if(ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED){
       requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                ConstantVariables.READ_EXTERNAL_STORAGE);
    }

Eu substituí o onRequestPermissionsResultmétodo no fragmento usando o código abaixo:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case ConstantVariables.READ_EXTERNAL_STORAGE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, proceed to the normal flow.
                startImageUploading();
            } else {}

Mas não está sendo chamado, em vez do método onRequestPermissionsResult desta atividade ser chamado.

Eu defini o mesmo método onRequestPermissionsResult na atividade pai do fragmento também e está sendo chamado.

Não consigo remover o método onRequestPermissionsResult da atividade, mas quero chamar o método onRequestPermissionsResult do fragmento quando solicito permissão do fragmento. Como posso fazer isso? Estou fazendo algo errado aqui, por favor me ajude se alguém tiver idéia aqui.


1
consulte este link executar permissões tempo no fragmento Esta é a solução exata
Antony jackson

Respostas:


372

Resposta editada para cobrir problemas mais amplos

Eu acho que você está confundindo o método para fragmento e atividade. Tive um problema semelhante no meu projeto no mês passado. Por favor, verifique se você finalmente tem o seguinte:

  1. Em AppCompatActivity, use o método ActivityCompat.requestpermissions
  2. No fragmento de suporte v4, você deve usar requestpermissions
  3. O problema é que, se você chamar AppcompatActivity.requestpermissions no seu fragmento, o retorno de chamada chegará à atividade e não ao fragmento
  4. Certifique-se de ligar super.onRequestPermissionsResultda atividade onRequestPermissionsResult.

Veja se isso ajuda.


9
Só para verificação dupla verifique se você tem conjunto super.onrequestpermissionresult em sua atividade
VarunJoshi129

27
A adição super.onrequestpermissionresultdo resultado da solicitação de autorização da atividade chama o resultado da solicitação de autorização do fragmento quando solicito permissão usando requestpermissions. Isso é bom trabalhar agora, muito obrigado .. :)
Prithniraj Nicyone

1
O super.onrequestpermissionresult estava faltando a partir do retorno de chamada atividade, levando a minha fragmento de retorno de chamada não sendo chamado
sakis kaliakoudas

4
requestPermissions () requer o nível 23 da API. Existe outra solução que seja compatível com versões anteriores do nível 21 da API?
Adam Hurwitz

2
@ msc87 1. em onRequestPermissionsResult da atividade e fragmento, a primeira linha deve ser: super.onRequestPermissionsResult (requestCode, permissions, grantResults); 2.em um fragmento em que você reconhece a permissão não concedida, basta chamar o método requestPermission como este: requestPermissions (new String [] {Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE);
AREF 07/04

122

Solicitei permissão de localização de um fragmento e, no fragmento, precisava alterar isso:

            ActivityCompat.requestPermissions(getActivity(), new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_REQ_CODE);

para isso:

            requestPermissions(new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_REQ_CODE);

o onRequestPermissionsResult foi chamado no fragmento.


2
Funciona como um encanto :)
Antonio Vlasic

1
ele não está funcionando com Kotlin você pode por favor me ajude para o mesmo aqui é usado este requestPermissions (contexto como Atividade, permissionList.toTypedArray (), MY_PERMISSIONS_REQUEST)
Arbaz.in

Obrigado :), você economiza tempo
Axrorxo'ja Yodgorov 13/08/19

19

Esse é um erro comum que as pessoas cometem ao codificar marshmallow.

Quando em AppCompatActivity, você deve usar ActivityCompat.requestPermissions; Quando em android.support.v4.app.Fragment, você deve simplesmente solicitar requestPermissions (este é um método de instância de android.support.v4.app.Fragment) Se você chamar ActivityCompat.requestPermissions em um fragmento, o retorno de chamada onRequestPermissionsResult será chamado a atividade e não o fragmento.

requestPermissions(permissions, PERMISSIONS_CODE);

Se você está chamando esse código de um fragmento, ele possui seu próprio método requestPermissions.

O conceito básico é que, se você estiver em uma atividade, chame

ActivityCompat.requestPermissions(this,
                            new String[]{Manifest.permission.CAMERA},
                            MY_PERMISSIONS_REQUEST_CAMERA);

e se estiver em um fragmento, basta ligar

requestPermissions(new String[]{Manifest.permission.CAMERA},
                            MY_PERMISSIONS_REQUEST_CAMERA);

Para referência, obtive a resposta neste link https://www.coderzheaven.com/2016/10/12/onrequestpermissionsresult-not-called-on-fragments/


6

O método requestPermissionsem fragmentos requer API nível 23 ou superior.
Se seu aplicativo segmentar uma versão inferior, você poderá usar

FragmentCompat.requestPermissions(this,
            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
            ConstantVariables.READ_EXTERNAL_STORAGE);

Primeiro você precisa adicionar a dependência support-v13:

implementation "com.android.support:support-v13:$supportLibVersion"

O FragmentCompat foi descontinuado da versão 27.1.0
Raj kannan Iyyappan 27/18

6

mude isso :

ActivityCompat.requestPermissions(
    activity,
    arrayOf(Manifest.permission.READ_CONTACTS),
    PERMISSIONS_REQUEST_READ_CONTACTS
)

para isso :

requestPermissions(
     arrayOf(Manifest.permission.READ_CONTACTS),
     PERMISSIONS_REQUEST_READ_CONTACTS
)

O inferior é para uso em um fragmento (onRequestPermissionsResult é chamado em fragmento), a versão ActivityCompat é para uso quando onRequestPermissionsResult está localizado na Activity.
Roar Grønmo

1
private void showContacts() {
 if (getActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
         != PackageManager.PERMISSION_GRANTED) {
     requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
             PERMISSIONS_REQUEST_READ_STORAGE);
 } else {
     doShowContacts();
 }
}

 @Override
 public void onRequestPermissionsResult(int requestCode, String[] permissions,
     int[] grantResults) {
 if (requestCode == PERMISSIONS_REQUEST_READ_STORAGE
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
     doShowContacts();
 }
 }

alterar permissão


2
Olá user2002721; seu código pode estar correto, mas com algum contexto, seria uma resposta melhor; por exemplo, você pode explicar como e por que essa alteração proposta resolveria o problema do questionador, talvez incluindo um link para a documentação relevante. Isso tornaria mais útil para eles e também para outros leitores de sites que estão procurando soluções para problemas semelhantes.
precisa saber é o seguinte

O programa pode lançar uma matriz fora dos limites, se você tentar acessar o índice 0 de grantResults sem verificar primeiro o comprimento. Isso aconteceu com o meu programa. Separei a instrução if para grantResults como uma instrução if interna para impedir que isso aconteça, e ela funciona bem agora.
Peter Griffin

1

Esta resposta aceita não foi trabalhada para mim, então encontrei minha própria solução, explicada abaixo:

Primeiro, criei um método, no fragmento:

public static void MyOnRequestPermissionResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
        if (requestCode == 1 && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "Permission: true");
        } else {
            Log.d(TAG, "permission: false");
        }
}

2.E então o chamou de sua atividade subjacente:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if(requestCode ==1){
        SignupFragment.MyOnRequestPermissionResult(requestCode, permissions, grantResults);
    }
}

E está funcionando ...


0

Verifique se tanto PERMISSION_REQUEST_CODEem onRequestPermissionsResulte dentro de sua Fragmentcontém o mesmo valor.


0

Para o tragetSDK 28, a verificação do SDK (> 23) e as permissões de solicitação do fragmento funcionariam. O ActivityCompat.requestPermissions está falhando (se você definir o código de solicitação abaixo de 65536, a caixa de diálogo de permissão será exibida e, se o usuário permitir, as permissões serão fornecidas, mas não haverá retorno de chamada. Mas se você definir acima de 65536, o ActivityCompat.requestPermissions ocorrerá. falhe imediatamente. não sei o raciocínio por trás dessa lógica. pode ser um bug ou intencional).

Código de trabalho:

  if (Build.VERSION.SDK_INT >= 23) {
                        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_ACCESS_REQUEST);
                    }

você não precisa fazer a verificação da versão. nas versões abaixo de 23, ele retornará o valor de 'permissão concedida'. Escolha do desenvolvedor aqui: evitar o bloco 'se' para simplificar ou evitar a chamada pedido quando não for necessário
Psest328


0

Eu tive o mesmo problema. Seu fragmento pode ser inicializado a partir do layout da atividade. Curtiu isso:

main_activty.xml

<fragment
    android:id="@+id/fragment"
    android:name="com.exampe.SomeFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Esse problema foi resolvido para mim quando eu usei FragmentTransactionvez


0

nas APIs abaixo de 23, você pode criar uma interface na atividade e implementá-la no fragmento filho. Quando você obtiver uma solicitação de permissão, a atividade passará para a interface implementada no fragmento. É simples assim :)


0

você pode chamar o método Fragment abaixo

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case REQUEST_CODE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission is granted. Continue the action or workflow
                // in your app.
                doActionBecauseNowYouCanBro();
            } else {
                // Explain to the user that the feature is unavailable because
                // the features requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
                showWhyRequestPermissionsAndDontBlockUserItsCalledManners();
            }
            return;
    }
    // Other 'case' lines to check for other
    // permissions this app might request.

}

-5

Esse problema estava realmente sendo causado por NestedFragments. Basicamente, na maioria dos fragmentos, estendemos um HostedFragment que, por sua vez, estende um CompatFragment. A presença desses fragmentos aninhados causou problemas que foram resolvidos por outro desenvolvedor no projeto.

Ele estava fazendo algumas coisas de baixo nível, como troca de bits, para que isso funcionasse, então não tenho certeza da solução final real


3
Em vez de copiar uma resposta, você poderia apenas fornecer um link - stackoverflow.com/a/33081173/630833
jayeffkay
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.