了解Android 6权限方法

2023-12-09

我试图从图库中获取图像并将其设置为图像视图,但在 Android 6 中存在一些权限问题。以下是请求许可的方法。我应该要求读取外部存储还是写入外部存储?

这是我到目前为止所做的:

    private static final int READ_CONTACTS_PERMISSIONS_REQUEST = 1;


    public void getPermissionToReadExternalStorage() {

    if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {

        if (shouldShowRequestPermissionRationale(
                Manifest.permission.READ_EXTERNAL_STORAGE)) {

            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    READ_CONTACTS_PERMISSIONS_REQUEST);
        }}}
    @Override
            public void onRequestPermissionsResult(int requestCode,
                                                   @NonNull String permissions[],
                                                   @NonNull int[] grantResults){
                // Make sure it's our original READ_CONTACTS request
                if (requestCode == READ_CONTACTS_PERMISSIONS_REQUEST) {
                    if (grantResults.length == 1 &&
                            grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        Toast.makeText(getActivity(), "Read Contacts permission granted", Toast.LENGTH_SHORT).show();

                    } else {
                        Toast.makeText(getActivity(), "Read Contacts permission denied", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                }
            }

现在我的点击侦听器从图库中选取数据:

     pro.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            intent.setType("image/*");
            if (android.os.Build.VERSION.SDK_INT >= 23) {
                getPermissionToReadExternalStorage();
                if (getPermissionToReadExternalStorage () this???? <==)
                startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0);
            } else {
                startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0);
        }}

    });
    return v;
}

现在我想得到该方法的结果getPermissionToReadExternalStorage()这样我就可以启动Android 6的挑选画廊的活动。如何获得void类的结果? 另一件事是我是否必须为我的应用程序要求的每个权限编写方法?


所以我完全重写了请求权限的代码。 现在它支持请求多个权限并运行代码并获得正确的结果。 它还适用于 preMarshmallow 设备,因此在这种情况下您不必检查和复制代码。

首先,使用以下代码创建一个 Activity 类(您可以扩展您需要的任何 Activity 类,例如 AppCompatActivity):

public abstract class PermissionActivity extends AppCompatActivity {

    private final ArrayList<PermissionListener> permissionListeners = new ArrayList<>();

    @SuppressWarnings("unused")
    public void requestPermissions(int requestCode, String[] requestPermissions, PermissionListener permissionListener) {
        requestPermissions(requestCode, requestPermissions, null, permissionListener);
    }

    @SuppressWarnings("unused")
    public void requestPermissions(final int requestCode, String[] requestPermissions, String message, final PermissionListener permissionListener) {
        final int[] grantResults = new int[requestPermissions.length];

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ArrayList<String> list_notGranted = new ArrayList<>();

            for (String requestPermission : requestPermissions)
                if (ContextCompat.checkSelfPermission(this, requestPermission) != PackageManager.PERMISSION_GRANTED)
                    list_notGranted.add(requestPermission);

            if (list_notGranted.size() > 0) {
                permissionListeners.add(permissionListener);

                requestPermissions = list_notGranted.toArray(new String[list_notGranted.size()]);

                if (message != null) {
                    boolean shouldShowRequestPermissionRationale = false;

                    for (String permission : requestPermissions)
                        if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
                            shouldShowRequestPermissionRationale = true;
                            break;
                        }

                    if (shouldShowRequestPermissionRationale) {
                        final String[] f_requestPermissions = requestPermissions;

                        AlertDialog.Builder builder = new AlertDialog.Builder(this);

                        builder.setMessage(message);

                        DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {

                            @TargetApi(Build.VERSION_CODES.M)
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                switch (which) {
                                    case DialogInterface.BUTTON_POSITIVE:
                                        PermissionActivity.super.requestPermissions(f_requestPermissions, requestCode);
                                        break;
                                    default:
                                        for (int i = 0; i < grantResults.length; i++)
                                            grantResults[i] = PackageManager.PERMISSION_DENIED;

                                        if (permissionListener != null)
                                            permissionListener.onResult(requestCode, f_requestPermissions, grantResults);
                                        break;
                                }
                            }
                        };

                        builder.setPositiveButton("OK", onClickListener);
                        builder.setNegativeButton("Cancel", onClickListener);

                        builder.show();
                    } else {
                        super.requestPermissions(requestPermissions, requestCode);
                    }
                } else {
                    super.requestPermissions(requestPermissions, requestCode);
                }
            } else {
                for (int i = 0; i < grantResults.length; i++)
                    grantResults[i] = PackageManager.PERMISSION_GRANTED;

                if (permissionListener != null)
                    permissionListener.onResult(requestCode, requestPermissions, grantResults);
            }
        } else {
            if (permissionListener != null) {
                for (int i = 0; i < grantResults.length; i++)
                    grantResults[i] = PackageManager.PERMISSION_GRANTED;

                permissionListener.onResult(requestCode, requestPermissions, grantResults);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
        for (Iterator<PermissionListener> it = permissionListeners.iterator(); it.hasNext(); ) {
            PermissionListener permissionListener = it.next();
            if (permissionListener.onResult(requestCode, permissions, grantResults)) {
                it.remove();
            }
        }
    }

    public interface PermissionListener {

        boolean onResult(int requestCode, String[] requestPermissions, int[] grantResults);

    }
}

