expo-media-library 18.3.0-canary-20250919-7a31b96 → 18.3.0-canary-20251003-7b9d7ff

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/android/build.gradle +6 -6
  3. package/android/src/main/java/expo/modules/medialibrary/next/MediaLibraryNextModule.kt +37 -18
  4. package/android/src/main/java/expo/modules/medialibrary/next/extensions/resolver/CursorExtensions.kt +15 -5
  5. package/android/src/main/java/expo/modules/medialibrary/next/objects/album/Album.kt +16 -17
  6. package/android/src/main/java/expo/modules/medialibrary/next/objects/album/AlbumQuery.kt +3 -2
  7. package/android/src/main/java/expo/modules/medialibrary/next/objects/album/factories/AlbumFactory.kt +1 -0
  8. package/android/src/main/java/expo/modules/medialibrary/next/objects/album/factories/AlbumLegacyFactory.kt +13 -4
  9. package/android/src/main/java/expo/modules/medialibrary/next/objects/album/factories/AlbumModernFactory.kt +13 -4
  10. package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/Asset.kt +10 -18
  11. package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/ExifTags.kt +135 -0
  12. package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/delegates/AssetDelegate.kt +4 -0
  13. package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/delegates/AssetLegacyDelegate.kt +44 -9
  14. package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/delegates/AssetModernDelegate.kt +46 -4
  15. package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/deleters/AssetDeleter.kt +8 -0
  16. package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/deleters/AssetLegacyDeleter.kt +46 -0
  17. package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/deleters/AssetModernDeleter.kt +24 -0
  18. package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/factories/AssetFactory.kt +2 -1
  19. package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/factories/AssetLegacyFactory.kt +25 -10
  20. package/android/src/main/java/expo/modules/medialibrary/next/objects/asset/factories/AssetModernFactory.kt +22 -3
  21. package/android/src/main/java/expo/modules/medialibrary/next/objects/query/Query.kt +6 -2
  22. package/android/src/main/java/expo/modules/medialibrary/next/permissions/MediaStorePermissionsDelegate.kt +12 -6
  23. package/android/src/main/java/expo/modules/medialibrary/next/records/Location.kt +9 -0
  24. package/build/next/types/Asset.d.ts +21 -3
  25. package/build/next/types/Asset.d.ts.map +1 -1
  26. package/build/next/types/Asset.js.map +1 -1
  27. package/build/next/types/Location.d.ts +5 -0
  28. package/build/next/types/Location.d.ts.map +1 -0
  29. package/build/next/types/Location.js +2 -0
  30. package/build/next/types/Location.js.map +1 -0
  31. package/expo-module.config.json +1 -1
  32. package/ios/next/MediaLibraryNextModule.swift +15 -7
  33. package/ios/next/exceptions/Exceptions.swift +6 -0
  34. package/ios/next/objects/Query/Query.swift +3 -3
  35. package/ios/next/objects/album/Album.swift +2 -2
  36. package/ios/next/objects/asset/Asset.swift +36 -26
  37. package/ios/next/objects/asset/Location.swift +13 -0
  38. package/ios/next/objects/asset/UriExtractor.swift +86 -0
  39. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/{18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96-sources.jar → 18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar} +0 -0
  40. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar.md5 +1 -0
  41. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar.sha1 +1 -0
  42. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar.sha256 +1 -0
  43. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff-sources.jar.sha512 +1 -0
  44. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar +0 -0
  45. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar.md5 +1 -0
  46. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar.sha1 +1 -0
  47. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar.sha256 +1 -0
  48. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.aar.sha512 +1 -0
  49. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/{18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.module → 18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.module} +27 -27
  50. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.module.md5 +1 -0
  51. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.module.sha1 +1 -0
  52. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.module.sha256 +1 -0
  53. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.module.sha512 +1 -0
  54. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/{18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.pom → 18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.pom} +4 -4
  55. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.pom.md5 +1 -0
  56. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.pom.sha1 +1 -0
  57. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.pom.sha256 +1 -0
  58. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20251003-7b9d7ff/expo.modules.medialibrary-18.3.0-canary-20251003-7b9d7ff.pom.sha512 +1 -0
  59. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml +4 -4
  60. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml.md5 +1 -1
  61. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml.sha1 +1 -1
  62. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml.sha256 +1 -1
  63. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/maven-metadata.xml.sha512 +1 -1
  64. package/package.json +3 -3
  65. package/src/next/types/Asset.ts +21 -3
  66. package/src/next/types/Location.ts +4 -0
  67. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96-sources.jar.md5 +0 -1
  68. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96-sources.jar.sha1 +0 -1
  69. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96-sources.jar.sha256 +0 -1
  70. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96-sources.jar.sha512 +0 -1
  71. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.aar +0 -0
  72. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.aar.md5 +0 -1
  73. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.aar.sha1 +0 -1
  74. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.aar.sha256 +0 -1
  75. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.aar.sha512 +0 -1
  76. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.module.md5 +0 -1
  77. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.module.sha1 +0 -1
  78. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.module.sha256 +0 -1
  79. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.module.sha512 +0 -1
  80. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.pom.md5 +0 -1
  81. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.pom.sha1 +0 -1
  82. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.pom.sha256 +0 -1
  83. package/local-maven-repo/host/exp/exponent/expo.modules.medialibrary/18.3.0-canary-20250919-7a31b96/expo.modules.medialibrary-18.3.0-canary-20250919-7a31b96.pom.sha512 +0 -1
