Skip to content

Commit

Permalink
🐛 Fix request permissions for images and videos on Android API 33+ (#…
Browse files Browse the repository at this point in the history
…1221)

`READ_MEDIA_IMAGES` and `READ_MEDIA_VIDEO` are both required whether
requesting images or videos.
  • Loading branch information
AlexV525 authored Nov 10, 2024
1 parent 885914c commit a75a215
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 86 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ To know more about breaking changes, see the [Migration Guide][].

*None.*

## 3.6.2

### Fixes

- Fix request permissions for images and videos on Android API 33+.

## 3.6.1

### Fixes
Expand Down
6 changes: 4 additions & 2 deletions README-ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -806,10 +806,12 @@ rootProject.allprojects {
就算你的 `targetSdkVersion``compileSdkVersion` 不是 `33`
你也需要在清单文件中添加以下权限配置:

> 注意:`READ_MEDIA_IMAGES``READ_MEDIA_VIDEO` 无论在请求图片还是请求视频时都需要。
```xml
<manifest>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- 如果需要读取图片 -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- 如果需要读取视频 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- 如果需要读取图片或视频 -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- 如果需要读取视频或图片 -->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <!-- 如果需要读取音频 -->
</manifest>
```
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -866,10 +866,12 @@ When running on Android 13 (API level 33),
the following permissions needs to be added to the manifest
even if your `targetSdkVersion` and `compileSdkVersion` is not `33`:

> Note: `READ_MEDIA_IMAGES` and `READ_MEDIA_VIDEO` are both required whether requesting images or videos.
```xml
<manifest>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- If you want to read images-->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- If you want to read videos-->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- If you want to read images or videos-->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- If you want to read videos or images-->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <!-- If you want to read audio-->
</manifest>
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package com.fluttercandies.photo_manager.permission.impl
import android.app.Application
import android.content.Context
import com.fluttercandies.photo_manager.core.entity.PermissionResult
import com.fluttercandies.photo_manager.permission.PermissionDelegate
import com.fluttercandies.photo_manager.permission.PermissionsUtils

class PermissionDelegate19 : com.fluttercandies.photo_manager.permission.PermissionDelegate() {
class PermissionDelegate19 : PermissionDelegate() {
override fun requestPermission(
permissionsUtils: PermissionsUtils,
context: Context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import android.app.Application
import android.content.Context
import androidx.annotation.RequiresApi
import com.fluttercandies.photo_manager.core.entity.PermissionResult
import com.fluttercandies.photo_manager.permission.PermissionDelegate
import com.fluttercandies.photo_manager.permission.PermissionsUtils

@RequiresApi(23)
open class PermissionDelegate23 : com.fluttercandies.photo_manager.permission.PermissionDelegate() {

class PermissionDelegate23 : PermissionDelegate() {
companion object {
private const val readPermission = Manifest.permission.READ_EXTERNAL_STORAGE
private const val writePermission = Manifest.permission.WRITE_EXTERNAL_STORAGE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import com.fluttercandies.photo_manager.permission.PermissionsUtils

@RequiresApi(33)
class PermissionDelegate33 : PermissionDelegate() {

companion object {
private const val mediaVideo = Manifest.permission.READ_MEDIA_VIDEO
private const val mediaImage = Manifest.permission.READ_MEDIA_IMAGES
Expand All @@ -26,24 +25,19 @@ class PermissionDelegate33 : PermissionDelegate() {
requestType: Int,
mediaLocation: Boolean
) {
val containsVideo = RequestTypeUtils.containsVideo(requestType)
val containsImage = RequestTypeUtils.containsImage(requestType)
val containsAudio = RequestTypeUtils.containsAudio(requestType)

val permissions = mutableListOf<String>()

if (containsVideo) {
permissions.add(mediaVideo)
}
val containsImage = RequestTypeUtils.containsImage(requestType)
val containsVideo = RequestTypeUtils.containsVideo(requestType)
val containsAudio = RequestTypeUtils.containsAudio(requestType)

if (containsImage) {
if (containsImage || containsVideo) {
permissions.add(mediaImage)
permissions.add(mediaVideo)
}

if (containsAudio) {
permissions.add(mediaAudio)
}

if (mediaLocation) {
permissions.add(mediaLocationPermission)
}
Expand All @@ -60,21 +54,19 @@ class PermissionDelegate33 : PermissionDelegate() {
val containsImage = RequestTypeUtils.containsImage(requestType)
val containsAudio = RequestTypeUtils.containsAudio(requestType)

var result = true

if (containsVideo) {
result = result && havePermission(context, mediaVideo)
}
var granted = true

if (containsImage) {
result = result && havePermission(context, mediaImage)
granted = granted && havePermission(context, mediaImage)
}
if (containsVideo) {
granted = granted && havePermission(context, mediaVideo)
}

if (containsAudio) {
result = result && havePermission(context, mediaAudio)
granted = granted && havePermission(context, mediaAudio)
}

return result
return granted
}

override fun haveMediaLocation(context: Context): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import com.fluttercandies.photo_manager.util.ResultHandler

@RequiresApi(34)
class PermissionDelegate34 : PermissionDelegate() {

companion object {
private const val mediaVideo = Manifest.permission.READ_MEDIA_VIDEO
private const val mediaImage = Manifest.permission.READ_MEDIA_IMAGES
Expand All @@ -32,55 +31,39 @@ class PermissionDelegate34 : PermissionDelegate() {
requestType: Int,
mediaLocation: Boolean
) {
if (havePermissions(context, requestType) && (!mediaLocation || haveMediaLocation(context))) {
if (havePermissions(
context,
requestType
) && (!mediaLocation || haveMediaLocation(context))
) {
permissionsUtils.permissionsListener?.onGranted(mutableListOf())
return
}

LogUtils.info("requestPermission")
var havePermission = true
val permissions = mutableListOf<String>()

val containsImage = RequestTypeUtils.containsImage(requestType)
val containsVideo = RequestTypeUtils.containsVideo(requestType)
val containsAudio = RequestTypeUtils.containsAudio(requestType)

val requiredPermissions = mutableListOf<String>()

if (containsVideo || containsImage) {
requiredPermissions.add(mediaVisualUserSelected)
// check have media visual user selected permission, the permission does not need to be defined in the manifest.
val haveMediaVisualUserSelected =
havePermissionForUser(context, mediaVisualUserSelected)

havePermission = haveMediaVisualUserSelected
if (containsImage || containsVideo) {
permissions.add(mediaImage)
permissions.add(mediaVideo)
permissions.add(mediaVisualUserSelected)

if (mediaLocation) {
requiredPermissions.add(mediaLocationPermission)
havePermission = havePermission && havePermission(context, mediaLocationPermission)
permissions.add(mediaLocationPermission)
}

if (containsVideo) {
requiredPermissions.add(mediaVideo)
}

if (containsImage) {
requiredPermissions.add(mediaImage)
}

}

if (containsAudio) {
requiredPermissions.add(mediaAudio)
havePermission = havePermission && havePermission(context, mediaAudio)
permissions.add(mediaAudio)
}

LogUtils.info("Current permissions: $requiredPermissions")
LogUtils.info("havePermission: $havePermission")

if (havePermission) {
permissionsUtils.permissionsListener?.onGranted(requiredPermissions)
if (havePermissions(context, *permissions.toTypedArray())) {
permissionsUtils.permissionsListener?.onGranted(permissions)
} else {
requestPermission(permissionsUtils, requiredPermissions)
requestPermission(permissionsUtils, permissions)
}
}

Expand All @@ -89,17 +72,20 @@ class PermissionDelegate34 : PermissionDelegate() {
val containsVideo = RequestTypeUtils.containsVideo(requestType)
val containsAudio = RequestTypeUtils.containsAudio(requestType)

var result = true
var granted = true

if (containsVideo || containsImage) {
result = result && havePermission(context, mediaVisualUserSelected)
if (containsImage || containsVideo) {
var hasPermission = havePermission(context, mediaImage)
hasPermission = hasPermission || havePermission(context, mediaVideo)
hasPermission = hasPermission || havePermission(context, mediaVisualUserSelected)
granted = granted && hasPermission
}

if (containsAudio) {
result = result && havePermission(context, mediaAudio)
granted = granted && havePermission(context, mediaAudio)
}

return result
return granted
}

override fun haveMediaLocation(context: Context): Boolean {
Expand Down Expand Up @@ -132,28 +118,27 @@ class PermissionDelegate34 : PermissionDelegate() {
val needMediaVisualUserSelected =
needToRequestPermissionsList.contains(mediaVisualUserSelected)

var result = true
var granted = true

if (needImage || needVideo || needMediaVisualUserSelected) {
val haveVideoOrImagePermission = haveAnyPermissionForUser(
context,
mediaVisualUserSelected, mediaImage, mediaVideo
)

result = haveVideoOrImagePermission
granted = haveVideoOrImagePermission
}

if (needAudio) {
result = result && havePermission(context, mediaAudio)
granted = granted && havePermission(context, mediaAudio)
}

if (needMediaLocation) {
result = result && havePermissionForUser(context, mediaLocationPermission)
granted = granted && havePermissionForUser(context, mediaLocationPermission)
}

val listener = permissionsUtils.permissionsListener ?: return

if (result) {
if (granted) {
listener.onGranted(needToRequestPermissionsList)
} else {
listener.onDenied(
Expand All @@ -172,21 +157,11 @@ class PermissionDelegate34 : PermissionDelegate() {
) {
this.resultHandler = resultHandler

val containsImage = RequestTypeUtils.containsImage(type)
val containsVideo = RequestTypeUtils.containsVideo(type)

val permissions = mutableListOf<String>()

if (containsVideo || containsImage) {
permissions.add(mediaVisualUserSelected)
}

if (containsVideo) {
permissions.add(mediaVideo)
}

if (containsImage) {
if (RequestTypeUtils.containsImage(type) || RequestTypeUtils.containsVideo(type)) {
permissions.add(mediaImage)
permissions.add(mediaVideo)
permissions.add(mediaVisualUserSelected)
}

requestPermission(permissionsUtils, permissions, limitedRequestCode)
Expand Down Expand Up @@ -219,8 +194,8 @@ class PermissionDelegate34 : PermissionDelegate() {
}

PermissionResult.Limited -> result = PermissionResult.Limited
else -> {
}

else -> {}
}
}

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: photo_manager
description: A Flutter plugin that provides album assets abstraction management APIs on Android, iOS, macOS, and OpenHarmony.
repository: https://github.com/fluttercandies/flutter_photo_manager
version: 3.6.1
version: 3.6.2

environment:
sdk: ">=2.13.0 <4.0.0"
Expand Down

0 comments on commit a75a215

Please sign in to comment.