如果要向 Fragments 请求权限,请添加此类:

public class PermissionFragment extends Fragment {

    @SuppressWarnings("unused")
    public void requestPermissions(int requestCode, String[] requestPermissions, PermissionActivity.PermissionListener permissionListener) {
        requestPermissions(requestCode, requestPermissions, null, permissionListener);
    }

    @SuppressWarnings("unused")
    public void requestPermissions(final int requestCode, String[] requestPermissions, String message, PermissionActivity.PermissionListener permissionListener) {
        ((PermissionActivity) getActivity()).requestPermissions(requestCode, requestPermissions, message, permissionListener);
    }
}

您的活动和片段应该扩展这些类而不是标准类。

现在您可以通过调用方法来请求权限:

requestPermissions(int requestCode, String[] requestPermissions, PermissionListener permissionListener)

如果应用程序需要该权限才能运行,您应该调用此方法并指定消息说明为什么需要该权限。

requestPermissions(int requestCode, String[] requestPermissions, String message, PermissionListener permissionListener)

不要错过调用默认方法,即

// DON'T USE THIS ONE!
requestPermissions(String[] requestPermissions, int requestCode)
// DON'T USE THIS ONE!

以下是请求联系人的示例:

private void requestAndLoadContacts() {
    String[] permissions = new String[]{Manifest.permission.READ_CONTACTS};

    requestPermissions(REQUEST_PERMISSIONS_CONTACTS, permissions, "Read contacts permission is required for the app to work!", new PermissionListener() {

        @Override
        public boolean onResult(int requestCode, String[] requestPermissions, int[] grantResults) {
            // Check if the requestCode is ours
            if (requestCode == REQUEST_PERMISSIONS_CONTACTS) {
                // Check if the permission is correct and is granted
                if (requestPermissions[0].equals(Manifest.permission.READ_CONTACTS) && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Permission granted
                    // Calling a method to actually load the contacts
                    loadContacts();
                } else {
                    // Permission not granted
                    Toast.makeText(MainActivity.this, "Access denied!", Toast.LENGTH_SHORT).show();
                }

                return true;
            }

            return false;
        }
    });
}

笔记: 当你实现 PermissionListener 时,不要忘记返回真当。。。的时候requestCode 是正确的,否则 PermissionListener不会被删除从 ArrayList 中,您很可能会遇到小的内存泄漏。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解Android 6权限方法 的相关文章

