Я работаю над обеспечением поддержки Android 11 в своем приложении аудио/видеоплеера. Моя главная забота на самом деле заключается в том, чтобы не спровоцировать племя Google тем, что у них нет разрешений All files access
для приложений игроков. Я не хочу, чтобы мое приложение было отклонено при публикации в магазине Google.
В предыдущих API я использую разрешение WRITE_EXTERNAL_STORAGE
, включая Android 10 (где я отказываюсь от Scoped Storage). Однако я не знаю, как справиться с Android 11, чтобы мое приложение не было отклонено при публикации в магазине Google. Я узнал, что для запроса READ_EXTERNAL_STORAGE
записей требуется разрешение MediaStore
, и у меня есть следующие вопросы:
READ_EXTERNAL_STORAGE
во время выполнения на Android 11 (когда я публикую свое приложение в их магазине)?WRITE_EXTERNAL_STORAGE
во время выполнения вместо READ_EXTERNAL_STORAGE
для всех API, и система на устройствах Android 11 заменит это разрешение READ_EXTERNAL_STORAGE
, или мне нужно будет добавить условия, когда я запрашиваю READ_EXTERNAL_STORAGE
на устройствах Android 11.WRITE_EXTERNAL_STORAGE
во время выполнения на Android 11 (когда я публикую свое приложение в их магазине)?вы можете использовать все эти разрешения без какого-либо запрета со стороны Google. вы не можете / не должны использовать MANAGE_EXTERNAL_STORAGE
, новые права доступа, предназначенные для Scoped Storage и приложений для управления файлами, антивирусов и другого «привилегированного» программного обеспечения.
Вот функция для получения списка всех видео
весело 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.Вот все [исходный код]1 для проекта видеоплеера
ОП задал ответ в java
не проблема рад помочь
Большое спасибо за код. Хотя я не понимаю Котлин, ваш проект подтвердил то, что я хотел знать о разрешениях. Я хотел бы выбрать два ответа, хотя мне пришлось выбрать один, и я выбрал тот, который непосредственно отвечал на вопросы.