onRequestPermissionsResult non essere chiamato in frammento se definito sia in frammento che in attività


167

Ho un frammento in cui ho recyclerview e impostazione dei dati in questo recyclerview utilizzando l'adattatore recyclerview.

Ora, sto avendo un pulsante nella voce di elenco dell'adattatore facendo clic sul quale devo controllare l'autorizzazione READ_EXTERNAL_STORAGE in Android per un nuovo modello di autorizzazione in Android.

Ho creato una nuova funzione nel frammento di questo adattatore per verificare se l'autorizzazione è concessa o meno e richiedere l'autorizzazione se non già concessa.

Ho passato MyFragment.this come parametro nell'adattatore e chiamando il metodo del frammento sul pulsante clicca nell'adattatore.

Ho usato il seguente codice per chiamare requestPermission in frammento.

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

Ho ignorato il onRequestPermissionsResultmetodo in frammento usando il codice seguente:

@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 {}

Ma non viene chiamato, invece del metodo onRequestPermissionsResult di questa attività viene chiamato.

Ho definito lo stesso metodo onRequestPermissionsResult anche nell'attività padre del frammento e viene chiamato.

Non riesco a rimuovere il metodo onRequestPermissionsResult dell'attività ma desidero chiamare il metodo onRequestPermissionsResult del frammento quando richiedo l'autorizzazione dal frammento. Come posso fare questo? Sto facendo qualcosa di sbagliato qui, per favore aiutami se qualcuno ha idea qui.


1
fai riferimento a questo link permessi di esecuzione in frammento Questa è la soluzione esatta
Antony jackson,

Risposte:


372

Risposta modificata per coprire questioni più ampie

Penso che tu stia confondendo il metodo per frammento e attività. Ho avuto un problema simile il mio progetto il mese scorso. Si prega di verificare se si dispone finalmente di quanto segue:

  1. In AppCompatActivity utilizzare il metodo ActivityCompat.requestpermissions
  2. Nel frammento di supporto v4 dovresti usare autorizzazioni di richiesta
  3. La cattura è se si chiama AppcompatActivity.requestpermissions nel frammento, la richiamata verrà attivata e non frammentata
  4. Assicurati di chiamare super.onRequestPermissionsResultdalle attività onRequestPermissionsResult.

Vedi se aiuta.


9
Solo per ricontrollare assicurati di avere super.onrequestpermissionresult impostato nella tua attività
VarunJoshi129

27
L'aggiunta super.onrequestpermissionresultdi onrequestpermissionresult di attività chiama la richiesta onrequestpermissionresult del frammento quando richiedo l'autorizzazione utilizzando requestpermissions.
Funziona

1
Il super.onrequestpermissionresult mancava dall'attività callback, portando al mio frammento di callback non essere chiamato
sakis kaliakoudas

4
requestPermissions () richiede il livello API 23. Esiste un'altra soluzione retrocompatibile per il livello API 21?
Adam Hurwitz il

2
@ msc87 1. in onRequestPermissionsResult di attività e frammento, la prima riga dovrebbe essere: super.onRequestPermissionsResult (requestCode, autorizzazioni, grantResults); 2.in frammento in cui si riconosce l'autorizzazione non concessa, basta chiamare il metodo requestPermission in questo modo: requestPermissions (nuova stringa [] {Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE);
AREF

122

Ho richiesto il permesso di localizzazione da un frammento e nel frammento, ho dovuto cambiare questo:

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

a questa:

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

quindi onRequestPermissionsResult è stato chiamato nel frammento.


2
Funziona come un fascino :)
Antonio Vlasic,

1
non funziona con Kotlin, per favore, potete aiutarmi per lo stesso, qui viene utilizzata questa richiesta Condizioni (contesto come Attività, permessoList.toTypedArray (), MY_PERMISSIONS_REQUEST)
Arbaz.in

Grazie :), mi risparmia tempo
Axrorxo'ja Yodgorov,

19

Questo è un errore comune che le persone fanno quando si codifica per marshmallow.

In AppCompatActivity, è necessario utilizzare ActivityCompat.requestPermissions; Quando sei in android.support.v4.app.Fragment, dovresti usare semplicemente requestPermissions (questo è un metodo di istanza di android.support.v4.app.Fragment) Se chiami ActivityCompat.requestPermissions in un frammento, viene richiamato il callback onRequestPermissionsResult l'attività e non il frammento.

