Skip to content

Commit a75a215

Browse files
authored
🐛 Fix request permissions for images and videos on Android API 33+ (#1221)
`READ_MEDIA_IMAGES` and `READ_MEDIA_VIDEO` are both required whether requesting images or videos.
1 parent 885914c commit a75a215

File tree

8 files changed

+64
-86
lines changed

8 files changed

+64
-86
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ To know more about breaking changes, see the [Migration Guide][].
1010

1111
*None.*
1212

13+
## 3.6.2
14+
15+
### Fixes
16+
17+
- Fix request permissions for images and videos on Android API 33+.
18+
1319
## 3.6.1
1420

1521
### Fixes

README-ZH.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -806,10 +806,12 @@ rootProject.allprojects {
806806
就算你的 `targetSdkVersion``compileSdkVersion` 不是 `33`
807807
你也需要在清单文件中添加以下权限配置:
808808

809+
> 注意:`READ_MEDIA_IMAGES``READ_MEDIA_VIDEO` 无论在请求图片还是请求视频时都需要。
810+
809811
```xml
810812
<manifest>
811-
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- 如果需要读取图片 -->
812-
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- 如果需要读取视频 -->
813+
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- 如果需要读取图片或视频 -->
814+
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- 如果需要读取视频或图片 -->
813815
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <!-- 如果需要读取音频 -->
814816
</manifest>
815817
```

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -866,10 +866,12 @@ When running on Android 13 (API level 33),
866866
the following permissions needs to be added to the manifest
867867
even if your `targetSdkVersion` and `compileSdkVersion` is not `33`:
868868

869+
> Note: `READ_MEDIA_IMAGES` and `READ_MEDIA_VIDEO` are both required whether requesting images or videos.
870+
869871
```xml
870872
<manifest>
871-
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- If you want to read images-->
872-
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- If you want to read videos-->
873+
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- If you want to read images or videos-->
874+
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- If you want to read videos or images-->
873875
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <!-- If you want to read audio-->
874876
</manifest>
875877
```

android/src/main/kotlin/com/fluttercandies/photo_manager/permission/impl/PermissionDelegate19.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ package com.fluttercandies.photo_manager.permission.impl
33
import android.app.Application
44
import android.content.Context
55
import com.fluttercandies.photo_manager.core.entity.PermissionResult
6+
import com.fluttercandies.photo_manager.permission.PermissionDelegate
67
import com.fluttercandies.photo_manager.permission.PermissionsUtils
78

8-
class PermissionDelegate19 : com.fluttercandies.photo_manager.permission.PermissionDelegate() {
9+
class PermissionDelegate19 : PermissionDelegate() {
910
override fun requestPermission(
1011
permissionsUtils: PermissionsUtils,
1112
context: Context,

android/src/main/kotlin/com/fluttercandies/photo_manager/permission/impl/PermissionDelegate23.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import android.app.Application
55
import android.content.Context
66
import androidx.annotation.RequiresApi
77
import com.fluttercandies.photo_manager.core.entity.PermissionResult
8+
import com.fluttercandies.photo_manager.permission.PermissionDelegate
89
import com.fluttercandies.photo_manager.permission.PermissionsUtils
910

1011
@RequiresApi(23)
11-
open class PermissionDelegate23 : com.fluttercandies.photo_manager.permission.PermissionDelegate() {
12-
12+
class PermissionDelegate23 : PermissionDelegate() {
1313
companion object {
1414
private const val readPermission = Manifest.permission.READ_EXTERNAL_STORAGE
1515
private const val writePermission = Manifest.permission.WRITE_EXTERNAL_STORAGE

android/src/main/kotlin/com/fluttercandies/photo_manager/permission/impl/PermissionDelegate33.kt

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import com.fluttercandies.photo_manager.permission.PermissionsUtils
1111

1212
@RequiresApi(33)
1313
class PermissionDelegate33 : PermissionDelegate() {
14-
1514
companion object {
1615
private const val mediaVideo = Manifest.permission.READ_MEDIA_VIDEO
1716
private const val mediaImage = Manifest.permission.READ_MEDIA_IMAGES
@@ -26,24 +25,19 @@ class PermissionDelegate33 : PermissionDelegate() {
2625
requestType: Int,
2726
mediaLocation: Boolean
2827
) {
29-
val containsVideo = RequestTypeUtils.containsVideo(requestType)
30-
val containsImage = RequestTypeUtils.containsImage(requestType)
31-
val containsAudio = RequestTypeUtils.containsAudio(requestType)
32-
3328
val permissions = mutableListOf<String>()
3429

35-
if (containsVideo) {
36-
permissions.add(mediaVideo)
37-
}
30+
val containsImage = RequestTypeUtils.containsImage(requestType)
31+
val containsVideo = RequestTypeUtils.containsVideo(requestType)
32+
val containsAudio = RequestTypeUtils.containsAudio(requestType)
3833

39-
if (containsImage) {
34+
if (containsImage || containsVideo) {
4035
permissions.add(mediaImage)
36+
permissions.add(mediaVideo)
4137
}
42-
4338
if (containsAudio) {
4439
permissions.add(mediaAudio)
4540
}
46-
4741
if (mediaLocation) {
4842
permissions.add(mediaLocationPermission)
4943
}
@@ -60,21 +54,19 @@ class PermissionDelegate33 : PermissionDelegate() {
6054
val containsImage = RequestTypeUtils.containsImage(requestType)
6155
val containsAudio = RequestTypeUtils.containsAudio(requestType)
6256

63-
var result = true
64-
65-
if (containsVideo) {
66-
result = result && havePermission(context, mediaVideo)
67-
}
57+
var granted = true
6858

6959
if (containsImage) {
70-
result = result && havePermission(context, mediaImage)
60+
granted = granted && havePermission(context, mediaImage)
61+
}
62+
if (containsVideo) {
63+
granted = granted && havePermission(context, mediaVideo)
7164
}
72-
7365
if (containsAudio) {
74-
result = result && havePermission(context, mediaAudio)
66+
granted = granted && havePermission(context, mediaAudio)
7567
}
7668

77-
return result
69+
return granted
7870
}
7971

8072
override fun haveMediaLocation(context: Context): Boolean {

android/src/main/kotlin/com/fluttercandies/photo_manager/permission/impl/PermissionDelegate34.kt

Lines changed: 33 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import com.fluttercandies.photo_manager.util.ResultHandler
1313

1414
@RequiresApi(34)
1515
class PermissionDelegate34 : PermissionDelegate() {
16-
1716
companion object {
1817
private const val mediaVideo = Manifest.permission.READ_MEDIA_VIDEO
1918
private const val mediaImage = Manifest.permission.READ_MEDIA_IMAGES
@@ -32,55 +31,39 @@ class PermissionDelegate34 : PermissionDelegate() {
3231
requestType: Int,
3332
mediaLocation: Boolean
3433
) {
35-
if (havePermissions(context, requestType) && (!mediaLocation || haveMediaLocation(context))) {
34+
if (havePermissions(
35+
context,
36+
requestType
37+
) && (!mediaLocation || haveMediaLocation(context))
38+
) {
3639
permissionsUtils.permissionsListener?.onGranted(mutableListOf())
3740
return
3841
}
3942

40-
LogUtils.info("requestPermission")
41-
var havePermission = true
43+
val permissions = mutableListOf<String>()
4244

4345
val containsImage = RequestTypeUtils.containsImage(requestType)
4446
val containsVideo = RequestTypeUtils.containsVideo(requestType)
4547
val containsAudio = RequestTypeUtils.containsAudio(requestType)
4648

47-
val requiredPermissions = mutableListOf<String>()
48-
49-
if (containsVideo || containsImage) {
50-
requiredPermissions.add(mediaVisualUserSelected)
51-
// check have media visual user selected permission, the permission does not need to be defined in the manifest.
52-
val haveMediaVisualUserSelected =
53-
havePermissionForUser(context, mediaVisualUserSelected)
54-
55-
havePermission = haveMediaVisualUserSelected
49+
if (containsImage || containsVideo) {
50+
permissions.add(mediaImage)
51+
permissions.add(mediaVideo)
52+
permissions.add(mediaVisualUserSelected)
5653

5754
if (mediaLocation) {
58-
requiredPermissions.add(mediaLocationPermission)
59-
havePermission = havePermission && havePermission(context, mediaLocationPermission)
55+
permissions.add(mediaLocationPermission)
6056
}
61-
62-
if (containsVideo) {
63-
requiredPermissions.add(mediaVideo)
64-
}
65-
66-
if (containsImage) {
67-
requiredPermissions.add(mediaImage)
68-
}
69-
7057
}
7158

7259
if (containsAudio) {
73-
requiredPermissions.add(mediaAudio)
74-
havePermission = havePermission && havePermission(context, mediaAudio)
60+
permissions.add(mediaAudio)
7561
}
7662

77-
LogUtils.info("Current permissions: $requiredPermissions")
78-
LogUtils.info("havePermission: $havePermission")
79-
80-
if (havePermission) {
81-
permissionsUtils.permissionsListener?.onGranted(requiredPermissions)
63+
if (havePermissions(context, *permissions.toTypedArray())) {
64+
permissionsUtils.permissionsListener?.onGranted(permissions)
8265
} else {
83-
requestPermission(permissionsUtils, requiredPermissions)
66+
requestPermission(permissionsUtils, permissions)
8467
}
8568
}
8669

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

92-
var result = true
75+
var granted = true
9376

94-
if (containsVideo || containsImage) {
95-
result = result && havePermission(context, mediaVisualUserSelected)
77+
if (containsImage || containsVideo) {
78+
var hasPermission = havePermission(context, mediaImage)
79+
hasPermission = hasPermission || havePermission(context, mediaVideo)
80+
hasPermission = hasPermission || havePermission(context, mediaVisualUserSelected)
81+
granted = granted && hasPermission
9682
}
9783

9884
if (containsAudio) {
99-
result = result && havePermission(context, mediaAudio)
85+
granted = granted && havePermission(context, mediaAudio)
10086
}
10187

102-
return result
88+
return granted
10389
}
10490

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

135-
var result = true
121+
var granted = true
136122

137123
if (needImage || needVideo || needMediaVisualUserSelected) {
138124
val haveVideoOrImagePermission = haveAnyPermissionForUser(
139125
context,
140126
mediaVisualUserSelected, mediaImage, mediaVideo
141127
)
142-
143-
result = haveVideoOrImagePermission
128+
granted = haveVideoOrImagePermission
144129
}
145130

146131
if (needAudio) {
147-
result = result && havePermission(context, mediaAudio)
132+
granted = granted && havePermission(context, mediaAudio)
148133
}
149134

150135
if (needMediaLocation) {
151-
result = result && havePermissionForUser(context, mediaLocationPermission)
136+
granted = granted && havePermissionForUser(context, mediaLocationPermission)
152137
}
153138

154139
val listener = permissionsUtils.permissionsListener ?: return
155140

156-
if (result) {
141+
if (granted) {
157142
listener.onGranted(needToRequestPermissionsList)
158143
} else {
159144
listener.onDenied(
@@ -172,21 +157,11 @@ class PermissionDelegate34 : PermissionDelegate() {
172157
) {
173158
this.resultHandler = resultHandler
174159

175-
val containsImage = RequestTypeUtils.containsImage(type)
176-
val containsVideo = RequestTypeUtils.containsVideo(type)
177-
178160
val permissions = mutableListOf<String>()
179-
180-
if (containsVideo || containsImage) {
181-
permissions.add(mediaVisualUserSelected)
182-
}
183-
184-
if (containsVideo) {
185-
permissions.add(mediaVideo)
186-
}
187-
188-
if (containsImage) {
161+
if (RequestTypeUtils.containsImage(type) || RequestTypeUtils.containsVideo(type)) {
189162
permissions.add(mediaImage)
163+
permissions.add(mediaVideo)
164+
permissions.add(mediaVisualUserSelected)
190165
}
191166

192167
requestPermission(permissionsUtils, permissions, limitedRequestCode)
@@ -219,8 +194,8 @@ class PermissionDelegate34 : PermissionDelegate() {
219194
}
220195

221196
PermissionResult.Limited -> result = PermissionResult.Limited
222-
else -> {
223-
}
197+
198+
else -> {}
224199
}
225200
}
226201

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: photo_manager
22
description: A Flutter plugin that provides album assets abstraction management APIs on Android, iOS, macOS, and OpenHarmony.
33
repository: https://github.com/fluttercandies/flutter_photo_manager
4-
version: 3.6.1
4+
version: 3.6.2
55

66
environment:
77
sdk: ">=2.13.0 <4.0.0"

0 commit comments

Comments
 (0)