package/CHANGELOG.md CHANGED
@@ -6,15 +6,19 @@
6
6
 
7
7
  ### 🎉 New features
8
8
 
9
+ - [next] Add exif support ([#39992](https://github.com/expo/expo/pull/39992) by [@Wenszel](https://github.com/Wenszel))
9
10
  - [next] Add `Album.get(title)` ([#39717](https://github.com/expo/expo/pull/39717) by [@Wenszel](https://github.com/Wenszel))
10
11
 
11
12
  ### 🐛 Bug fixes
12
13
 
14
+ - [next][iOS] Convert `id` to URI format ([#39920](https://github.com/expo/expo/pull/39920) by [@Wenszel](https://github.com/Wenszel))
15
+ - [next][android] Fix `delete()` throwing security exception ([#39914](https://github.com/expo/expo/pull/39914) by [@Wenszel](https://github.com/Wenszel))
13
16
  - [next][android] Change default root directory to Pictures ([#39716](https://github.com/expo/expo/pull/39716) by [@Wenszel](https://github.com/Wenszel))
14
17
  - [next] Fix `asset.getModificationTime` to return milliseconds ([#39715](https://github.com/expo/expo/pull/39715) by [@Wenszel](https://github.com/Wenszel))
15
18
 
16
19
  ### 💡 Others
17
20
 
21
+ - [next] Add test screens ([#39951](https://github.com/expo/expo/pull/39951) by [@Wenszel](https://github.com/Wenszel))
18
22
  - [next] Add documentation ([#39754](https://github.com/expo/expo/pull/39754) by [@Wenszel](https://github.com/Wenszel))
19
23
 
20
24
  ## 18.2.0 — 2025-09-16
@@ -4,23 +4,23 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'host.exp.exponent'
7
- version = '18.3.0-canary-20250919-7a31b96'
7
+ version = '18.3.0-canary-20251003-7b9d7ff'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.medialibrary"
11
11
  defaultConfig {
12
12
  versionCode 37
13
- versionName "18.3.0-canary-20250919-7a31b96"
13
+ versionName "18.3.0-canary-20251003-7b9d7ff"
14
14
  }
15
15
  }
16
16
 
17
17
  dependencies {
18
- implementation "androidx.annotation:annotation:1.2.0"
19
- api "androidx.exifinterface:exifinterface:1.3.3"
20
- implementation 'androidx.activity:activity-ktx:1.10.1'
18
+ implementation "androidx.annotation:annotation:1.9.1"
19
+ api "androidx.exifinterface:exifinterface:1.4.1"
20
+ implementation 'androidx.activity:activity-ktx:1.11.0'
21
21
 
22
22
  if (project.findProject(':expo-modules-test-core')) {
23
23
  testImplementation project(':expo-modules-test-core')
24
24
  }
25
- testImplementation "org.robolectric:robolectric:4.10"
25
+ testImplementation "org.robolectric:robolectric:4.16"
26
26
  }
@@ -15,6 +15,8 @@ import expo.modules.medialibrary.next.objects.album.AlbumQuery
15
15
  import expo.modules.medialibrary.next.objects.asset.Asset
16
16
  import expo.modules.medialibrary.next.objects.album.factories.AlbumModernFactory
17
17
  import expo.modules.medialibrary.next.objects.album.factories.AlbumLegacyFactory
18
+ import expo.modules.medialibrary.next.objects.asset.deleters.AssetLegacyDeleter
19
+ import expo.modules.medialibrary.next.objects.asset.deleters.AssetModernDeleter
18
20
  import expo.modules.medialibrary.next.objects.asset.factories.AssetModernFactory
19
21
  import expo.modules.medialibrary.next.objects.asset.factories.AssetLegacyFactory
20
22
  import expo.modules.medialibrary.next.objects.query.MediaStoreQueryFormatter
@@ -40,22 +42,30 @@ class MediaLibraryNextModule : Module() {
40
42
  }
41
43
 
42
44
  private val albumQuery by lazy {
43
- AlbumQuery(context)
45
+ AlbumQuery(albumFactory, context)
44
46
  }
45
47
 
46
48
  private val albumFactory by lazy {
47
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
48
- AlbumModernFactory(assetFactory, context)
49
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
50
+ AlbumModernFactory(assetFactory, assetDeleter, context)
49
51
  } else {
50
- AlbumLegacyFactory(assetFactory, context)
52
+ AlbumLegacyFactory(assetFactory, assetDeleter, context)
51
53
  }
52
54
  }
53
55
 
54
56
  private val assetFactory by lazy {
55
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
56
- AssetModernFactory(context)
57
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
58
+ AssetModernFactory(assetDeleter, context)
57
59
  } else {
58
- AssetLegacyFactory(context)
60
+ AssetLegacyFactory(assetDeleter, context)
61
+ }
62
+ }
63
+
64
+ private val assetDeleter by lazy {
65
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
66
+ AssetModernDeleter(mediaStorePermissionsDelegate)
67
+ } else {
68
+ AssetLegacyDeleter(context)
59
69
  }
60
70
  }
61
71
 
@@ -64,7 +74,7 @@ class MediaLibraryNextModule : Module() {
64
74
 
65
75
  Class(Asset::class) {
66
76
  Constructor { contentUri: Uri ->
67
- Asset(contentUri, context)
77
+ assetFactory.create(contentUri)
68
78
  }
69
79
 
70
80
  Property("id") { self: Asset ->
@@ -82,6 +92,16 @@ class MediaLibraryNextModule : Module() {
82
92
  self.getDuration()
83
93
  }
84
94
 
95
+ AsyncFunction("getExif") Coroutine { self: Asset ->
96
+ systemPermissionsDelegate.requireSystemPermissions(false)
97
+ self.getExif()
98
+ }
99
+
100
+ AsyncFunction("getLocation") Coroutine { self: Asset ->
101
+ systemPermissionsDelegate.requireSystemPermissions(false)
102
+ self.getLocation()
103
+ }
104
+
85
105
  AsyncFunction("getFilename") Coroutine { self: Asset ->
86
106
  systemPermissionsDelegate.requireSystemPermissions(false)
87
107
  self.getFilename()
@@ -114,14 +134,13 @@ class MediaLibraryNextModule : Module() {
114
134
 
115
135
  AsyncFunction("delete") Coroutine { self: Asset ->
116
136
  systemPermissionsDelegate.requireSystemPermissions(true)
117
- mediaStorePermissionsDelegate.requestMediaLibraryActionPermission(listOf(self.contentUri), needsDeletePermission = true)
118
137
  self.delete()
119
138
  }
120
139
  }
121
140
 
122
141
  Class(Album::class) {
123
142
  Constructor { id: String ->
124
- Album(id, context)
143
+ Album(id, assetDeleter, assetFactory, context)
125
144
  }
126
145
 
127
146
  Property("id") { self: Album ->
@@ -140,21 +159,19 @@ class MediaLibraryNextModule : Module() {
140
159
 
141
160
  AsyncFunction("add") Coroutine { self: Album, asset: Asset ->
142
161
  systemPermissionsDelegate.requireSystemPermissions(true)
143
- mediaStorePermissionsDelegate.requestMediaLibraryActionPermission(listOf(asset.contentUri))
162
+ mediaStorePermissionsDelegate.requestMediaLibraryWritePermission(listOf(asset.contentUri))
144
163
  self.add(asset)
145
164
  }
146
165
 
147
166
  AsyncFunction("delete") Coroutine { self: Album ->
148
167
  systemPermissionsDelegate.requireSystemPermissions(true)
149
- val assetIdsToDelete = self.getAssets().map { it.contentUri }
150
- mediaStorePermissionsDelegate.requestMediaLibraryActionPermission(assetIdsToDelete, needsDeletePermission = true)
151
168
  self.delete()
152
169
  }
153
170
  }
154
171
 
155
172
  Class(Query::class) {
156
173
  Constructor {
157
- Query(context)
174
+ Query(assetFactory, context)
158
175
  }
159
176
 
160
177
  Function("limit") { self: Query, limit: Int ->
@@ -233,14 +250,16 @@ class MediaLibraryNextModule : Module() {
233
250
 
234
251
  AsyncFunction("deleteAlbums") Coroutine { albums: List<Album> ->
235
252
  systemPermissionsDelegate.requireSystemPermissions(true)
236
- albums.forEach { album -> album.delete() }
253
+ val contentUris = albums
254
+ .map { it.getAssets() }
255
+ .flatten()
256
+ .map { it.contentUri }
257
+ assetDeleter.delete(contentUris)
237
258
  }
238
259
 
239
260
  AsyncFunction("deleteAssets") Coroutine { assets: List<Asset> ->
240
261
  systemPermissionsDelegate.requireSystemPermissions(true)
241
- val assetIdsToDelete = assets.map { it.contentUri }
242
- mediaStorePermissionsDelegate.requestMediaLibraryActionPermission(assetIdsToDelete, needsDeletePermission = true)
243
- assets.forEach { asset -> asset.delete() }
262
+ assetDeleter.delete(assets.map { it.contentUri })
244
263
  }
245
264
 
246
265
  AsyncFunction("requestPermissionsAsync") { writeOnly: Boolean, permissions: List<GranularPermission>?, promise: Promise ->
@@ -3,16 +3,26 @@ package expo.modules.medialibrary.next.extensions.resolver
3
3
  import android.content.ContentUris
4
4
  import android.database.Cursor
5
5
  import android.net.Uri
6
+ import android.os.Build
6
7
  import android.provider.MediaStore
7
8
 
8
9
  fun Cursor.extractAssetContentUri(idColumn: Int, typeColumn: Int): Uri {
9
10
  val id = getLong(idColumn)
10
11
  val mediaType = getInt(typeColumn)
11
- val baseUri = when (mediaType) {
12
- MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
13
- MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
14
- MediaStore.Files.FileColumns.MEDIA_TYPE_AUDIO -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
15
- else -> EXTERNAL_CONTENT_URI
12
+ val baseUri = if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
13
+ when (mediaType) {
14
+ MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE -> MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
15
+ MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO -> MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
16
+ MediaStore.Files.FileColumns.MEDIA_TYPE_AUDIO -> MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
17
+ else -> MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
18
+ }
19
+ } else {
20
+ when (mediaType) {
21
+ MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
22
+ MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
23
+ MediaStore.Files.FileColumns.MEDIA_TYPE_AUDIO -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
24
+ else -> EXTERNAL_CONTENT_URI
25
+ }
16
26
  }
17
27
  return ContentUris.withAppendedId(baseUri, id)
18
28
  }
@@ -12,14 +12,18 @@ import expo.modules.medialibrary.next.extensions.resolver.queryAlbumFilepath
12
12
  import expo.modules.medialibrary.next.extensions.resolver.queryAlbumRelativePath
13
13
  import expo.modules.medialibrary.next.extensions.resolver.queryAlbumTitle
14
14
  import expo.modules.medialibrary.next.objects.asset.Asset
15
+ import expo.modules.medialibrary.next.objects.asset.deleters.AssetDeleter
16
+ import expo.modules.medialibrary.next.objects.asset.factories.AssetFactory
15
17
  import expo.modules.medialibrary.next.objects.wrappers.RelativePath
16
- import kotlinx.coroutines.async
17
- import kotlinx.coroutines.awaitAll
18
- import kotlinx.coroutines.coroutineScope
19
18
  import java.io.File
20
19
  import java.lang.ref.WeakReference
21
20
 
22
- class Album(val id: String, context: Context) : SharedObject() {
21
+ class Album(
22
+ val id: String,
23
+ val assetDeleter: AssetDeleter,
24
+ val assetFactory: AssetFactory,
25
+ context: Context
26
+ ) : SharedObject() {
23
27
  private val contextRef = WeakReference(context)
24
28
 
25
29
  private val contentResolver
@@ -51,21 +55,16 @@ class Album(val id: String, context: Context) : SharedObject() {
51
55
  return RelativePath(relative)
52
56
  }
53
57
 
54
- suspend fun getAssets(): List<Asset> {
55
- return contentResolver
58
+ suspend fun getAssets(): List<Asset> =
59
+ contentResolver
56
60
  .queryAlbumAssetsContentUris(id)
57
- .map { contentUri -> Asset(contentUri, contextRef.getOrThrow()) }
58
- }
61
+ .map { assetFactory.create(it) }
59
62
 
60
- suspend fun delete() = coroutineScope {
61
- getAssets().map { asset ->
62
- async {
63
- asset.delete()
64
- }
65
- }.awaitAll()
66
- }
63
+ suspend fun delete() =
64
+ assetDeleter.delete(
65
+ getAssets().map { it.contentUri }
66
+ )
67
67
 
68
- suspend fun add(asset: Asset) {
68
+ suspend fun add(asset: Asset) =
69
69
  asset.move(getRelativePath())
70
- }
71
70
  }
@@ -4,9 +4,10 @@ import android.content.Context
4
4
  import expo.modules.medialibrary.next.exceptions.ContentResolverNotObtainedException
5
5
  import expo.modules.medialibrary.next.extensions.getOrThrow
6
6
  import expo.modules.medialibrary.next.extensions.resolver.queryAlbumId
7
+ import expo.modules.medialibrary.next.objects.album.factories.AlbumFactory
7
8
  import java.lang.ref.WeakReference
8
9
 
9
- class AlbumQuery(context: Context) {
10
+ class AlbumQuery(val albumFactory: AlbumFactory, context: Context) {
10
11
  private val contextRef = WeakReference(context)
11
12
 
12
13
  private val contentResolver
@@ -17,6 +18,6 @@ class AlbumQuery(context: Context) {
17
18
  suspend fun getAlbum(title: String): Album? {
18
19
  val id = contentResolver.queryAlbumId(title)
19
20
  ?: return null
20
- return Album(id, contextRef.getOrThrow())
21
+ return albumFactory.create(id)
21
22
  }
22
23
  }
@@ -5,6 +5,7 @@ import expo.modules.medialibrary.next.objects.album.Album
5
5
  import expo.modules.medialibrary.next.objects.asset.Asset
6
6
 
7
7
  interface AlbumFactory {
8
+ fun create(id: String): Album
8
9
  suspend fun createFromAssets(albumName: String, assets: List<Asset>, deleteOriginalAssets: Boolean): Album
9
10
  suspend fun createFromFilePaths(albumName: String, filePaths: List<Uri>): Album
10
11
  }
@@ -12,14 +12,19 @@ import expo.modules.medialibrary.next.extensions.resolver.queryAssetBucketId
12
12
  import expo.modules.medialibrary.next.objects.album.Album
13
13
  import expo.modules.medialibrary.next.objects.wrappers.RelativePath
14
14
  import expo.modules.medialibrary.next.objects.asset.Asset
15
+ import expo.modules.medialibrary.next.objects.asset.deleters.AssetDeleter
15
16
  import expo.modules.medialibrary.next.objects.wrappers.MimeType
16
17
  import expo.modules.medialibrary.next.objects.asset.factories.AssetFactory
17
18
  import java.io.File
18
19
  import java.io.IOException
19
20
  import java.lang.ref.WeakReference
20
21
 
21
- @DeprecatedSinceApi(Build.VERSION_CODES.Q)
22
- class AlbumLegacyFactory(private val assetFactory: AssetFactory, context: Context) : AlbumFactory {
22
+ @DeprecatedSinceApi(Build.VERSION_CODES.R)
23
+ class AlbumLegacyFactory(
24
+ private val assetFactory: AssetFactory,
25
+ private val assetDeleter: AssetDeleter,
26
+ context: Context
27
+ ) : AlbumFactory {
23
28
  private val contextRef = WeakReference(context)
24
29
 
25
30
  private val contentResolver
@@ -27,6 +32,10 @@ class AlbumLegacyFactory(private val assetFactory: AssetFactory, context: Contex
27
32
  .getOrThrow()
28
33
  .contentResolver ?: throw AlbumCouldNotBeCreated("Failed to create album: ContentResolver is unavailable.")
29
34
 
35
+ override fun create(id: String): Album {
36
+ return Album(id, assetDeleter, assetFactory, contextRef.getOrThrow())
37
+ }
38
+
30
39
  override suspend fun createFromAssets(albumName: String, assets: List<Asset>, deleteOriginalAssets: Boolean): Album {
31
40
  try {
32
41
  val firstAsset = assets.firstOrNull()
@@ -37,7 +46,7 @@ class AlbumLegacyFactory(private val assetFactory: AssetFactory, context: Contex
37
46
  processAssetsLocation(assets, relativePath, true)
38
47
  val albumId = contentResolver.queryAssetBucketId(assets[0].contentUri)
39
48
  ?: throw AlbumNotFoundException("Could not find album with filePath: ${relativePath.toFilePath()}")
40
- return Album(albumId.toString(), contextRef.getOrThrow())
49
+ return Album(albumId.toString(), assetDeleter, assetFactory, contextRef.getOrThrow())
41
50
  } catch (e: SecurityException) {
42
51
  throw AlbumCouldNotBeCreated("Missing WRITE_EXTERNAL_STORAGE permission: ${e.message}", e)
43
52
  } catch (e: IOException) {
@@ -55,7 +64,7 @@ class AlbumLegacyFactory(private val assetFactory: AssetFactory, context: Contex
55
64
  }
56
65
  val albumId = contentResolver.queryAssetBucketId(assets[0].contentUri)
57
66
  ?: throw AlbumCouldNotBeCreated("Could not find album with relativePath: $relativePath")
58
- return Album(albumId.toString(), contextRef.getOrThrow())
67
+ return Album(albumId.toString(), assetDeleter, assetFactory, contextRef.getOrThrow())
59
68
  }
60
69
 
61
70
  private suspend fun processAssetsLocation(assets: List<Asset>, relativePath: RelativePath, deleteOriginalAssets: Boolean) {
@@ -11,13 +11,18 @@ import expo.modules.medialibrary.next.extensions.resolver.queryAlbumId
11
11
  import expo.modules.medialibrary.next.objects.album.Album
12
12
  import expo.modules.medialibrary.next.objects.wrappers.RelativePath
13
13
  import expo.modules.medialibrary.next.objects.asset.Asset
14
+ import expo.modules.medialibrary.next.objects.asset.deleters.AssetDeleter
14
15
  import expo.modules.medialibrary.next.objects.wrappers.MimeType
15
16
  import expo.modules.medialibrary.next.objects.asset.factories.AssetFactory
16
17
  import java.io.IOException
17
18
  import java.lang.ref.WeakReference
18
19
 
19
- @RequiresApi(Build.VERSION_CODES.Q)
20
- class AlbumModernFactory(private val assetFactory: AssetFactory, context: Context) : AlbumFactory {
20
+ @RequiresApi(Build.VERSION_CODES.R)
21
+ class AlbumModernFactory(
22
+ private val assetFactory: AssetFactory,
23
+ private val assetDeleter: AssetDeleter,
24
+ context: Context
25
+ ) : AlbumFactory {
21
26
  private val contextRef = WeakReference(context)
22
27
 
23
28
  private val contentResolver
@@ -25,6 +30,10 @@ class AlbumModernFactory(private val assetFactory: AssetFactory, context: Contex
25
30
  .getOrThrow()
26
31
  .contentResolver ?: throw AlbumCouldNotBeCreated("Failed to create album: ContentResolver is unavailable.")
27
32
 
33
+ override fun create(id: String): Album {
34
+ return Album(id, assetDeleter, assetFactory, contextRef.getOrThrow())
35
+ }
36
+
28
37
  override suspend fun createFromAssets(albumName: String, assets: List<Asset>, deleteOriginalAssets: Boolean): Album =
29
38
  try {
30
39
  val mimeTypeOfFirstAsset = assets[0].getMimeType()
@@ -32,7 +41,7 @@ class AlbumModernFactory(private val assetFactory: AssetFactory, context: Contex
32
41
  processAssetsLocation(assets, albumRelativePath, deleteOriginalAssets)
33
42
  val albumId = contentResolver.queryAlbumId(albumRelativePath)
34
43
  ?: throw AlbumNotFoundException("Could not find album with relativePath: $albumRelativePath")
35
- Album(albumId, contextRef.getOrThrow())
44
+ Album(albumId, assetDeleter, assetFactory, contextRef.getOrThrow())
36
45
  } catch (e: SecurityException) {
37
46
  throw AlbumCouldNotBeCreated("Security Exception: ${e.message}", e)
38
47
  } catch (e: IOException) {
@@ -47,7 +56,7 @@ class AlbumModernFactory(private val assetFactory: AssetFactory, context: Contex
47
56
  }
48
57
  val albumId = contentResolver.queryAlbumId(relativePath)
49
58
  ?: throw AlbumCouldNotBeCreated("Failed to create album: newly created album was not found in the MediaStore.")
50
- return Album(albumId, contextRef.getOrThrow())
59
+ return Album(albumId, assetDeleter, assetFactory, contextRef.getOrThrow())
51
60
  }
52
61
 
53
62
  private suspend fun processAssetsLocation(assets: List<Asset>, relativePath: RelativePath, deleteOriginalAssets: Boolean) {
@@ -1,31 +1,17 @@
1
1
  package expo.modules.medialibrary.next.objects.asset
2
2
 
3
- import android.content.Context
4
3
  import android.net.Uri
5
- import android.os.Build
4
+ import android.os.Bundle
6
5
  import expo.modules.kotlin.sharedobjects.SharedObject
7
- import expo.modules.medialibrary.next.extensions.getOrThrow
6
+ import expo.modules.medialibrary.next.objects.asset.delegates.AssetDelegate
8
7
  import expo.modules.medialibrary.next.objects.wrappers.RelativePath
9
- import expo.modules.medialibrary.next.objects.asset.delegates.AssetLegacyDelegate
10
- import expo.modules.medialibrary.next.objects.asset.delegates.AssetModernDelegate
11
8
  import expo.modules.medialibrary.next.objects.wrappers.MediaType
12
9
  import expo.modules.medialibrary.next.objects.wrappers.MimeType
10
+ import expo.modules.medialibrary.next.records.Location
13
11
  import kotlinx.coroutines.Dispatchers
14
12
  import kotlinx.coroutines.withContext
15
- import java.lang.ref.WeakReference
16
- import kotlin.getValue
17
-
18
- class Asset(contentUri: Uri, context: Context) : SharedObject() {
19
- private val contextRef = WeakReference(context)
20
-
21
- val assetDelegate by lazy {
22
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
23
- AssetModernDelegate(contentUri, contextRef.getOrThrow())
24
- } else {
25
- AssetLegacyDelegate(contentUri, contextRef.getOrThrow())
26
- }
27
- }
28
13
 
14
+ class Asset(val assetDelegate: AssetDelegate) : SharedObject() {
29
15
  val contentUri: Uri get() = assetDelegate.contentUri
30
16
 
31
17
  suspend fun getCreationTime(): Long? =
@@ -55,6 +41,12 @@ class Asset(contentUri: Uri, context: Context) : SharedObject() {
55
41
  suspend fun getMimeType(): MimeType =
56
42
  assetDelegate.getMimeType()
57
43
 
44
+ suspend fun getLocation(): Location? =
45
+ assetDelegate.getLocation()
46
+
47
+ suspend fun getExif(): Bundle =
48
+ assetDelegate.getExif()
49
+
58
50
  suspend fun move(relativePath: RelativePath) = withContext(Dispatchers.IO) {
59
51
  assetDelegate.move(relativePath)
60
52
  }
@@ -0,0 +1,135 @@
1
+ package expo.modules.medialibrary.next.objects.asset
2
+
3
+ import androidx.exifinterface.media.ExifInterface
4
+
5
+ val EXIF_TAGS = arrayOf(
6
+ arrayOf("string", ExifInterface.TAG_ARTIST),
7
+ arrayOf("int", ExifInterface.TAG_BITS_PER_SAMPLE),
8
+ arrayOf("int", ExifInterface.TAG_COMPRESSION),
9
+ arrayOf("string", ExifInterface.TAG_COPYRIGHT),
10
+ arrayOf("string", ExifInterface.TAG_DATETIME),
11
+ arrayOf("string", ExifInterface.TAG_IMAGE_DESCRIPTION),
12
+ arrayOf("int", ExifInterface.TAG_IMAGE_LENGTH),
13
+ arrayOf("int", ExifInterface.TAG_IMAGE_WIDTH),
14
+ arrayOf("int", ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT),
15
+ arrayOf("int", ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH),
16
+ arrayOf("string", ExifInterface.TAG_MAKE),
17
+ arrayOf("string", ExifInterface.TAG_MODEL),
18
+ arrayOf("int", ExifInterface.TAG_ORIENTATION),
19
+ arrayOf("int", ExifInterface.TAG_PHOTOMETRIC_INTERPRETATION),
20
+ arrayOf("int", ExifInterface.TAG_PLANAR_CONFIGURATION),
21
+ arrayOf("double", ExifInterface.TAG_PRIMARY_CHROMATICITIES),
22
+ arrayOf("double", ExifInterface.TAG_REFERENCE_BLACK_WHITE),
23
+ arrayOf("int", ExifInterface.TAG_RESOLUTION_UNIT),
24
+ arrayOf("int", ExifInterface.TAG_ROWS_PER_STRIP),
25
+ arrayOf("int", ExifInterface.TAG_SAMPLES_PER_PIXEL),
26
+ arrayOf("string", ExifInterface.TAG_SOFTWARE),
27
+ arrayOf("int", ExifInterface.TAG_STRIP_BYTE_COUNTS),
28
+ arrayOf("int", ExifInterface.TAG_STRIP_OFFSETS),
29
+ arrayOf("int", ExifInterface.TAG_TRANSFER_FUNCTION),
30
+ arrayOf("double", ExifInterface.TAG_WHITE_POINT),
31
+ arrayOf("double", ExifInterface.TAG_X_RESOLUTION),
32
+ arrayOf("double", ExifInterface.TAG_Y_CB_CR_COEFFICIENTS),
33
+ arrayOf("int", ExifInterface.TAG_Y_CB_CR_POSITIONING),
34
+ arrayOf("int", ExifInterface.TAG_Y_CB_CR_SUB_SAMPLING),
35
+ arrayOf("double", ExifInterface.TAG_Y_RESOLUTION),
36
+ arrayOf("double", ExifInterface.TAG_APERTURE_VALUE),
37
+ arrayOf("double", ExifInterface.TAG_BRIGHTNESS_VALUE),
38
+ arrayOf("string", ExifInterface.TAG_CFA_PATTERN),
39
+ arrayOf("int", ExifInterface.TAG_COLOR_SPACE),
40
+ arrayOf("string", ExifInterface.TAG_COMPONENTS_CONFIGURATION),
41
+ arrayOf("double", ExifInterface.TAG_COMPRESSED_BITS_PER_PIXEL),
42
+ arrayOf("int", ExifInterface.TAG_CONTRAST),
43
+ arrayOf("int", ExifInterface.TAG_CUSTOM_RENDERED),
44
+ arrayOf("string", ExifInterface.TAG_DATETIME_DIGITIZED),
45
+ arrayOf("string", ExifInterface.TAG_DATETIME_ORIGINAL),
46
+ arrayOf("string", ExifInterface.TAG_DEVICE_SETTING_DESCRIPTION),
47
+ arrayOf("double", ExifInterface.TAG_DIGITAL_ZOOM_RATIO),
48
+ arrayOf("string", ExifInterface.TAG_EXIF_VERSION),
49
+ arrayOf("double", ExifInterface.TAG_EXPOSURE_BIAS_VALUE),
50
+ arrayOf("double", ExifInterface.TAG_EXPOSURE_INDEX),
51
+ arrayOf("int", ExifInterface.TAG_EXPOSURE_MODE),
52
+ arrayOf("int", ExifInterface.TAG_EXPOSURE_PROGRAM),
53
+ arrayOf("double", ExifInterface.TAG_EXPOSURE_TIME),
54
+ arrayOf("double", ExifInterface.TAG_F_NUMBER),
55
+ arrayOf("string", ExifInterface.TAG_FILE_SOURCE),
56
+ arrayOf("int", ExifInterface.TAG_FLASH),
57
+ arrayOf("double", ExifInterface.TAG_FLASH_ENERGY),
58
+ arrayOf("string", ExifInterface.TAG_FLASHPIX_VERSION),
59
+ arrayOf("double", ExifInterface.TAG_FOCAL_LENGTH),
60
+ arrayOf("int", ExifInterface.TAG_FOCAL_LENGTH_IN_35MM_FILM),
61
+ arrayOf("int", ExifInterface.TAG_FOCAL_PLANE_RESOLUTION_UNIT),
62
+ arrayOf("double", ExifInterface.TAG_FOCAL_PLANE_X_RESOLUTION),
63
+ arrayOf("double", ExifInterface.TAG_FOCAL_PLANE_Y_RESOLUTION),
64
+ arrayOf("int", ExifInterface.TAG_GAIN_CONTROL),
65
+ arrayOf("int", ExifInterface.TAG_ISO_SPEED_RATINGS),
66
+ arrayOf("string", ExifInterface.TAG_IMAGE_UNIQUE_ID),
67
+ arrayOf("int", ExifInterface.TAG_LIGHT_SOURCE),
68
+ arrayOf("string", ExifInterface.TAG_MAKER_NOTE),
69
+ arrayOf("double", ExifInterface.TAG_MAX_APERTURE_VALUE),
70
+ arrayOf("int", ExifInterface.TAG_METERING_MODE),
71
+ arrayOf("int", ExifInterface.TAG_NEW_SUBFILE_TYPE),
72
+ arrayOf("string", ExifInterface.TAG_OECF),
73
+ arrayOf("int", ExifInterface.TAG_PIXEL_X_DIMENSION),
74
+ arrayOf("int", ExifInterface.TAG_PIXEL_Y_DIMENSION),
75
+ arrayOf("string", ExifInterface.TAG_RELATED_SOUND_FILE),
76
+ arrayOf("int", ExifInterface.TAG_SATURATION),
77
+ arrayOf("int", ExifInterface.TAG_SCENE_CAPTURE_TYPE),
78
+ arrayOf("string", ExifInterface.TAG_SCENE_TYPE),
79
+ arrayOf("int", ExifInterface.TAG_SENSING_METHOD),
80
+ arrayOf("int", ExifInterface.TAG_SHARPNESS),
81
+ arrayOf("double", ExifInterface.TAG_SHUTTER_SPEED_VALUE),
82
+ arrayOf("string", ExifInterface.TAG_SPATIAL_FREQUENCY_RESPONSE),
83
+ arrayOf("string", ExifInterface.TAG_SPECTRAL_SENSITIVITY),
84
+ arrayOf("int", ExifInterface.TAG_SUBFILE_TYPE),
85
+ arrayOf("string", ExifInterface.TAG_SUBSEC_TIME),
86
+ arrayOf("string", ExifInterface.TAG_SUBSEC_TIME_DIGITIZED),
87
+ arrayOf("string", ExifInterface.TAG_SUBSEC_TIME_ORIGINAL),
88
+ arrayOf("int", ExifInterface.TAG_SUBJECT_AREA),
89
+ arrayOf("double", ExifInterface.TAG_SUBJECT_DISTANCE),
90
+ arrayOf("int", ExifInterface.TAG_SUBJECT_DISTANCE_RANGE),
91
+ arrayOf("int", ExifInterface.TAG_SUBJECT_LOCATION),
92
+ arrayOf("string", ExifInterface.TAG_USER_COMMENT),
93
+ arrayOf("int", ExifInterface.TAG_WHITE_BALANCE),
94
+ arrayOf("int", ExifInterface.TAG_GPS_ALTITUDE_REF),
95
+ arrayOf("string", ExifInterface.TAG_GPS_AREA_INFORMATION),
96
+ arrayOf("double", ExifInterface.TAG_GPS_DOP),
97
+ arrayOf("string", ExifInterface.TAG_GPS_DATESTAMP),
98
+ arrayOf("double", ExifInterface.TAG_GPS_DEST_BEARING),
99
+ arrayOf("string", ExifInterface.TAG_GPS_DEST_BEARING_REF),
100
+ arrayOf("double", ExifInterface.TAG_GPS_DEST_DISTANCE),
101
+ arrayOf("string", ExifInterface.TAG_GPS_DEST_DISTANCE_REF),
102
+ arrayOf("double", ExifInterface.TAG_GPS_DEST_LATITUDE),
103
+ arrayOf("string", ExifInterface.TAG_GPS_DEST_LATITUDE_REF),
104
+ arrayOf("double", ExifInterface.TAG_GPS_DEST_LONGITUDE),
105
+ arrayOf("string", ExifInterface.TAG_GPS_DEST_LONGITUDE_REF),
106
+ arrayOf("int", ExifInterface.TAG_GPS_DIFFERENTIAL),
107
+ arrayOf("double", ExifInterface.TAG_GPS_IMG_DIRECTION),
108
+ arrayOf("string", ExifInterface.TAG_GPS_IMG_DIRECTION_REF),
109
+ arrayOf("string", ExifInterface.TAG_GPS_LATITUDE_REF),
110
+ arrayOf("string", ExifInterface.TAG_GPS_LONGITUDE_REF),
111
+ arrayOf("string", ExifInterface.TAG_GPS_MAP_DATUM),
112
+ arrayOf("string", ExifInterface.TAG_GPS_MEASURE_MODE),
113
+ arrayOf("string", ExifInterface.TAG_GPS_PROCESSING_METHOD),
114
+ arrayOf("string", ExifInterface.TAG_GPS_SATELLITES),
115
+ arrayOf("double", ExifInterface.TAG_GPS_SPEED),
116
+ arrayOf("string", ExifInterface.TAG_GPS_SPEED_REF),
117
+ arrayOf("string", ExifInterface.TAG_GPS_STATUS),
118
+ arrayOf("string", ExifInterface.TAG_GPS_TIMESTAMP),
119
+ arrayOf("double", ExifInterface.TAG_GPS_TRACK),
120
+ arrayOf("string", ExifInterface.TAG_GPS_TRACK_REF),
121
+ arrayOf("string", ExifInterface.TAG_GPS_VERSION_ID),
122
+ arrayOf("string", ExifInterface.TAG_INTEROPERABILITY_INDEX),
123
+ arrayOf("int", ExifInterface.TAG_THUMBNAIL_IMAGE_LENGTH),
124
+ arrayOf("int", ExifInterface.TAG_THUMBNAIL_IMAGE_WIDTH),
125
+ arrayOf("int", ExifInterface.TAG_DNG_VERSION),
126
+ arrayOf("int", ExifInterface.TAG_DEFAULT_CROP_SIZE),
127
+ arrayOf("int", ExifInterface.TAG_ORF_PREVIEW_IMAGE_START),
128
+ arrayOf("int", ExifInterface.TAG_ORF_PREVIEW_IMAGE_LENGTH),
129
+ arrayOf("int", ExifInterface.TAG_ORF_ASPECT_FRAME),
130
+ arrayOf("int", ExifInterface.TAG_RW2_SENSOR_BOTTOM_BORDER),
131
+ arrayOf("int", ExifInterface.TAG_RW2_SENSOR_LEFT_BORDER),
132
+ arrayOf("int", ExifInterface.TAG_RW2_SENSOR_RIGHT_BORDER),
133
+ arrayOf("int", ExifInterface.TAG_RW2_SENSOR_TOP_BORDER),
134
+ arrayOf("int", ExifInterface.TAG_RW2_ISO)
135
+ )
@@ -1,10 +1,12 @@
1
1
  package expo.modules.medialibrary.next.objects.asset.delegates
2
2
 
3
3
  import android.net.Uri
4
+ import android.os.Bundle
4
5
  import expo.modules.medialibrary.next.objects.wrappers.RelativePath
5
6
  import expo.modules.medialibrary.next.objects.asset.Asset
6
7
  import expo.modules.medialibrary.next.objects.wrappers.MediaType
7
8
  import expo.modules.medialibrary.next.objects.wrappers.MimeType
9
+ import expo.modules.medialibrary.next.records.Location
8
10
 
9
11
  interface AssetDelegate {
10
12
  val contentUri: Uri
@@ -17,6 +19,8 @@ interface AssetDelegate {
17
19
  suspend fun getModificationTime(): Long?
18
20
  suspend fun getUri(): Uri
19
21
  suspend fun getMimeType(): MimeType
22
+ suspend fun getLocation(): Location?
23
+ suspend fun getExif(): Bundle
20
24
  suspend fun delete()
21
25
  suspend fun move(relativePath: RelativePath)
22
26
  suspend fun copy(relativePath: RelativePath): Asset