在 Android 11 上正确查询 MediaStore 记录

发布于 2025-01-15 10:50:06 字数 796 浏览 6 评论 0原文

我正在努力为我的音频/视频播放器应用提供 Android 11 支持。我主要担心的是,实际上,不要激怒 Google 部落,因为他们不允许播放器应用程序拥有所有文件访问权限。我不希望我的应用程序在 Google 商店上发布时被拒绝。

在以前的 API 中,我使用的是 WRITE_EXTERNAL_STORAGE 权限,包括 Android 10(我在其中选择退出范围存储)。不过,我不知道如何处理 Android 11,而不会让我的应用程序在 Google 商店上发布时被拒绝。我了解到查询 MediaStore 记录需要 READ_EXTERNAL_STORAGE 权限,并且我有以下问题:

  1. 在 Android 11 上运行时会要求 READ_EXTERNAL_STORAGE谷歌可以接受(当我在他们的商店发布我的应用程序时)?
  2. 我是否可以为所有 API 请求运行时的 WRITE_EXTERNAL_STORAGE 权限,而不是 READ_EXTERNAL_STORAGE,并且 Android 11 设备上的系统会将此权限替换为 READ_EXTERNAL_STORAGE?需要在 Android 11 设备上添加要求 READ_EXTERNAL_STORAGE 的条件。
  3. Google 可以接受在 Android 11 上运行时请求 WRITE_EXTERNAL_STORAGE(当我在他们的商店中发布我的应用时)吗?

I am working on providing Android 11 support on my audio/video player app. My main concern is actually with not provoking the Google tribe with their no All files access permission allowed for player apps. I do not want my app to be rejected on publishing on the Google store.

In previous APIs, I am using WRITE_EXTERNAL_STORAGE permission including Android 10 (where I opt out off Scoped Storage). Though, I do not know how to handle Android 11 without having my app rejected on publishing on Google store. I have learned that READ_EXTERNAL_STORAGE permission is needed for querying MediaStore records and I have the following questions:

  1. Will asking for READ_EXTERNAL_STORAGE on runtime on Android 11 be acceptable with Google (when I publish my app on their store)?
  2. Can I ask for WRITE_EXTERNAL_STORAGE permission on runtime instead of READ_EXTERNAL_STORAGE for all APIs and the system on Android 11 devices would substitute that for READ_EXTERNAL_STORAGE or will I need to add conditions where I ask for READ_EXTERNAL_STORAGE on Android 11 devices.
  3. Will asking for WRITE_EXTERNAL_STORAGE on runtime on Android 11 be acceptable with Google (when I publish my app on their store)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

Bonjour°[大白 2025-01-22 10:50:06

您可以使用所有这些权限,而不会受到 Google 的任何禁止。你不能/不应该使用MANAGE_EXTERNAL_STORAGE,这是专门用于范围存储和文件管理应用程序、防病毒软件和其他“特权”软件的新权限

you may use all these permissions without any ban from Google. you can't/shouldn't use MANAGE_EXTERNAL_STORAGE, new perm dedicated for Scoped Storage and file managing apps, antivirs and other "privileged" soft

無心 2025-01-22 10:50:06
  1. 这是获取所有视频列表的函数

    有趣的 getVideo():ArrayList {

     val marrayList = ArrayList

    }

2.这是所有 [源代码]1 用于视频播放器项目

  1. Here is function for getting list of all video

    fun getVideo():ArrayList {

         val   marrayList = ArrayList<Video>()
         val contentResolver =context?.contentResolver
         val uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
         val selection = "${MediaStore.Video.Media.DURATION} >= ?"
         val selectionArgs = arrayOf(
             TimeUnit.MILLISECONDS.convert(2, TimeUnit.SECONDS).toString()
         )
         val sortOrder = "${MediaStore.Video.Media.DISPLAY_NAME} ASC"
         val collection =
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                 MediaStore.Video.Media.getContentUri(
                     MediaStore.VOLUME_EXTERNAL
                 )
             } else {
                 MediaStore.Video.Media.EXTERNAL_CONTENT_URI
             }
    
         val cursor = contentResolver?.query(collection, null, selection, selectionArgs, sortOrder)
         if (cursor != null && cursor.getCount() > 0 && cursor.moveToFirst()) {
    
             val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)
             val nameColumn =
                 cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME)
             val titleCol =cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE)
             val date=cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_ADDED)
             val durationColumn =
                 cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)
             val sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)
    
             while (cursor.moveToNext()) {
    
                 val videoPath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA))
                 val id = cursor.getLong(idColumn)
                 val title=cursor.getString(titleCol)
                 val name = cursor.getString(nameColumn)
                 val duration = cursor.getInt(durationColumn)
                 val mdate=cursor.getString(date)
                 val size = cursor.getString(sizeColumn)
                 val thumb =
                     ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id)
    
                 var duration_formatted: String
                 val sec: Int = duration / 1000 % 60
                 val min: Int = duration / (1000 * 60) % 60
                 val hrs: Int = duration / (1000 * 60 * 60)
    
                 duration_formatted = if (hrs == 0) {
                     min.toString() + ":" + String.format(Locale.UK, "%02d", sec)
                 } else {
                     hrs.toString() + ":" + String.format(
                         Locale.UK,
                         "%02d",
                         min
                     ) + ":" + String.format(
                         Locale.UK, "%02d", sec
                     )
                 }
    
                 val folder = Video(thumb.toString(),id,title,name,size, duration_formatted, videoPath, mdate)
                 marrayList.add(folder)
    
             }
             cursor.close()
         }
         return marrayList
    

    }

2.Here is all [source code]1 for video player project

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文