requestPermissions(permissions, PERMISSIONS_CODE);

Se stai chiamando questo codice da un frammento ha il suo metodo requestPermissions.

Quindi il concetto di base è: Se sei in un'attività, chiama

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

e se in un frammento, basta chiamare

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

Per il riferimento, ho ottenuto la risposta da questo link https://www.coderzheaven.com/2016/10/12/onrequestpermissionsresult-not-called-on-fragments/


6

Il metodo requestPermissionssu Frammenti richiede API livello 23 o superiore.
Se la tua app ha come target una versione precedente, puoi usarla

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

Per prima cosa devi aggiungere la dipendenza support-v13:

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

FragmentCompat è deprecato dalla versione 27.1.0
Raj kannan Iyyappan

6

cambia questo :

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

a questa :

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

Quello inferiore deve essere utilizzato in un frammento (onRequestPermissionsResult è chiamato in frammento), la versione ActivityCompat deve essere utilizzata quando onRequestPermissionsResult è situato nell'Attività.
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();
 }
 }

cambia permesso


2
Ciao utente2002721; il tuo codice potrebbe essere corretto, ma con un certo contesto darebbe una risposta migliore; ad esempio, potresti spiegare come e perché questa modifica proposta risolverà il problema dell'interrogante, magari includendo un collegamento alla documentazione pertinente. Ciò lo renderebbe più utile per loro e anche più utile per altri lettori del sito che sono alla ricerca di soluzioni a problemi simili.
Vince Bowdren,

Il programma potrebbe generare un'eccezione di array fuori limite se si tenta di accedere all'indice 0 di grantResults senza verificare prima la lunghezza. È successo al mio programma. Ho separato l'istruzione if per grantResults come un'istruzione if interna per evitare che ciò accada, e ora funziona bene.
Peter Griffin,

1

Questa risposta accettata non ha funzionato per me, quindi ho trovato la mia soluzione, spiegata di seguito:

1.Prima ho creato un metodo, in frammento:

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 poi chiamato dalla sua attività sottostante:

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

E sta funzionando ...


0

Verifica che sia PERMISSION_REQUEST_CODEdentro onRequestPermissionsResultche dentro Fragmentcontenga lo stesso valore.


0

Per il traget SDK 28, il controllo SDK (> 23) e le richieste di richiesta dal frammento funzionerebbero. ActivityCompat.requestPermissions non riesce (se si imposta un codice di richiesta inferiore a 65536, verrà visualizzata la finestra di dialogo delle autorizzazioni e se l'utente consente l'autorizzazione, vengono fornite le autorizzazioni, ma non si verificherà alcun callback. Ma se si imposta sopra 65536, ActivityCompat.requestPermissions sarà fallire immediatamente. Non conosco il ragionamento alla base di questa logica. Potrebbe essere un bug o intenzionale).

Codice di lavoro:

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

non è necessario eseguire il controllo della versione. nelle versioni inferiori a 23, restituirà semplicemente il valore "permesso concesso". La scelta dello sviluppatore qui: evita il blocco 'if' per semplicità o evita la chiamata di richiesta quando non è necessaria
Psest328


0

Ho avuto lo stesso problema. Il frammento può essere inizializzato dal layout dell'attività. Come quello:

main_activty.xml

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

Questo problema è stato risolto per me quando l'ho usato FragmentTransactioninvece


0

nelle API inferiori a 23 è possibile creare un'interfaccia nell'attività, quindi implementarla nel frammento figlio e quando si ottiene il risultato della richiesta di autorizzazione, l'attività viene passata all'interfaccia implementata in frammento. È così semplice :)


0

puoi chiamare il metodo Frammento di seguito

@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

Questo problema è stato effettivamente causato da NestedFragments. Fondamentalmente la maggior parte dei frammenti abbiamo esteso un HostedFragment che a sua volta estende un CompatFragment. La presenza di questi frammenti nidificati ha causato problemi che alla fine sono stati risolti da un altro sviluppatore nel progetto.

Stava facendo alcune cose di basso livello come il cambio di bit per farlo funzionare, quindi non sono troppo sicuro della soluzione finale effettiva


3
Invece di copiare una risposta, si può solo fornire un link - stackoverflow.com/a/33081173/630833
jayeffkay
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.