onRequestPermissionsResult не вызывается в фрагменте диалогового окна



я начал работать над разрешением Android M runtime. Здесь я столкнулся с проблемой, что если requestPermissions вызывается из Dialog Fragment класса onRequestPermissionsResult не вызывается в той же Dialog fragment класса. Но если requestPermissions вызывается из Activity класса или Fragment класса onRequestPermissionsResult метод вызывается в том же классе.



вот мой пример кода:



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;
}

}


вот в коде я звоню requestPermissions метод Dialog Fragment класса. Так что я ожидаю получить результат в том же класс.



любая помощь приветствуется. Заранее спасибо!





EDIT:
Здесь я добавляю больше деталей, так что это будет более полезно для других.
Ранее я использовал getChildFragmentManager (), чтобы показать DialogFragment.



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


, А Как @CommonWare попросил меня использовать activity, чтобы показать DialogFragment. Я сделал следующие изменения, и это работает.



ContactPickerDialog dialog = new ContactPickerDialog();
dialog.show(getActivity().getSupportFragmentManager(), "Contact Picker");
778   9  

9 ответов:

появляется ошибка в Android, где вложенные фрагменты не поддерживают onRequestPermissionsResult() обратный. Для DialogFragment, обходной путь, по-видимому, состоит в том, чтобы фрагмент, желающий показать диалог, вызывал метод на хостинге activity, и activity показывает .

если вы находитесь внутри Fragment из библиотеки поддержки, вызов requestPermissions() непосредственно, и ваш фрагмент onRequestPermissionsResult() будет называться обратной.

если вы называете ActivityCompat.requestPermissions(), потом Activity ' s onRequestPermissionsResult() это будет вызвано обратно.

этой вопрос кажется, исправлена в Библиотека Поддержки Android 23.3.0 и выше версий.

Если вы используете фрагменты поддержки v4, вложенные фрагменты теперь будут получение обратных вызовов в onRequestPermissionsResult ().

Edit: @AndrewS, вот как вы можете обновить.

в свою сборку.файл gradle (app), измените следующую строку, чтобы использовать последнюю библиотеку поддержки 24.0.0, которая является последней версия:

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

EDIT:

Я предлагаю использовать новую версию библиотеки поддержки 23.3.0, потому что Google Исправлена проблема с не вызывая onRequestPermissionsResult, но если по каким-то причинам вам нужно использовать более старую версию, то см. ответ origin ниже.

ОРИГИНАЛЬНЫЙ ОТВЕТ:

Я использую следующий обходной путь (вместе с easyPermissions библиотека):

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);
    }
}

использование:

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);
    }
}

Если у вас есть проблемы с вложенным фрагментом, вы можете запросить разрешение от родительского фрагмента

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

и потом вперед, обратного вызова, чтобы ребенок фрагмент

@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);
            }
        }
    }
}

одна вещь, которая помогла мне в этом. Когда вы запрашиваете разрешение от вложенного фрагмента, используйте getParent как so

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

а затем переопределите Родительский фрагмент onRequestPermissionResult и проверьте соответствующий код запроса.

надеюсь, что это помогает вам.

у меня была эта проблема без вложенных фрагментов, где активность показывала фрагмент диалога, и результат не передавался.

добавлять
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
к деятельности onRequestPermissionsResult() решается вопрос.

Я сделал это так

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();
        }
    }
}

Мой Класс Разрешение

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);
        }
    }
}

если вы вызываете DialogFragment из фрагмента, используйте это:

YourDialogFragment dialogFragment = YourDialogFragment.newInstance();
dialogFragment.show(getActivity().getFragmentManager(), YourDialogFragment.TAG);
dialogFragment.setParentFragment(this);

также напишите фрагмент:

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

    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        ...
    }
}

в YourDialogFragment напишите дополнительный метод для передачи родительского фрагмента:

public void setParentFragment(Fragment fragment) {
    this.fragment = fragment;
}

позже в YourDialogFragment при запросе разрешений вызовите:

if (fragment != null) {
    fragment.requestPermissions(new String[]{permission}, REQUEST_CODE);
}

Comments

    Ничего не найдено.