wake-up-neo.com

onRequestPermissionsResult wird nicht im Dialogfragment aufgerufen

Ich habe begonnen, an der Laufzeitberechtigung für Android M zu arbeiten. Hier stehe ich vor dem Problem, dass, wenn requestPermissions von Dialog Fragment-Klasse aufgerufen wird, onRequestPermissionsResult nicht in derselben Dialog fragment-Klasse aufgerufen wird. Wenn jedoch requestPermissions von der Klasse Activity oder der Klasse Fragment aufgerufen wird, wird die Methode onRequestPermissionsResult in derselben Klasse aufgerufen. 

Hier ist mein Beispielcode:

public class ContactPickerDialog extends DialogFragment {
    private static final int READ_CONTACTS_REQUEST_CODE = 12;
    private Context mContext;

    private void loadContact() {
        if(hasPermission(mContext, Manifest.permission.READ_CONTACTS)){
            new ContactSyncTask().execute();
        } else {
            this.requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, READ_CONTACTS_REQUEST_CODE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        Logger.d("TAG", "dialog onRequestPermissionsResult");
        switch (requestCode) {
            case READ_CONTACTS_REQUEST_CODE:
                // Check Permissions Granted or not
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    new ContactSyncTask().execute();
                } else {
                    // Permission Denied
                    Toast.makeText(getActivity(), "Read contact permission is denied", Toast.LENGTH_SHORT).show();
                }
            break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    private static boolean hasPermission(Context context, String permission){
        return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
    }

} 

Hier im Code rufe ich requestPermissions Methode der Dialog Fragment Klasse auf. Ich erwarte, dass ich in derselben Klasse Ergebnisse erzielen kann.

Jede Hilfe wird geschätzt. Danke im Voraus!


EDIT: Hier füge ich mehr Details hinzu, so dass es für andere hilfreich ist . Früher habe ich getChildFragmentManager () verwendet, um das DialogFragment anzuzeigen.

ContactPickerDialog dialog = new ContactPickerDialog();
dialog.show(getChildFragmentManager(), "Contact Picker");

As @CommonWare hat mich jedoch gebeten, mithilfe von Aktivität das DialogFragment anzuzeigen. Ich habe folgende Änderungen vorgenommen und es funktioniert.

ContactPickerDialog dialog = new ContactPickerDialog();
dialog.show(getActivity().getSupportFragmentManager(), "Contact Picker");
53
Dhaval Patel

Es scheint einen einen Fehler in Android zu geben, bei dem verschachtelte Fragmente den onRequestPermissionsResult()-Callback nicht unterstützen. Bei einer DialogFragment scheint eine Problemumgehung darin zu liegen, dass das Fragment zeigt, dass der Dialog eine Methode für die Hostingaktivität aufrufen soll, und die Aktivität zeigt die DialogFragment selbst.

54
CommonsWare

Wenn Sie sich in einer Fragment aus der Unterstützungsbibliothek befinden, rufen Sie requestPermissions() direkt auf, und Ihr Fragment onRequestPermissionsResult() wird zurückgerufen.

Wenn Sie ActivityCompat.requestPermissions() aufrufen, wird die Activitys onRequestPermissionsResult() zurückgerufen.

105
minipif

Dieses Problem scheint in Android Support Library 23.3.0 und höheren Versionen behoben zu sein.

Wenn Sie Support v4-Fragmente verwenden, werden verschachtelte Fragmente jetzt angezeigt Rückrufe an onRequestPermissionsResult () empfangen.

Edit: @AndrewS, hier kannst du ein Update machen.

Ändern Sie in Ihrer build.gradle-Datei (App-Datei) die folgende Zeile, um die neueste Support-Bibliothek 24.0.0 zu verwenden, die die neueste Version ist:

dependencies {
    compile 'com.Android.support:appcompat-v7:24.0.0'
}
13

Ich hatte dieses Problem ohne verschachtelte Fragmente, bei denen die Aktivität das Dialogfragment zeigte und das Ergebnis nicht übergeben wurde.

Hinzufügen
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
an die Aktivität onRequestPermissionsResult() hat das Problem behoben.

5
Eric B.

EDIT:

Ich schlage vor, eine neue Version von Support Library 23.3.0 zu verwenden, da Google ein Problem mit dem Aufruf von onRequestPermissionsResult behoben hat. Wenn Sie jedoch aus irgendeinem Grund eine ältere Version verwenden müssen, finden Sie weitere Informationen unter Origin.

ORIGINAL ANTWORT:

Ich verwende die nächste Problemumgehung (zusammen mit easyPermissions library):

BaseFragment:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    /** child v4.fragments aren't receiving this due to bug. So forward to child fragments manually
     * https://code.google.com/p/Android/issues/detail?id=189121
     */
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    List<Fragment> fragments = getChildFragmentManager().getFragments();
    if (fragments != null) {
        // it is possible that fragment might be null in FragmentManager
        for (Fragment fragment : fragments) {
            if (fragment != null) {
                fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
            }
        }
    }
}

BaseActivity:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    Fragment fragment = getSupportFragmentManager().findFragmentById(getFragmentContainer())
    if (fragment != null) {
        fragment.onRequestPermissionsResult(requestCode&0xff, permissions, grantResults);
    }
}