随机推荐

  • 在 catch 块中等待

    我有以下代码 WebClient wc new WebClient string result try result await wc DownloadStringTaskAsync new Uri http badurl catch re
  • css半边框圆,上面有透明形状

    我需要一个从底部开始有半边框的圆圈 我想按百分比用颜色填充这个圆圈 我需要在上面放另一个圆圈 但另一个圆圈的中心有一个透明的形状 首先 我需要一个带有半边框的圆圈 然后在其上放另一个具有透明形状的圆圈 有没有更简单的方法 例如使用画布 Wh
  • 我可以在独立项目中使用 android.os.* 库吗?

    我正在尝试开发一个外部库 不确定这是否是正确的术语 来在 Android 项目中提供预打包的功能 在 Eclipse 中工作 我已将适当的 android jar 文件添加到构建路径中 并且在编辑和编译时一切都很顺利 但是 当我使用 And
  • 是否可以通过 nightwatch.js 设置元素的 Style 属性值?如果是的话怎么办?

    我正在使用 nightwatch js 我对这个自动化测试还很陌生 我想通过 nightwatch js 将值设置到元素的 style 属性中 所以我问 这可能吗 如果可能的话我们如何实现它 我可以访问样式属性值 并可以通过以下 night
  • 全局节点模块安装不正确。找不到命令

    我在安装全局节点模块时遇到问题 我在网上找到的所有内容都说解决方法只是添加 g 这不是问题 我认为这是链接问题或错误的目录问题 这是我所做的 npm install g express npm http GET https registry
  • 单行无限分离循环的语法

    我可以像这样无限循环地运行一些东西 while true do foo done 我可以像这样运行一些独立的东西 foo 但我不能像这样在无限循环中运行分离的东西 while true do foo done bash syntax err
  • 通过远程 java 独立应用程序使用 EJB 3.1 bean

    我一直在尝试使用 Java EE 6 创建一个基于应用程序服务器的应用程序 该应用程序从 GWT Web 应用程序接收作业对象 并且这些作业将从 Java 独立应用程序中提取 我一直认为 EJB 模型将为我提供一种简单的远程处理方法 因为我
  • 如何在 Spring-Batch 中使用 ItemReader 跳行?

    我有一个自定义项目阅读器 可以将文本文件中的行转换为我的实体 public class EntityItemReader extends AbstractItemStreamItemReader
  • RegEx 字符串,12 个符号(至少 1 个数字和至少 1 个字母)

    我在使用正则表达式时遇到问题 如何获取至少包含 1 个数字和 1 个字母的字符串的 12 个符号长部分 例子 这有 12 个符号长 F8ENL83I0E12也许还有更多文字 要在较长的文本中查找长度为 12 的字母数字单词 请使用 i Ca
  • 如何快速编写这段代码?

    我用 Objective c 编写了这段代码 NSRect textRect NSMakeRect 42 35 117 55 NSString textContent Hello World NSMutableParagraphStyle
  • AVAudioPlayer 在模拟器上工作但在真实设备上不工作

    当我播放录制的音频时 出现此错误 致命错误 在解包可选值时意外发现 nil 在这行代码上 SoundPlayer try AVAudioPlayer contentsOfURL getFileURL 但它在除真实设备之外的模拟器上运行良好
  • Rails 表单提交与远程 => true -- js 文件渲染但不执行

    有一个类似的问题here and here但都没有我正在寻找的答案 我也做了很多搜索 rails format js render 但无法解决这个问题 在 Rails 4 中 我有一个经过验证的表单 如下所示 don t want to c
  • 模拟 ScheduledExecutorService 与“不要模拟您不拥有的类型”哲学

    Mocking 预定执行服务确实会让测试我的课程变得更容易 但根据模拟推荐这似乎是一个坏主意 因为模拟类的逻辑可能会以错误的方式使用 但单元测试仍然会报告成功 似乎为它编写一个包装器是 干净 的方式 但我有一种感觉 这只会导致接口的完全重复
  • Python3 在同一行上打印 - 7 段设备格式的数字

    我是 Python 新手 很难将输出打印在一行上 这与在线 Python 课程 Learning Python Essentials Lab 5 1 10 6 和打印到 7 段设备有关 如果您不熟悉 7 段设备 请参阅维基百科 我没有使用任
  • 是否可以将搜索过滤器/框添加到树视图组件中?

    我正在制作扩展 我很好奇是否可以向树组件添加搜索过滤器 框 我目前正在用 javascript 编码扩展 但我不确定它是否可能 这就是我想在树视图顶部添加的内容 它将在 v1 70 中内置到 vscode 中 它在我为垂直选项卡组编写的树视
  • 使用 Linq 表达式和反射获取属性值的通用方法

    亲爱的反思之神 我想要一个通用的GetValue
  • 正则表达式 match() 无法捕获 python 中的简单模式

    我正在尝试在 Python 中使用一些简单的正则表达式函数 我正在使用正则表达式来捕获阿拉伯字母表中的模式 但在最简单的情况下 当人们在模式的开头添加几个字母时 无论是否有连字 它似乎都不起作用 gt gt gt p re compile
  • 等待几秒钟而不阻止 UI 执行

    我想在两条指令之间等待几秒钟 但不阻止执行 例如 Thread Sleep 2000 这不好 因为它会阻塞执行 我的想法是 我调用一个方法 然后等待 X 秒 例如 20 秒 监听即将到来的事件 在 20 秒结束时 我应该根据 20 秒内发生
  • C#.NET 使用 Windows 服务获取计算机的用户名

    我很难获取使用 Windows 服务登录计算机的人的用户名 当同时使用 System Environment UserName 或 WindowsIdentity GetCurrent UserName 时 我得到 NTAUTHORITY
  • 了解Android 6权限方法

    我试图从图库中获取图像并将其设置为图像视图 但在 Android 6 中存在一些权限问题 以下是请求许可的方法 我应该要求读取外部存储还是写入外部存储 这是我到目前为止所做的 private static final int READ CO