프래그먼트와 액티비티 모두에 정의 된 경우 onRequestPermissionsResult가 프래그먼트에서 호출되지 않습니다


167

recyclerview 어댑터를 사용하여 recyclerview를 가지고이 recyclerview에서 데이터를 설정하는 조각이 있습니다.

이제 어댑터의 목록 항목에 버튼이있어 Android의 새 권한 모델에 대해 Android의 READ_EXTERNAL_STORAGE 권한을 확인해야합니다.

이 어댑터의 조각에서 권한이 부여되었는지 여부를 확인하고 권한이 아직 부여되지 않은 경우 권한을 요청하기 위해 새 기능을 만들었습니다.

어댑터의 매개 변수로 MyFragment.this를 전달하고 어댑터에서 버튼 클릭으로 조각의 메소드를 호출합니다.

아래 코드를 사용하여 조각으로 requestPermission을 호출했습니다.

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

onRequestPermissionsResult아래 코드를 사용하여 조각 의 메서드를 재정의했습니다 .

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

그러나이 Activity의 onRequestPermissionsResult 메소드가 호출되는 대신 호출되지 않습니다.

조각의 부모 활동에서도 동일한 onRequestPermissionsResult 메소드를 정의했으며 호출되고 있습니다.

활동의 onRequestPermissionsResult 메소드를 제거 할 수 없지만 프래그먼트에서 권한을 요청할 때 프래그먼트의 onRequestPermissionsResult 메소드를 호출하려고합니다. 어떻게해야합니까? 내가 여기서 뭔가 잘못하고 있습니까, 누군가 여기에 아이디어가 있으면 도와주세요.


1
이 링크 런타임 권한을 조각으로 참조 이것은 정확한 해결책입니다
Antony jackson

답변:


372

광범위한 문제를 다루기 위해 수정 된 답변

조각과 활동에 대한 방법을 혼란스럽게 생각합니다. 지난 달에 비슷한 문제가 발생했습니다. 마지막으로 다음 사항이 있는지 확인하십시오.

  1. AppCompatActivity에서 ActivityCompat.requestpermissions 메소드를 사용하십시오.
  2. v4 지원 단편에서는 requestpermissions 를 사용해야합니다.
  3. 캐치는 조각에서 AppcompatActivity.requestpermissions를 호출하면 콜백이 조각화되지 않고 활동하게됩니다.
  4. super.onRequestPermissionsResult액티비티의에서 전화해야합니다 onRequestPermissionsResult.

도움이되는지 확인하십시오.



27
super.onrequestpermissionresult활동의 onrequestpermissionresult를 추가하면 을 사용하여 권한을 요청할 때 조각의 onrequestpermissionresult를 호출합니다 requestpermissions. 이것은 지금 잘 작동하고 있습니다, 정말 고마워요 .. :)
Prithniraj Nicyone 2016 년

1
super.onrequestpermissionresult 호출하기 나의 조각 콜백 선도 활동 콜백에서 누락 된
sakis kaliakoudas

4
requestPermissions () 에는 API 레벨 23이 필요합니다. API 레벨 21과 호환되는 다른 솔루션이 있습니까?
Adam Hurwitz

2
@ msc87 1. 활동 및 프래그먼트의 onRequestPermissionsResult에서 첫 번째 행은 다음과 같아야합니다. super.onRequestPermissionsResult (requestCode, permissions, grantResults); 권한이 인식되지 않은 조각에서 다음과 같이 requestPermission 메소드를 호출하십시오. requestPermissions (new String [] {Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE);
AREF

122

조각과 조각에서 위치 권한을 요청했는데 이것을 변경해야했습니다.

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

이에:

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

그런 다음 조각에서 onRequestPermissionsResult가 호출되었습니다.


2
매력처럼 작동 :)
Antonio Vlasic

1
이 코 틀린와 함께 작동하지 않습니다이 사용됩니다 여기에 같은 도움을 나를 기쁘게 할 수 requestPermissions (활동과 같은 상황을 permissionList.toTypedArray (), MY_PERMISSIONS_REQUEST)
Arbaz.in

감사합니다 :), 당신은 내 시간을 절약
Axrorxo'ja Yodgorov

19

이것은 사람들이 마쉬멜로를 코딩 할 때 흔히 저지르는 실수입니다.

AppCompatActivity에있을 때는 ActivityCompat.requestPermissions를 사용해야합니다. android.support.v4.app.Fragment에있는 경우 간단히 requestPermissions를 사용해야합니다 (이는 android.support.v4.app.Fragment의 인스턴스 메소드입니다). 조각에서 ActivityCompat.requestPermissions를 호출하면 onRequestPermissionsResult 콜백이 호출됩니다. 조각이 아닌 활동.

