Android处理来自不同来源的同时权限

3

我正在尝试同时请求来自多个来源的多个权限。我的问题是只有一个权限被请求。

以下是一个例子:

我们有两个片段在MainActivity上同时加载,例如

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.myapplication.MainActivity"
    android:orientation="vertical">

    <fragment android:name="com.example.myapplication.fragments.FragmentOne"
        android:id="@+id/fragment_one"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <fragment android:name="com.example.myapplication.fragments.FragmentTwo"
        android:id="@+id/fragment_two"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

我们有一个名为 FragmentOne 的组件,它申请了读取通话记录的权限(READ_CALL_LOG),例如:
@Override
public void onStart() {
    super.onStart();
    Log.d(TAG, "onStart: ");
    requestPermissions(new String[]{Manifest.permission.READ_CALL_LOG}, 1);
}

我们还有一个名为FragmentTwo的功能,它请求读取联系人操作,例如:

@Override
public void onStart() {
    super.onStart();
    Log.d(TAG, "onStart: ");
    requestPermissions(new String[] { Manifest.permission.READ_CONTACTS }, 2);
}

这意味着应用程序启动时,会创建并启动2个片段。随即这两个片段同时请求权限。我的问题是只有第一个权限会提示用户。为了解决这个问题,我在每个片段的onRequestPermissionsResult中添加了一些日志,例如:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    Log.d(TAG, "onRequestPermissionsResult: requestCode=" + requestCode + " permissions=" + permissions
            + " permissions.length=" + permissions.length + " grantResults.length=" + grantResults.length);
    for (String permission : permissions) {
        Log.d(TAG, "onRequestPermissionsResult: permission=" + permission);
    }
}

我找到了问题所在,但是还没有解决方案。当我查看日志时,只要启动应用程序,就会出现以下日志:

2017-05-02 13:22:40:0356    + 677   05-02 13:22:38.650 27003 27003 D FragmentOne: onStart:
2017-05-02 13:22:40:0357    + 699   05-02 13:22:38.661 27003 27003 D FragmentTwo: onStart:
2017-05-02 13:22:40:0357    + 702   05-02 13:22:38.661 27003 27003 D FragmentTwo: onRequestPermissionsResult: requestCode=2 permissions=[Ljava.lang.String;@afbcb45 permissions.length=0 grantResults.length=0

同时,要求读取通话记录的对话框出现了。

这里的问题似乎是它太早进入了onRequestPermissionsResult方法。

只要我从对话框中接受了读取通话记录权限,我就会得到2个新的日志。

2017-05-02 13:27:42:0017    + 2803  05-02 13:27:40.358 27003 27003 D FragmentOne: onRequestPermissionsResult: requestCode=1 permissions=[Ljava.lang.String;@5028ba8 permissions.length=1 grantResults.length=1
2017-05-02 13:27:42:0017    + 2804  05-02 13:27:40.358 27003 27003 D FragmentOne: onRequestPermissionsResult: permission=android.permission.READ_CALL_LOG

这时,我期望出现第二个权限对话框(READ_CONTACTS),但它并未显示。之后也没有生成任何其他日志。

我知道我可以从不同的片段中获取所有权限,并通过传递相关的字符串数组同时提示它们。但这不是我想要实现的目标,我想让多个组件处理它们自己的权限。

我是否遗漏了什么?我做错了什么吗?

为了参考,我在此放置MainActivity和FragmentOne的完整代码。FragmentTwo基本上是相同的(只有标签和权限更改不同)。

MainActivity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

碎片一:

public class FragmentOne extends Fragment {

    private static final String TAG = "FragmentOne";

    public FragmentOne() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_fragment_one, container, false);
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart: ");
        requestPermissions(new String[]{Manifest.permission.READ_CALL_LOG}, 1);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        Log.d(TAG, "onRequestPermissionsResult: requestCode=" + requestCode + " permissions=" + permissions
                + " permissions.length=" + permissions.length + " grantResults.length=" + grantResults.length);
        for (String permission : permissions) {
            Log.d(TAG, "onRequestPermissionsResult: permission=" + permission);
        }
    }
}
1个回答

0
尝试将权限请求放置在活动中而非片段中,并同时请求两个权限。 问题似乎在于,当您请求第二个权限时,第一个对话框会关闭,因此被视为已拒绝。

这最终是我所做的。但它并没有解决实际问题。问题在于权限在片段中似乎没有被正确处理。或者至少,只有在单个时间运行需要权限的单个片段时才会处理。我觉得很奇怪Fragment提供了requestPermissions方法,如果它不能正确处理多个片段。 - Charles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接