Verwendungszweck:

public class SomeFragment extends BaseFragment implements EasyPermissions.PermissionCallbacks {
    private static final int PICK_CONTACT = 1;
    private static final int READ_CONTACTS_PERM = 2;

    // some code

    @AfterPermissionGranted(READ_CONTACTS_PERM)
    private void pickContactWithPermissionsCheck() {
        if (EasyPermissions.hasPermissions(getContext(), Manifest.permission.READ_CONTACTS)) {
            // Have permission
            pickContactForResult();
        } else {
            // Request one permission
            EasyPermissions.requestPermissions(this, getString(R.string.read_contacts_permission_explanation),
                    READ_CONTACTS_PERM, Manifest.permission.READ_CONTACTS);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // FIXME problem with incorrect requestCode coming to callback for Nested fragments
        // More information here - https://code.google.com/p/Android/issues/detail?id=189121
        if (isVisible() && Arrays.asList(permissions).contains(Manifest.permission.READ_CONTACTS)) {
            requestCode = READ_CONTACTS_PERM;
        }

        // EasyPermissions handles the request result.
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }
}
5
Oleksandr

Bei Problemen mit verschachtelten Fragmenten können Sie die Genehmigung vom übergeordneten Fragment anfordern

getParentFragment().requestPermissions(new String[]{permission}, requestCode);

und dann Rückruf an untergeordnetes Fragment weiterleiten

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grants) {
    List<Fragment> fragments = getChildFragmentManager().getFragments();
    if (fragments != null) {
        for (Fragment fragment : fragments) {
            if (fragment != null) {
                fragment.onRequestPermissionsResult(requestCode, permissions, grants);
            }
        }
    }
}
4
Artem

Eine Sache, die mir geholfen hat, war dies. Wenn Sie die Erlaubnis für ein verschachteltes Fragment anfordern, verwenden Sie getParent auf diese Weise

 fragment.getParentFragment().requestPermissions((new String[]
              {Manifest.permission.READ_CONTACTS}), requestCode);

und überschreiben Sie dann das übergeordnete Fragment inRequestPermissionResult und suchen Sie nach dem entsprechenden requestCode.

Ich hoffe es hilft dir auch.

4
udit

Wenn Sie sich die Dokumentation der requestPermissions-Methode des Fragments ansehen, werden Sie feststellen, dass Sie die Berechtigungen in Ihrem Manifest noch deklarieren müssen:

 enter image description here

Ist dies nicht der Fall, wird die onRequestPermissionsResult des Fragments nicht aufgerufen.

Stattdessen wird die onRequestPermissionsResult der Aktivität aufgerufen, die jedoch keine Auswirkungen hat.

