developer tip

onRequestPermissionsResult가 대화 조각에서 호출되지 않습니다.

optionbox 2021. 1. 9. 09:44
반응형

onRequestPermissionsResult가 대화 조각에서 호출되지 않습니다.


Android M 런타임 권한 작업을 시작했습니다. 여기에 나는 경우 그 문제에 직면하고있다 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클래스 메서드를 호출하고 있습니다 . 그래서 같은 수업에서 결과를 기대하고 있습니다.

도움을 주시면 감사하겠습니다. 미리 감사드립니다!


편집 : 여기에 더 많은 세부 정보를 추가하여 다른 사람들에게 더 도움이 될 것입니다. 이전에는 getChildFragmentManager ()를 사용하여 DialogFragment를 표시했습니다.

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

그러나 @CommonWareDialogFragment 를 표시하기 위해 활동을 사용하도록 요청했습니다. 다음과 같이 변경했으며 작동합니다.

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

있을 나타납니다 안드로이드의 버그 중첩 조각이 지원하지 않는, onRequestPermissionsResult()콜백. 의 경우 DialogFragment해결 방법은 대화 상자를 표시하려는 프래그먼트가 호스팅 활동에 대한 메서드를 호출하도록하는 것으로 보이며 활동은 DialogFragment자체를 표시합니다 .


당신이 내부에 있다면 Fragment지원 라이브러리에서, 전화를 requestPermissions()직접, 그리고 조각의가 onRequestPermissionsResult()다시 호출됩니다.

당신이 호출 할 경우 ActivityCompat.requestPermissions(), 다음이의 ActivityonRequestPermissionsResult()다시 호출됩니다.


문제Android 지원 라이브러리 23.3.0 이상 버전 에서 해결 된 것으로 보입니다 .

Support v4 프래그먼트를 사용하는 경우 중첩 프래그먼트는 이제 onRequestPermissionsResult ()에 대한 콜백을 수신합니다.

편집 : @AndrewS, 업데이트 방법은 다음과 같습니다.

build.gradle (app) 파일에서 최신 버전 인 최신 지원 라이브러리 24.0.0을 사용하도록 다음 줄을 변경합니다.

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

편집하다:

Google이를 호출하지 않는 문제를 해결onRequestPermissionsResult 했기 때문에 새 버전의 지원 라이브러리 23.3.0을 사용하는 것이 좋지만 어떤 이유로 이전 버전을 사용해야하는 경우 아래 원본 답변을 참조하세요.

원래 답변 :

다음 해결 방법을 사용하고 있습니다 ( 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);
    }
}

활동이 대화 조각을 표시하고 결과가 전달되지 않는 중첩 조각 없이이 문제가 발생했습니다.


super.onRequestPermissionsResult(requestCode, permissions, grantResults);
활동에 추가 onRequestPermissionsResult()하면 문제 해결되었습니다.


중첩 조각에 문제가있는 경우 부모 조각에 권한을 요청할 수 있습니다.

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를 사용하십시오.

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

그런 다음 부모 조각 onRequestPermissionResult를 재정의하고 해당 requestCode를 확인하십시오.

도움이되기를 바랍니다.


프래그먼트 requestPermissions메서드 의 문서를 살펴보면 매니페스트에서 권한을 선언해야한다는 것을 알 수 있습니다.

여기에 이미지 설명 입력

그렇지 않은 경우 조각 자체 onRequestPermissionsResult가 호출되지 않습니다.

대신 활동 onRequestPermissionsResult이 호출되지만 효과가 없습니다.

So grating a permission from within a fragment should be done as follows:

1. Declare the permission in your manifest

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

Enter this before the application tag.

2. Check for the permission in your fragment

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

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

3. Wait for the permission result in your 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. Make sure you don't override the activity's onRequestPermissionsResult

Overriding the activity's onRequestPermissionsResult will cause the fragment's one not to react.


I got it done like this

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

My Class Permission

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

In addition to the end portion of Nino Handler's answer and for anyone still having issues with this, make sure that if you do override onRequestPermissionsResult in the parent activity/fragment of your dialog fragment, that you call super.onRequestPermissionsResult there.

내 대화 조각의 부모 활동에서 onRequestPermissionsResult를 재정의했지만 거기에서 super 메서드를 호출하는 것을 무시했습니다. 수퍼 메서드를 호출하도록 변경하면 대화 조각의 onRequestPermissionsResult에 제대로 위임됩니다.

참조 URL : https://stackoverflow.com/questions/33169455/onrequestpermissionsresult-not-being-called-in-dialog-fragment

반응형