android 使用MediaPlayer实现音乐播放--权限请求

        在Android应用中,获取本地音乐文件的权限是实现音乐扫描功能的关键步骤之一。随着Android版本的不断更新,从Android 6.0(API级别23)开始,应用需要动态请求权限,而到了android 13以上需要的权限又做了进一步改变。

       1. 需要添加存储权限到AndroidManifest.xml中,android 6.0到android 12只需要存储权限,android 13开始对权限做了更细致的处理,而不是READ_EXTERNAL_STORAGE,拆分成下面三个权限。如果同时请求 READ_MEDIA_IMAGES 权限和 READ_MEDIA_VIDEO 权限,系统只会显示一个系统权限对话框。如果您的应用之前已获得 READ_EXTERNAL_STORAGE 权限,则在升级时,系统会自动授予任何请求的 READ_MEDIA_* 权限。如果您的应用只需要访问图片、照片和视频,优先使用照片选择器,而不是声明 READ_MEDIA_IMAGES 和 READ_MEDIA_VIDEO 权限。如果是只要音频文件同理只需要READ_MEDIA_VIDEO 权限即可。

一般我们获取音频文件,只需要添加下面权限即可

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"tools:ignore="ScopedStorage" android:maxSdkVersion="32"/><uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>

2.动态请求权限

检查是否有获取音频文件权限

    fun checkPermission(context: Context): Boolean {return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {ContextCompat.checkSelfPermission(context,Manifest.permission.READ_MEDIA_AUDIO) == PackageManager.PERMISSION_GRANTED} else {ContextCompat.checkSelfPermission(context,Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED}}

请求权限

    fun requestPermission(activity: Activity, requestCode: Int) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {ActivityCompat.requestPermissions(activity,arrayOf(Manifest.permission.READ_MEDIA_AUDIO,Manifest.permission.POST_NOTIFICATIONS), requestCode)} else {ActivityCompat.requestPermissions(activity,arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),requestCode)}}