Um eine Erlaubnis aus einem Fragment heraus zu erhalten, gehen Sie wie folgt vor:

1. Deklarieren Sie die Erlaubnis in Ihrem Manifest

<uses-permission Android:name="Android.permission.CAMERA"/>

Geben Sie dies vor dem Anwendungs-Tag ein.

2. Überprüfen Sie die Berechtigung in Ihrem Fragment.

if (ActivityCompat.checkSelfPermission(context, permission) 
        != PackageManager.PERMISSION_GRANTED) {

    requestPermissions(
        arrayOf(Manifest.permission.CAMERA), 
        REQUEST_CODE_CAMERA_PERMISSION)
}

3. Warten Sie auf das Berechtigungsergebnis in Ihrem Fragment.

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    when (requestCode) {
        REQUEST_CODE_CAMERA_PERMISSION -> { 

        val granted = grantResults.isNotEmpty()
            && permissions.isNotEmpty()
            && grantResults[0] == PackageManager.PERMISSION_GRANTED
            && !ActivityCompat.shouldShowRequestPermissionRationale(activity, permissions[0])    

        when (granted) {
            true -> openCamera()
            else -> proceedWithoutPermission()
        }
    }
}

4. Stellen Sie sicher, dass Sie die AktivitätonRequestPermissionsResult der Aktivität nicht überschreiben.

Das Überschreiben der onRequestPermissionsResult der Aktivität führt dazu, dass das Fragment des Fragments nicht reagiert.

1
Nino Handler

Ich habe es so gemacht

public class DialogFragmentSMS extends DialogFragment implements View.OnClickListener {

public static DialogFragmentSMS frag;
private static View view;
private static ViewGroup parent;
private EditText editTextMensagem;
private String celular;

private final static int SMS_REQUEST = 20;

public DialogFragmentSMS() {

}
public static DialogFragmentSMS newInstance(String celular)
{

    Bundle args = new Bundle();
    args.putString("celular", celular);
    frag = new DialogFragmentSMS();
    frag.setArguments(args);
    return frag;
}

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

    @Override
public void onClick(View v) {
    if (!PermissaoUtils.hasPermission(getActivity(), Manifest.permission.SEND_SMS)) {
        //PermissaoUtils.requestPermissions(getActivity(), new String[]{Manifest.permission.SEND_SMS}, SMS_REQUEST);
        frag.requestPermissions(new String[]{Manifest.permission.SEND_SMS}, SMS_REQUEST);
    }else{
        if (validaCampos()) {
            SmsManager smsManager = SmsManager.getDefault();
            smsManager.sendTextMessage("0" + celular, null, editTextMensagem.getText().toString(), null, null);
            Toast.makeText(getActivity(), R.string.sms_enviado, Toast.LENGTH_SHORT).show();
            getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
            frag.dismiss();
        }
    }
}

Meine Klassenerlaubnis

public class PermissaoUtils
{
    public static boolean useRunTimePermissions() {
        return Build.VERSION.SDK_INT > Build.VERSION_CODES.Lollipop_MR1;
    }

    public static boolean hasPermission(Activity activity, String permission) {
        if (useRunTimePermissions()) {
            return activity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
        }
        return true;
    }

    public static void requestPermissions(Activity activity, String[] permission, int requestCode) {
        if (useRunTimePermissions()) {
            activity.requestPermissions(permission, requestCode);
        }
    }
}
0

Vergewissern Sie sich zusätzlich zum Endteil der Antwort von Nino Handler und für alle, die immer noch Probleme damit haben, wenn Sie onRequestPermissionsResult in der übergeordneten Aktivität/im Fragment Ihres Dialogfragments überschreiben.

Ich habe onRequestPermissionsResult in der übergeordneten Aktivität meines Dialogfragments überschrieben, aber die Supermethode dort nicht aufgerufen. Nachdem ich es geändert hatte, um die Supermethode aufzurufen, wurde sie ordnungsgemäß an das onRequestPermissionsResult in meinem Dialogfragment delegiert.

0
D.J.M. Francis