Java 从 v4.Fragment 请求运行时权限并让回调转到 Fragment?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32890702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 13:59:49  来源:igfitidea点击:

Request runtime permissions from v4.Fragment and have callback go to Fragment?

javaandroidandroid-fragmentsandroid-6.0-marshmallow

提问by RED_

I'm having a weird issue that is causing a conflict. I had to switch to native Fragmentsto fix it, but there are bugs with that.

我遇到了一个导致冲突的奇怪问题。我不得不切换到本机Fragments来修复它,但有一些错误。

My original problem: I have a navigation drawer setup with v4 Fragments.To ask for permission in one of my Fragments I call ActivityCompat.requestPermissions(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, 1);The prompt shows up just fine, but when I accept or deny the permission, nothing happens. The callback onRequestPermissionsResult()is never called. Instead it gets called in the Activity that my Fragments are attached to. Useless to me, I need the callback to work in the Fragment.

我的原始问题:我有一个导航抽屉设置,v4 Fragments.在我调用ActivityCompat.requestPermissions(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, 1);的其中一个片段中请求许可提示显示得很好,但是当我接受或拒绝许可时,没有任何反应。onRequestPermissionsResult()永远不会调用回调。相反,它在我的 Fragments 附加到的 Activity 中被调用。对我没用,我需要回调才能在 Fragment 中工作。

With this in mind I was told that I need to use FragmentCompat, but that only works with native Fragments (v13+), so I changed navigation drawer to work from native Fragments instead of the v4 support library Fragments. However, because I'm using AppCompatActivity, certain things do not work, like addToBackStack()and going back to a previous fragment.

考虑到这一点,我被告知我需要使用FragmentCompat,但这仅适用于native Fragments (v13+),因此我将导航抽屉更改为使用本机 Fragments 而不是 v4 支持库 Fragments。但是,因为我正在使用 AppCompatActivity,所以某些事情不起作用,例如addToBackStack()并返回到前一个片段。

Long story short, does anyone know how I can use the v4.Fragmentand still call for permission in the Fragmentand get the callback to be in the Fragment? I feel like this is a bug in Android that hasn't been addressed but I'm not 100%.

长话短说,有谁知道我如何使用v4.Fragment并且仍然在 中请求许可并在 中Fragment获得回调Fragment?我觉得这是 Android 中的一个尚未解决的错误,但我不是 100%。

Let me know if you need to see my code, it's just the standard methods that you need for runtime permissions, I would like to work with v4 Fragments though which doesn't work from my understanding.

如果您需要查看我的代码,请告诉我,这只是运行时权限所需的标准方法,我想使用 v4 Fragments 尽管根据我的理解这不起作用。

采纳答案by NasaGeek

This behavior seems to be present in the v4 Fragment support class requestPermissions in Fragment. The Activity/FragmentCompat implementations exist for people who wish to use the native classes with the extended functionality on API levels between 11 and 23.

这种行为似乎存在于 Fragment 中的 v4 Fragment 支持类requestPermissions 中。Activity/FragmentCompat 实现适用于希望在 11 到 23 之间的 API 级别上使用具有扩展功能的本机类的人。

回答by Nitesh Mudireddy

I faced the same situation recently, when I needed to check for a permission inside the support fragment and get a callback there.

我最近遇到了同样的情况,当我需要检查支持片段中的权限并在那里获得回调时。

I was able to use ContextCompatto checkSelfPermissionand then as @NasaGeek said called android.support.v4.app.Fragment's requestPermissionsto request the permission and then got a call back to onRequestPermissionsResultin v4 Fragment.

我能够使用ContextCompattocheckSelfPermission然后正如@NasaGeek 所说的那样调用android.support.v4.app.Fragment'srequestPermissions来请求许可,然后onRequestPermissionsResult在 v4 Fragment 中收到回电。

Hope this helps.

希望这可以帮助。

Thanks.

谢谢。

回答by android_dev

v4.Fragment works well. I have an issue with nested fragment of v4.Fragment. Permission is asked, but the callback onRequestPermissionsResult() is never called in nested fragment!

v4.Fragment 运行良好。我有 v4.Fragment 的嵌套片段问题。请求权限,但回调 onRequestPermissionsResult() 永远不会在嵌套片段中调用!

Issue opened

问题已打开

回答by Szymon Klimaszewski

At the moment the most stable solution is doing it by hand. I myself resolved it simply by notifying child fragments from the parent fragments.

目前最稳定的解决方案是手工完成。我自己只是通过从父片段通知子片段来解决它。