一般我们写成一个数组里面一起去请求

  private static final String[] permissionsArray = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.RECORD_AUDIO};private static final String[] permissionsArray13 = new String[]{Manifest.permission.READ_MEDIA_AUDIO,Manifest.permission.RECORD_AUDIO,Manifest.permission.POST_NOTIFICATIONS};private void checkRequiredPermission(final Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {for (String permission : permissionsArray13) {if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {permissionsList.add(permission);}}} else {for (String permission : permissionsArray) {if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {permissionsList.add(permission);}}}if (permissionsList != null && permissionsList.size() > 0) {ActivityCompat.requestPermissions(activity, permissionsList.toArray(new String[permissionsList.size()]), REQUEST_PERMISSION);} else {//去初始化}}

去请求权限可以用一个对话框去处理会显得更友好

    final PermissionDialog permissionDialog = new PermissionDialog(this, R.color.library_dialog_bg, getString(R.string.permission_title));permissionDialog.setPermissionDialogListener(new PermissionDialog.IPermissionDialogListener() {@Overridepublic void cancelClick() {finish();permissionDialog.cancel();}@Overridepublic void okClick() {boolean isBannedPermission = MusicPermissionUtils.INSTANCE.isBannedPermission(MusicLibraryActivity.this);if (!isBannedPermission) {Utils.goToSettingIntent(MusicLibraryActivity.this);} else {MusicPermissionUtils.INSTANCE.requestPermission(MusicLibraryActivity.this, REQUEST_PERMISSION);}permissionDialog.cancel();}});permissionDialog.show();

处理权限请求结果,如果全部权限都已同意可以去做初始化,一般我们做权限请求最好每个功能点需要用到的权限一个个去请求会更友好。

    @Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {switch (requestCode) {case REQUEST_PERMISSION:boolean isAllRequest = false;for (int i = 0; i < permissions.length; i++) {if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {isAllRequest = true;} else {//去请求权限showPermissionDialog();return;}}if (isAllRequest) {//初始化或者继续操作}break;default:super.onRequestPermissionsResult(requestCode, permissions, grantResults);}}

用户如果不同意权限可以跳转到设置找到应用去同意添加权限,用户有可能会拒绝权限请求,最好在界面添加可以继续请求的按钮或者直接跳转到设置里面让用户找到应用去添加需要的权限

    public static void goToSettingIntent(Context context) {Intent localIntent = new Intent();localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);if (Build.VERSION.SDK_INT >= 9) {localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));} else if (Build.VERSION.SDK_INT <= 8) {localIntent.setAction(Intent.ACTION_VIEW);localIntent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");localIntent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName());}context.startActivity(localIntent);}

音乐权限请求工具代码

object MusicPermissionUtils {fun hasMusicPermission(context: Context): Boolean {val permission = checkPermission(context)if (permission == PackageManager.PERMISSION_GRANTED) {return true}return false}fun isBannedPermission(activity: Activity): Boolean {val isBannedPermission: Boolean =if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {ActivityCompat.shouldShowRequestPermissionRationale(activity,Manifest.permission.READ_MEDIA_AUDIO)} else {ActivityCompat.shouldShowRequestPermissionRationale(activity,Manifest.permission.READ_EXTERNAL_STORAGE)}return isBannedPermission}fun requestPermission(activity: Activity, requestCode: Int) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {ActivityCompat.requestPermissions(activity,arrayOf(Manifest.permission.READ_MEDIA_AUDIO,Manifest.permission.POST_NOTIFICATIONS), requestCode)} else {ActivityCompat.requestPermissions(activity,arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),requestCode)}}fun checkReadPermission(context: Context): Boolean {return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {ContextCompat.checkSelfPermission(context,Manifest.permission.READ_MEDIA_AUDIO) == PackageManager.PERMISSION_GRANTED} else {ContextCompat.checkSelfPermission(context,Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED}}fun checkPermission(context: Context): Int {val checkWriteStoragePermission: Int =if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {ContextCompat.checkSelfPermission(context, Manifest.permission.READ_MEDIA_AUDIO)} else {ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE)}return checkWriteStoragePermission}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/60439.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GPT系列文章

GPT系列文章 GPT1 GPT1是由OpenAI公司发表在2018年要早于我们之前介绍的所熟知的BERT系列文章。总结&#xff1a;GPT 是一种半监督学习&#xff0c;采用两阶段任务模型&#xff0c;通过使用无监督的 Pre-training 和有监督的 Fine-tuning 来实现强大的自然语言理解。在 Pre-t…

NUXT3学习日记四(路由中间件、导航守卫)

前言 在 Nuxt 3 中&#xff0c;中间件&#xff08;Middleware&#xff09;是用于在页面渲染之前或导航发生之前执行的函数。它们允许你在路由切换时执行逻辑&#xff0c;像是身份验证、重定向、权限控制、数据预加载等任务。中间件可以被全局使用&#xff0c;也可以只在特定页…

汽车免拆诊断案例 | 2012款路虎揽胜运动版柴油车加速无力

故障现象  一辆2012款路虎揽胜运动版车&#xff0c;搭载3.0T柴油发动机&#xff08;型号为306DT&#xff09;&#xff0c;累计行驶里程约为10.2万km。车主进厂反映&#xff0c;车辆行驶中加速无力&#xff0c;且发动机故障灯异常点亮。 故障诊断 接车后试车&#xff0c;发动…

网络安全与加密

1.Base64简单说明描述&#xff1a;Base64可以成为密码学的基石&#xff0c;非常重要。特点&#xff1a;可以将任意的二进制数据进行Base64编码结果&#xff1a;所有的数据都能被编码为并只用65个字符就能表示的文本文件。65字符&#xff1a;A~Z a~z 0~9 / 对文件进行base64编码…

C语言:数组转换指针的时机

1、指针数组 如果一个数组中的所有元素保存的都是指针&#xff0c;那么我们就称它为指针数组&#xff0c;指针数组的定义形式一般为&#xff1a; dataType *arrayName[length];[ ]的优先级高于*&#xff0c;该定义形式应该理解为&#xff1a; dataType *(arrayName[length])…

UE5 DownloadImage加载jpg失败的解决方法

DownloadImage加载jpg失败的解决方法 现象解决方案具体方法 现象 用UE自带的 DownloadImage 无法下载成功&#xff0c;从 failure 引脚出来。 接入一个由监控器自动保存起的图像&#xff0c;有些可以正常加载成功&#xff0c;有些无法加载成功。 经调查问题出现在&#xff0c;…

使用 helm 部署 gitlab

一、下载 Gitlab chart 进入 artifacthub 官网 选择你想要的版本&#xff08;我选择的chart版本是 8.4.0 , gitlab 版本是17.4.0 &#xff09; 进入到控制台&#xff0c;添加helm仓库 如果你想不改任何配置&#xff0c;你可以执行安装命令&#xff0c;等待安装即可helm instal…

FreeRTOS信号量(一)

目录 什么是信号量&#xff1f; 1.信号量简介 2.二值信号量 2.1二值信号量简介 1. 首先&#xff0c;创建时&#xff0c;二值信号量默认无效 2. 之后中断释放信号量 3.信号量获取成功 4、任务再次进入阻塞态 2.2 创建二值信号量 1、函数vSemaphoreCreateBinary () 2、…

51单片机-独立按键与数码管联动

独立键盘和矩阵键盘检测原理及实现 键盘的分类&#xff1a;编码键盘和非编码键盘 键盘上闭合键的识别由专用的硬件编码器实现&#xff0c;并产生键编码号或键值的称为编码键盘&#xff0c;如&#xff1a;计算机键盘。靠软件编程识别的称为非编码键盘&#xff1b;在单片机组成…

springboot课程答疑系统(代码+数据库+LW)

摘要 随着信息互联网信息的飞速发展&#xff0c;无纸化作业变成了一种趋势&#xff0c;针对这个问题开发一个专门适应师生交流形式的网站。本文介绍了课程答疑系统的开发全过程。通过分析企业对于课程答疑系统的需求&#xff0c;创建了一个计算机管理课程答疑系统的方案。文章…

解锁业务成功:大数据和 AI 如何协作以释放战略洞察

在当今这个数据主导的时代&#xff0c;大数据与AI的协同作用对于寻求竞争优势的组织而言愈发关键。大数据以其庞大的数据量、多样化的数据类型以及高速的数据生成能力&#xff0c;为AI算法提供了丰富的原材料&#xff0c;助力其挖掘出有价值的洞见&#xff0c;推动明智决策的制…

24.UE5枚举,怪物分类,龙卷风技能

2-26 枚举、怪物分类、龙旋风技能、掉落概率_哔哩哔哩_bilibili 目录 1.枚举 1.1枚举类型的创建 1.2 将枚举类型绑定到怪物蓝图上 1.3枚举类型的使用 1.3.1创建新的掉落物 1.3.2更改怪物掉落逻辑 2.龙卷风技能 2.1输入映射 2.2龙卷风发射物的创建 2.3龙卷风伤害逻辑…

故障字故障码 简单介绍

一、故障字 1.1故障字的概念 故障字&#xff08;Fault Word&#xff09;是一种常用的技术术语&#xff0c;主要应用在工业控制、嵌入式系统和通信领域&#xff0c;用于表示系统状态或故障信息。它是一个以位为单位的编码方式&#xff0c;每个位&#xff08;bit&#xff09;对应…

鸿蒙系统ubuntu开发环境搭建

在RISC-V等平台移植鸿蒙系统OpenHarmony&#xff0c;需要使用linux环境进行代码的编译&#xff0c;为兼顾日常办公需要&#xff0c;可采用WindowsUbuntu虚拟机的混合开发的环境&#xff0c;通过网络及文件夹共享&#xff0c;在主机和虚拟机之间共享文件数据。 工具准备&#x…

二叉树oj题解析

二叉树 二叉树的最近公共祖先什么是最近公共祖先&#xff1f;leetcode中求二叉树中最近公共祖先解题1.解题2. 根据二叉树创建字符串 二叉树的最近公共祖先 什么是最近公共祖先&#xff1f; 最近的公共祖先指的是这一棵树中两个节点中深度最大的且公共的祖先节点就是最近祖先节…

优先算法 —— 双指针系列 - 移动零

1. 移动零 题目链接&#xff1a; 283. 移动零 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/move-zeroes/description/ 2. 算法原理 其实像移动零这种类型的题目都有一个名字叫做数组划分&#xff08;数组分块&#xff09;&#xff0c;就是说先给一个…

C语言——数组逐元素操作练习

定义一个能容纳10个元素的整形数组a&#xff0c;从键盘读取9个整数存放到前9个数组元素中。 一. 从键盘读取一个整数n和位置p(0<p<8)&#xff0c;插入n到数组a中&#xff0c;插入位置&#xff1a;下标p。要求插入点及后续的数组元素都要后移动。 代码如下&#xff1a; …

【ArcGISPro】根据yaml构建原始Pro的conda环境

使用场景 我们不小心把原始arcgispro-py3的conda环境破坏了,我们就可以使用以下方法进行修复 查找文件 在arcgis目录下找到yaml文件 如果没找到请复制以下内容到新的yaml文件 channels: - esri - defaults dependencies: - anyio=4.2.0=py311haa95532_0 - appdirs=1.4.4=p…

解决IDEA报包不存在,但实际存在的问题

前言 最近在把一个亿老项目交割给同事&#xff0c;同事在导入项目运行时遇到IDEA报包不存在&#xff0c;但实际存在的问题&#xff0c;最终通过以下方式解决 现象 在IDEA里启动运行项目&#xff0c;报某个类有问题&#xff0c;引入的包不存在。 点击这个引入的包&#xff0c;可…

使用uniapp编写APP的文件上传

使用uniapp插件文件选择、文件上传组件&#xff08;图片&#xff0c;视频&#xff0c;文件等&#xff09; - DCloud 插件市场 实用效果&#xff1a; 缺陷是只能一个一个单独上传