Tar*_*w45 6 android android-fragments android-permissions android-6.0-marshmallow
我有一个带有targetSdkVersion = 23的应用程序,compileSdkVersion = 23,主要活动设置如下
- HomeActivity (AppCompatActivity)
  - FragmentA (V4 Fragment)
    - ViewPager
      - NestedFragmentA (V4 Fragment)
      - NestedFragmentB (v4 Fragment)
      - NestedFragmentC (v4 Fragment)
      - NestedFragmentD (v4 Fragment)
  - Fragment B (V4 Fragment)
  - Fragment C (V4 Fragment)
在HomeActivity中
public static final String PERMISSION = Manifest.permission.WRITE_EXTERNAL_STORAGE
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    Log.i("Logger", "Request Code: " + String.valueOf(requestCode));
    // Handle permission request result
}
我从@CommonsWare读到这个答案,
嵌套片段中的onRequestPermissionsResult永远不会被调用(在我的情况下,它会返回HomeActivity)但我很好,我会手动通知结果片段.
但问题是,当我在HomeActivity中请求许可时,一切正常.
HomeActivity
// Request permission from HomeActivity
// Supply 101 as request code, get 101 back
@Override
public void clickSomething(View v) {
    requestPermissions(new String[]{PERMISSION}, 101);
}
// Logcat
Logger: Request Code: 101 <<< CORRECT
但是在FragmetnA或NestedFragmentA中,当我从嵌套片段请求时,返回HomeActivity的requestCode已更改
FragmentA
// Request permission from FragmentA
// Supply 102 as request code, get 358 back
@Override
public void clickAnotherThing(View v) {
    requestPermissions(new String[]{HomeActivity.PERMISSION}, 102);
}
// Logcat
Logger: Request Code: 358 <<< INCORRECT
NestedFragmentA
// Request permission from NestedFragmentA
// Supply 103 as request code, get 615 back
@Override
public void clickDifferentThing(View v) {
    requestPermissions(new String[]{HomeActivity.PERMISSION}, 103);
}
// Logcat
Logger: Request Code: 615 <<< INCORRECT
你知道什么会导致这个问题吗?
Sha*_*ari 15
我不会否定这个事实"Nested Fragments do not receive request permissions (onRequestPermissionsResult()) callback".
但我在这里要做的是解释你观察到的关于容器活动中收到的不同"怪异"请求代码的行为,这些代码requestPermissions()由片段和嵌套片段产生.
为了解释这个,让我们考虑你的例子 -
- HomeActivity (AppCompatActivity)
  - FragmentA (V4 Fragment)
    - ViewPager
      - NestedFragmentA (V4 Fragment)
      - NestedFragmentB (v4 Fragment)
      - NestedFragmentC (v4 Fragment)
      - NestedFragmentD (v4 Fragment)
  - Fragment B (V4 Fragment)
  - Fragment C (V4 Fragment)
onRequestPermissionsResult()仅为HomeActivity, FragmentA and NestedFragmentA了更好地理解打印收到的请求代码的日志而实施
    @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            Log.d("debug", "req code :: " + requestCode);     
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
还要求某些权限FragmentA和NestedFragmentA.我们来看一下位置权限
 requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 102); 
现在,无论何时我们requestPermissions()来自片段或嵌套片段,它都会调用Fragment class's requestPermissions()哪些调用依次调用FragmentHostCallback's onRequestPermissionsFromFragment()哪些片段FragmentActivity's requestPermissionsFromFragment().现在这里是您的请求代码的转换.验证您的请求代码后,它会调用
ActivityCompat's requestPermissions()
但
使用转换后的请求代码 -
ActivityCompat.requestPermissions(this, permissions,((fragment.mIndex + 1) << 8) + (requestCode & 0xff));
所以更改的请求代码是 -
((fragment.mIndex + 1) << 8) + (requestCode & 0xff)
fragment.mIndex片段级别在哪里.因此对于立即片段(直接意味着容器活动的子代),它将是"0"并且对于直接嵌套片段(意味着片段内的片段)它将是"1"并且它将根据深度增加你的片段是嵌套的.
在我们的例子中,for FragmentA,请求代码更改为
 (((0 + 1) << 8) + (102 & 0xff)) which computes to 358
并且NestedFragmentA,请求代码更改为
(((1 + 1) << 8) + (102 & 0xff)) which computes to 614
现在我们知道请求代码的变化.让我们继续吧   ActivityCompat.requestPermissions().因此我们知道,ActivityCompat.requestPermissions()因为我们使用此方法从活动请求权限.此外,我们知道这将执行一些操作,并且将向用户显示权限弹出窗口以接受/拒绝所请求的权限.
现在我们来了onRequestPermissionsResult().当用户接受/拒绝onRequestPermissionsResult()时,容器活动将被调用,因为最终ActivityCompat.requestPermissions()被调用.假设您接受/拒绝了许可,FragmentA那么您将获得日志 -
 req code ::358
之后
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
将调用FragmentActivity's onRequestPermissionsResult()哪个进而执行一些验证和调用
frag.onRequestPermissionsResult(requestCode&0xff, permissions, grantResults);
Bow你可以看到传入的请求代码frag.onRequestPermissionsResult()是不同的.requestCode为358以后&0xff就变成102  一次.瞧!! 这意味着虽然我们有不同的请求代码(358)HomeActivity's  onRequestPermissionsResult(),但我们FragmentA's onRequestPermissionsResult()使用原始请求代码调用(102)所以我们将从 - 获取这些日志FragmentA-
 req code ::358
现在来了NestedFragmentA.假设您接受/拒绝来自NestedFragmentA您的许可,您将获得登录HomeActivity-
 req code ::614
但我们知道onRequestPermissionsResult()不会为嵌套片段调用,所以我们不会得到任何登录NestedFragmentA's onRequestPermissionsResult()
我想我已经解释了为什么我们在容器活动中requestPermissions()获得由片段和嵌套片段产生的不同请求代码的原因.
所以我要说的是,对于那些不是requestPermissions()仅从片段嵌套   的片段,只onRequestPermissionsResult()在那里实现,而不是在容器活动中实现.对于嵌套片段,应该requestPermissions()  只为父片段中的嵌套片段所需的权限.这似乎是唯一的解决方法.
| 归档时间: | 
 | 
| 查看次数: | 1484 次 | 
| 最近记录: |