if (fragment.getParentFragment() != null) {
                            Fragment parentFragment = fragment.getParentFragment();
                            try {
                                ChildFragmentPermissionRegistry registry = (ChildFragmentPermissionRegistry) parentFragment;
                                registry.registerPermissionListener((ChildFragmentPermissionCallback) fragment);
                                parentFragment.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
                            } catch (ClassCastException e) {
                                Log.e(PermissionVerifier.class.getSimpleName(), e.getMessage());
                            }
                        } else {
                            fragment.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
                        }

Where parent fragment implements interface ChildFragmentPermissionRegistry and registers child fragment,

其中父片段实现接口 ChildFragmentPermissionRegistry 并注册子片段,

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (callback != null) {
        callback.onRequestPermissionsResult(requestCode, permissions, grantResults);
        callback = null;
    }
}

and child fragments implements ChildFragmentPermissionCallback

和子片段实现 ChildFragmentPermissionCallback

and interfaces are something like this:

和接口是这样的:

public interface ChildFragmentPermissionCallback {
    void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);
}

public interface ChildFragmentPermissionRegistry {
    void registerPermissionListener(ChildFragmentPermissionCallback callback);
}

回答by Samuel Gaona

Adding this to the parent activity works for me:

将此添加到父活动对我有用:

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

Source: https://code.google.com/p/android/issues/detail?id=189121#c5

来源:https: //code.google.com/p/android/issues/detail?id=189121#c5

回答by Abubakar

You can use this part of code

你可以使用这部分代码

requestPermissions(new String[]{Manifest.permission.GET_ACCOUNTS}, PERMISSION_REQUEST_CODE);

回答by DoruChidean

If you need to get the permissionResult in fragment v4make sure you use

如果您需要获得permissionResult,请fragment v4确保您使用

Fragment.requestPermission(String[], int);

instead of

代替

AppCompat.requestPermission(Activity, String[], int)

Check out thisanswer!

看看这个答案!

回答by Andrew Coder

Just use requestPermission("your permission/s in string array",your request code) simply no need to use Fragment.requestPermissons(String[],int );

只需使用 requestPermission("your permission/s in string array",your request code) 根本不需要使用 Fragment.requestPermissons(String[],int );

This method in your fragment calls requestPermissions of android.support.v4.app.Fragment class i.e

您片段中的此方法调用 requestPermissions android.support.v4.app.Fragment class i.e

public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
        if (mHost == null) {
            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
        }
        mHost.onRequestPermissionsFromFragment(this, permissions, requestCode);
    }

回答by YunhaoLIU

I don't know if it's recently fixed by google, but I can reach the expected result without doing any tricks.

我不知道它最近是否被谷歌修复了,但我可以在不做任何技巧的情况下达到预期的结果。

The most important thing is to call super.onRequestPermissionsResult(requestCode, permissions, grantResults);in the activity, so it will pass the result to fragment if it's requested from fragment.

最重要的是super.onRequestPermissionsResult(requestCode, permissions, grantResults);在活动中调用 ,因此如果从片段请求结果,它会将结果传递给片段。

So, what I do is:

所以,我要做的是:

1) in fragment, ask permission using v4 fragment.requestPermissions(permissions, requestCode)

1)在片段中,使用请求许可 v4 fragment.requestPermissions(permissions, requestCode)

2) in activity's onRequestPermissionsResult, must call super.onRequestPermissionsResult(requestCode, permissions, grantResults);

2) 在活动的 onRequestPermissionsResult 中,必须调用 super.onRequestPermissionsResult(requestCode, permissions, grantResults);

3) in fragment's onRequestPermissionsResult, write the code I want to handle the result.

3)在fragment的onRequestPermissionsResult中,写出我想要处理结果的代码。

回答by Aleksey Timoshchenko

In my case I have requested the permission from the fragment and also need to get the response in fragment.

在我的情况下,我已请求片段的许可,并且还需要在片段中获得响应。

But my phone running on android 8.1

但是我的手机运行在 android 8.1 上

so I was need to add one more condition for check this

所以我需要再添加一个条件来检查这个

so eventually there is my solution

所以最终有我的解决方案

private void doOnWazeButtonClick()
{
    int permissionStatus = PackageManager.PERMISSION_DENIED;

    if (getContext() != null)
    {
        permissionStatus = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION);
    }

    if (permissionStatus == PackageManager.PERMISSION_GRANTED)
    {
        showContentWaze();
    }
    else
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        {
            Objects.requireNonNull(getActivity()).requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION);
        }
        else
        {
            requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION);
        }
    }
}