requestPermissions(permissions, PERMISSIONS_CODE);

프래그먼트에서이 코드를 호출하는 경우 고유 한 requestPermissions 메소드가 있습니다.

기본 개념은, 당신이 활동에 있다면, 전화

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

조각에 있다면 전화하십시오.

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

참고 로이 링크 https://www.coderzheaven.com/2016/10/12/onrequestpermissionsresult-not-called-on-fragments/ 에서 답변을 얻었습니다.


6

requestPermissionsFragments 의 메소드 에는 API 레벨 23 이상이 필요합니다.
앱이 더 낮은 버전을 대상으로하는 경우 사용할 수 있습니다

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

먼저 support-v13 종속성을 추가해야합니다.

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

FragmentCompat 버전 27.1.0에서 사용되지 않습니다
라즈 Kannan은 Iyyappan을

6

이것을 바꾸십시오 :

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

이에 :

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

아래쪽은 조각에서 사용하기위한 것이고 (onRequestPermissionsResult는 조각으로 호출 됨) ActivityCompat 버전은 onRequestPermissionsResult가 Activity에 위치 할 때 사용하기위한 것입니다.
포효 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();
 }
 }

허가 변경


2
안녕하세요 user2002721; 코드가 정확할 수도 있지만 일부 상황에서는 더 나은 답변을 얻을 수 있습니다. 예를 들어,이 제안 된 변경으로 인해 관련 문서에 대한 링크를 포함하여 질문자의 문제를 해결하는 방법과 이유를 설명 할 수 있습니다. 그것은 그들에게 더 유용 할 것이며, 비슷한 문제에 대한 해결책을 찾고있는 다른 사이트 독자들에게도 더 유용 할 것입니다.
Vince Bowdren

먼저 길이를 확인하지 않고 grantResults의 인덱스 0에 액세스하려고하면 프로그램이 범위를 벗어난 예외를 throw 할 수 있습니다. 내 프로그램에 일어났다. grantResults의 if 문을 내부 if 문으로 분리하여 문제가 발생하지 않도록 막았습니다. 이제 잘 작동합니다.
피터 그리핀

1

이 받아 들인 대답은 나를 위해 작동하지 않으므로 아래에서 설명하는 내 솔루션을 찾았습니다.

1. 먼저 조각으로 메서드를 만들었습니다.

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

그런 다음 기본 활동에서 호출했습니다.

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

그리고 그것은 작동하고 있습니다 ...


0

모두 있는지 확인 PERMISSION_REQUEST_CODEonRequestPermissionsResult와 내부에 Fragment같은 값을 포함합니다.


0

tragetSDK 28의 경우 SDK 확인 (> 23) 및 조각의 요청 권한이 작동합니다. ActivityCompat.requestPermissions가 실패합니다 (요청 코드를 65536 미만으로 설정하면 권한 대화 상자가 나타나고 사용자가 권한을 허용하면 권한이 제공되지만 콜백은 발생하지 않지만 65536 이상으로 설정하면 ActivityCompat.requestPermissions가 즉시 실패합니다.이 논리의 이유를 모르겠습니다. 버그이거나 의도적 일 수 있습니다.

작업 코드 :

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

버전 확인을 수행 할 필요가 없습니다. 23 이하 버전에서는 '허가 부여'값만 반환합니다. 여기에서 개발자의 선택 : 단순성을 위해 'if'블록을 피하거나 필요하지 않은 경우 요청 호출을 피하십시오
Psest328


0

나는 같은 문제가 있었다. 활동 레이아웃에서 조각을 초기화 할 수 있습니다. 그렇게 :

main_activty.xml

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

이 문제는 FragmentTransaction대신 사용했을 때 해결되었습니다.


0

23 이하의 API에서는 액티비티에 인터페이스를 생성 한 다음 자식 프래그먼트에서 인터페이스를 구현할 수 있으며 권한 요청을 받으면 액티비티에서 결과를 프래그먼트의 구현 된 인터페이스로 전달합니다. 이 간단한 :)


0

아래의 Fragment 메소드를 호출 할 수 있습니다

@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

이 문제는 실제로 NestedFragments로 인해 발생했습니다. 기본적으로 대부분의 프래그먼트는 HostedFragment를 확장하여 CompatFragment를 확장합니다. 이러한 중첩 된 조각으로 인해 프로젝트의 다른 개발자가 문제를 해결했습니다.

그는 비트 스위칭과 같은 저수준 작업을 수행 하여이 작업을 수행 했으므로 실제 최종 솔루션을 너무 확신하지 못합니다.


3
답변을 복사하는 대신 링크를 제공하면됩니다.- stackoverflow.com
a
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.