フラグメントとアクティビティの両方で定義されている場合、フラグメントでonRequestPermissionsResultが呼び出されない


167

recyclerviewアダプターを使用して、このrecyclerviewにrecyclerviewと設定データがあるフラグメントがあります。

これで、アダプターのリスト項目にボタンがあり、これをクリックして、AndroidのREAD_EXTERNAL_STORAGE権限を確認して、Androidの新しい権限モデルを確認します。

このアダプターのフラグメントに新しい機能を作成して、許可が付与されているかどうかを確認し、まだ付与されていない場合は許可を要求します。

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

ただし、このアクティビティのonRequestPermissionsResultメソッドが呼び出される代わりに、呼び出されません。

同じonRequestPermissionsResultメソッドをフラグメントの親アクティビティにも定義し、それが呼び出されています。

アクティビティのonRequestPermissionsResultメソッドを削除できませんが、フラグメントから許可をリクエストするときにフラグメントのonRequestPermissionsResultメソッドを呼び出したいです。これどうやってするの?私はここで何か悪いことをしていますか、誰かがここでアイデアを持っている場合は私を助けてください。


1
このリンクの実行時のアクセス許可をフラグメントで参照してくださいこれは正確な解決策です
アントニージャクソン

回答:


372

より広範な問題をカバーするように回答を編集

フラグメントとアクティビティの方法がわかりにくいと思います。先月、私のプロジェクトに同様の問題がありました。最後に次のことを確認してください。

  1. AppCompatActivityでは、メソッドActivityCompat.requestpermissionsを使用します
  2. v4サポートフラグメントでは、requestpermissionsを使用する必要があります
  3. キャッチは、フラグメントでAppcompatActivity.requestpermissionsを呼び出した場合、コールバックはフラグメントではなくアクティビティになります
  4. super.onRequestPermissionsResultアクティビティのから必ず呼び出してくださいonRequestPermissionsResult

それが役立つかどうかを確認してください。


9
もう一度確認して、アクティビティにsuper.onrequestpermissionresultが設定されていることを確認してください
VarunJoshi129

27
super.onrequestpermissionresult使用して許可を要求すると、アクティビティのonrequestpermissionresultを追加すると、フラグメントのonrequestpermissionresultが呼び出されrequestpermissionsます。これで問題なく動作します。ありがとうございました。:)
Prithniraj Nicyone 2016年

1
super.onrequestpermissionresultがアクティビティコールバックにないため、フラグメントコールバックが呼び出されませんでした
sakis kaliakoudas

4
requestPermissions()にはAPIレベル23が必要です。APIレベル21に対して下位互換性のある別のソリューションはありますか?
Adam Hurwitz、2017

2
@ msc87 1.アクティビティとフラグメントのonRequestPermissionsResultでは、最初の行は次のようになります。 2.許可されていないアクセス許可を認識しているフラグメントでは、次のようにrequestPermissionメソッドを呼び出すだけです。
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 '29

1
Kotlinで動作していません。同じようにここで私を助けてください。このrequestPermissions(context as Activity、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から非推奨になりました
Raj

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がアクティビティ内にある場合に使用します。
RoarGrø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 2016

最初に長さをチェックせずにgrantResultsのインデックス0にアクセスしようとすると、プログラムは配列の範囲外の例外をスローする場合があります。それは私のプログラムに起こりました。これを防ぐために、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");
        }
}

2.そして、その基礎となる活動からそれを呼び出しました:

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

そしてそれは働いています...



0

tragetSDK 28の場合、SDKチェック(> 23)およびフラグメントからのrequestpermissionsが機能します。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を拡張しており、HostedFragmentはCompatFragmentを拡張しています。これらのネストされたフラグメントがあると問題が発生し、最終的にプロジェクトの他の開発者によって解決されました。

彼はこれを機能させるためにビット切り替えのようないくつかの低レベルのことをしていたので、実際の最終的な解決策はよくわかりません


3
-代わりに答えをコピーするのは、あなただけのリンクを提供できstackoverflow.com/a/33081173/630833
jayeffkay
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.