从v4.Fragment请求运行时权限,并callback到Fragment?

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

我原来的问题:我有一个导航抽屉设置与v4 Fragments. 要求我的片段之一的权限,我打电话给ActivityCompat.requestPermissions(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, 1); 提示显示正常,但是当我接受或拒绝这个权限时,什么也没有发生。 callback函数onRequestPermissionsResult()永远不会被调用。 相反,它会在我的碎片附加到的活动中被调用。 对我无用,我需要callback才能在片段中工作。

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

长话短说,有没有人知道我可以如何使用v4.Fragment并仍然要求在Fragment权限,并获得在Fragment的callback? 我觉得这是Android的一个错误,但没有得到解决,但我不是100%。

让我知道如果你需要看我的代码,这只是你需要运行时权限的标准方法,我想使用v4碎片,尽pipe这不工作,从我的理解。

这种行为似乎在v4 Fragment支持类[ 1 ]中出现。 Activity / FragmentCompat实现存在于希望在11到23之间的API级别上使用具有扩展function的本地类的人。

将此添加到父项目对我来说是有效的:

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

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

如果你需要得到fragment v4的permissionResult,请确保你使用

 Fragment.requestPermission(String[], int); 

代替

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

看看这个答案!

你可以使用这部分代码

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

我最近面临同样的情况,当我需要检查支持片段内的许可,并在那里得到callback。

我能够使用ContextCompat checkSelfPermission ,然后作为@NasaGeek说,调用android.support.v4.app.FragmentrequestPermissions来请求权限,然后在v4 Fragment中得到一个callbackonRequestPermissionsResult

希望这可以帮助。

谢谢。

v4.Fragment运作良好。 我有一个v4.Fragment的嵌套片段的问题。 权限被问到,但callbackonRequestPermissionsResult()永远不会调用嵌套片段!

问题已打开

目前最稳定的解决scheme是手工完成的。 我自己解决它简单地通过从父片段通知子片段。

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

在父节点实现接口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; } } 

和子片段实现ChildFragmentPermissionCallback

和接口是这样的:

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

只要使用requestPermission(“你的权限/ s在string数组”,你的请求代码)根本就不需要使用Fragment.requestPermissons(String[],int );

在你的片段中的这个方法调用android.support.v4.app.Fragment class ie requestPermissions android.support.v4.app.Fragment class ie

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