Skip to content

Commit 1b2b572

Browse files
author
Laks Castro
authored
Merge pull request #67 from lakscastro/master
`v0.4.0` release
2 parents bc1133c + 108f900 commit 1b2b572

File tree

18 files changed

+188
-479
lines changed

18 files changed

+188
-479
lines changed

.all-contributorsrc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@
6565
"avatar_url": "https://avatars.githubusercontent.com/u/758047?v=4",
6666
"profile": "https://eternityforest.com",
6767
"contributions": [
68-
"bug"
68+
"bug",
69+
"code",
70+
"doc"
6971
]
7072
}
7173
],

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
## 0.4.0
2+
3+
Fix the current behavior of `listFiles` and `openDocumentFile` API.
4+
5+
### Improvements
6+
7+
- It's now possible to list contents of all subfolders of a granted Uri opened from `openDocumentTree` ([@EternityForest](https://github.com/EternityForest)).
8+
- Now `ACTION_VIEW` intent builder through `openDocumentFile` API was fixed. So it's now possible to open any file of any kind in third party apps without needing specify the mime type.
9+
10+
### Breaking changes
11+
12+
- Removed Android specific APIs:
13+
- `DocumentFile.listFiles` (Now it's only available globally).
14+
- `buildDocumentUriUsingTree` removed due high coupling with Android API (Android specific API that are not useful on any other platforms).
15+
- `buildDocumentUri` removed due high coupling with Android API (Android specific API that are not useful on any other platforms).
16+
- `buildTreeDocumentUri` removed due high coupling with Android API (Android specific API that are not useful on any other platforms).
17+
- `getDocumentThumbnail` now receives only the `uri` param instead of a `rootUri` and a `documentId`.
18+
- `rootUri` field from `QueryMetadata` was removed due API ambiguity: there's no such concept in the Android API and this is not required by it to work well.
19+
120
## 0.3.1
221

322
Minor improvements and bug fixes:

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@
2222

2323
## Documentation
2424

25-
#### See the website for [documentation](https://lakscastro.github.io/shared-storage)
25+
See the website for [documentation](https://lakscastro.github.io/shared-storage).
2626

2727
All documentation is also available under `/docs` to each released version which is the data source of the website.
2828

2929
You can contribute to the documentation by just editing these files through the GitHub web editor!
3030

31+
To check all ways you can contribute to this package see [Contributing/Ways to contribute](https://lakscastro.github.io/shared-storage/Contributing/Ways%20to%20contribute/).
32+
3133
Latest changes are available on `master` branch and the actual latest published package version lives under `release` branch.
3234

3335
All other branches are derivated from issues, new features or bug fixes.
@@ -46,7 +48,7 @@ These are the brilliant minds behind the development of this plugin!
4648
<td align="center"><a href="https://www.bibliotecaortodoxa.ro"><img src="https://avatars.githubusercontent.com/u/1148228?v=4?s=100" width="100px;" alt=""/><br /><sub><b>www.bibliotecaortodoxa.ro</b></sub></a><br /><a href="https://github.com/lakscastro/shared-storage/commits?author=aplicatii-romanesti" title="Code">💻</a> <a href="https://github.com/lakscastro/shared-storage/issues?q=author%3Aaplicatii-romanesti" title="Bug reports">🐛</a> <a href="#ideas-aplicatii-romanesti" title="Ideas, Planning, & Feedback">🤔</a></td>
4749
<td align="center"><a href="https://github.com/dangilbert"><img src="https://avatars.githubusercontent.com/u/6799566?v=4?s=100" width="100px;" alt=""/><br /><sub><b>dangilbert</b></sub></a><br /><a href="https://github.com/lakscastro/shared-storage/commits?author=dangilbert" title="Code">💻</a> <a href="https://github.com/lakscastro/shared-storage/issues?q=author%3Adangilbert" title="Bug reports">🐛</a></td>
4850
<td align="center"><a href="https://github.com/dhaval-k-simformsolutions"><img src="https://avatars.githubusercontent.com/u/90894202?v=4?s=100" width="100px;" alt=""/><br /><sub><b>dhaval-k-simformsolutions</b></sub></a><br /><a href="https://github.com/lakscastro/shared-storage/issues?q=author%3Adhaval-k-simformsolutions" title="Bug reports">🐛</a> <a href="#ideas-dhaval-k-simformsolutions" title="Ideas, Planning, & Feedback">🤔</a></td>
49-
<td align="center"><a href="https://eternityforest.com"><img src="https://avatars.githubusercontent.com/u/758047?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Dunn</b></sub></a><br /><a href="https://github.com/lakscastro/shared-storage/issues?q=author%3AEternityForest" title="Bug reports">🐛</a></td>
51+
<td align="center"><a href="https://eternityforest.com"><img src="https://avatars.githubusercontent.com/u/758047?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Dunn</b></sub></a><br /><a href="https://github.com/lakscastro/shared-storage/issues?q=author%3AEternityForest" title="Bug reports">🐛</a> <a href="https://github.com/lakscastro/shared-storage/commits?author=EternityForest" title="Code">💻</a> <a href="https://github.com/lakscastro/shared-storage/commits?author=EternityForest" title="Documentation">📖</a></td>
5052
</tr>
5153
</table>
5254

android/src/main/kotlin/io/lakscastro/sharedstorage/storageaccessframework/DocumentFileApi.kt

Lines changed: 86 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ import io.lakscastro.sharedstorage.ROOT_CHANNEL
1414
import io.lakscastro.sharedstorage.SharedStoragePlugin
1515
import io.lakscastro.sharedstorage.plugin.*
1616
import io.lakscastro.sharedstorage.storageaccessframework.lib.*
17+
import kotlinx.coroutines.CoroutineScope
18+
import kotlinx.coroutines.Dispatchers
19+
import kotlinx.coroutines.launch
1720
import java.io.FileNotFoundException
1821
import java.io.IOException
1922
import java.io.InputStream
2023
import java.io.OutputStream
21-
import kotlinx.coroutines.CoroutineScope
22-
import kotlinx.coroutines.Dispatchers
23-
import kotlinx.coroutines.launch
2424

2525
/**
2626
* Aimed to implement strictly only the APIs already available from the native and original
@@ -75,57 +75,73 @@ internal class DocumentFileApi(private val plugin: SharedStoragePlugin) :
7575
)
7676
}
7777
PERSISTED_URI_PERMISSIONS ->
78-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
79-
persistedUriPermissions(result)
80-
}
78+
persistedUriPermissions(result)
8179
RELEASE_PERSISTABLE_URI_PERMISSION ->
82-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
83-
releasePersistableUriPermission(result, call.argument<String?>("uri") as String)
84-
}
80+
releasePersistableUriPermission(
81+
result,
82+
call.argument<String?>("uri") as String
83+
)
8584
FROM_TREE_URI ->
86-
if (Build.VERSION.SDK_INT >= API_21) {
87-
result.success(
88-
createDocumentFileMap(
89-
documentFromUri(plugin.context, call.argument<String?>("uri") as String)
90-
)
85+
if (Build.VERSION.SDK_INT >= API_21) {
86+
result.success(
87+
createDocumentFileMap(
88+
documentFromUri(
89+
plugin.context,
90+
call.argument<String?>("uri") as String
91+
)
9192
)
92-
}
93+
)
94+
}
9395
CAN_WRITE ->
94-
if (Build.VERSION.SDK_INT >= API_21) {
95-
result.success(
96-
documentFromUri(plugin.context, call.argument<String?>("uri") as String)?.canWrite()
97-
)
98-
}
96+
if (Build.VERSION.SDK_INT >= API_21) {
97+
result.success(
98+
documentFromUri(
99+
plugin.context,
100+
call.argument<String?>("uri") as String
101+
)?.canWrite()
102+
)
103+
}
99104
CAN_READ ->
100-
if (Build.VERSION.SDK_INT >= API_21) {
101-
val uri = call.argument<String?>("uri") as String
105+
if (Build.VERSION.SDK_INT >= API_21) {
106+
val uri = call.argument<String?>("uri") as String
102107

103-
result.success(documentFromUri(plugin.context, uri)?.canRead())
104-
}
108+
result.success(documentFromUri(plugin.context, uri)?.canRead())
109+
}
105110
LENGTH ->
106111
if (Build.VERSION.SDK_INT >= API_21) {
107112
result.success(
108-
documentFromUri(plugin.context, call.argument<String?>("uri") as String)?.length()
113+
documentFromUri(
114+
plugin.context,
115+
call.argument<String?>("uri") as String
116+
)?.length()
109117
)
110118
}
111119
EXISTS ->
112120
if (Build.VERSION.SDK_INT >= API_21) {
113121
result.success(
114-
documentFromUri(plugin.context, call.argument<String?>("uri") as String)?.exists()
122+
documentFromUri(
123+
plugin.context,
124+
call.argument<String?>("uri") as String
125+
)?.exists()
115126
)
116127
}
117128
DELETE ->
118129
if (Build.VERSION.SDK_INT >= API_21) {
119130
result.success(
120-
documentFromUri(plugin.context, call.argument<String?>("uri") as String)?.delete()
131+
documentFromUri(
132+
plugin.context,
133+
call.argument<String?>("uri") as String
134+
)?.delete()
121135
)
122136
}
123137
LAST_MODIFIED ->
124138
if (Build.VERSION.SDK_INT >= API_21) {
125-
result.success(
126-
documentFromUri(plugin.context, call.argument<String?>("uri") as String)
127-
?.lastModified()
139+
val document = documentFromUri(
140+
plugin.context,
141+
call.argument<String?>("uri") as String
128142
)
143+
144+
result.success(document?.lastModified())
129145
}
130146
CREATE_DIRECTORY -> {
131147
if (Build.VERSION.SDK_INT >= API_21) {
@@ -146,7 +162,12 @@ internal class DocumentFileApi(private val plugin: SharedStoragePlugin) :
146162
val displayName = call.argument<String?>("displayName") as String
147163

148164
result.success(
149-
createDocumentFileMap(documentFromUri(plugin.context, uri)?.findFile(displayName))
165+
createDocumentFileMap(
166+
documentFromUri(
167+
plugin.context,
168+
uri
169+
)?.findFile(displayName)
170+
)
150171
)
151172
}
152173
}
@@ -165,9 +186,9 @@ internal class DocumentFileApi(private val plugin: SharedStoragePlugin) :
165186
}
166187
} else {
167188
result.notSupported(
168-
RENAME_TO,
169-
API_21,
170-
mapOf("uri" to "$uri", "destination" to "$destination")
189+
RENAME_TO,
190+
API_21,
191+
mapOf("uri" to "$uri", "destination" to "$destination")
171192
)
172193
}
173194
}
@@ -180,8 +201,13 @@ internal class DocumentFileApi(private val plugin: SharedStoragePlugin) :
180201
val success = renameTo(displayName)
181202

182203
result.success(
183-
if (success) createDocumentFileMap(documentFromUri(plugin.context, this.uri)!!)
184-
else null
204+
if (success) createDocumentFileMap(
205+
documentFromUri(
206+
plugin.context,
207+
this.uri
208+
)!!
209+
)
210+
else null
185211
)
186212
}
187213
} else {
@@ -235,9 +261,9 @@ internal class DocumentFileApi(private val plugin: SharedStoragePlugin) :
235261

236262
if (Build.VERSION.SDK_INT >= API_26) {
237263
putExtra(
238-
if (Build.VERSION.SDK_INT >= API_26) DocumentsContract.EXTRA_INITIAL_URI
239-
else DOCUMENTS_CONTRACT_EXTRA_INITIAL_URI,
240-
tree?.uri
264+
if (Build.VERSION.SDK_INT >= API_26) DocumentsContract.EXTRA_INITIAL_URI
265+
else DOCUMENTS_CONTRACT_EXTRA_INITIAL_URI,
266+
tree?.uri
241267
)
242268
}
243269
}
@@ -380,7 +406,9 @@ internal class DocumentFileApi(private val plugin: SharedStoragePlugin) :
380406
eventSink = events
381407

382408
when (args["event"]) {
383-
LIST_FILES -> listFilesEvent(eventSink, args)
409+
LIST_FILES -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
410+
listFilesEvent(eventSink, args)
411+
}
384412
}
385413
}
386414

@@ -393,42 +421,41 @@ internal class DocumentFileApi(private val plugin: SharedStoragePlugin) :
393421
private fun listFilesEvent(eventSink: EventChannel.EventSink?, args: Map<*, *>) {
394422
if (eventSink == null) return
395423

396-
val document =
397-
if (Build.VERSION.SDK_INT >= API_24) {
398-
documentFromUri(plugin.context, args["uri"] as String) ?: return
399-
} else {
400-
null
401-
}
424+
val columns = args["columns"] as List<*>
425+
val uri = Uri.parse(args["uri"] as String)
426+
val document = DocumentFile.fromTreeUri(plugin.context, uri)
402427

403428
if (document == null) {
404429
eventSink.error(
405-
EXCEPTION_NOT_SUPPORTED,
406-
"Android SDK must be greater or equal than [Build.VERSION_CODES.N]",
407-
"Got (Build.VERSION.SDK_INT): ${Build.VERSION.SDK_INT}"
430+
EXCEPTION_NOT_SUPPORTED,
431+
"Android SDK must be greater or equal than [Build.VERSION_CODES.N]",
432+
"Got (Build.VERSION.SDK_INT): ${Build.VERSION.SDK_INT}"
408433
)
409434
} else {
410-
val columns = args["columns"] as List<*>
411-
412435
if (!document.canRead()) {
413436
val error = "You cannot read a URI that you don't have read permissions"
414437

415438
Log.d("NO PERMISSION!!!", error)
416439

417-
eventSink.error(EXCEPTION_MISSING_PERMISSIONS, error, mapOf("uri" to args["uri"]))
440+
eventSink.error(
441+
EXCEPTION_MISSING_PERMISSIONS,
442+
error,
443+
mapOf("uri" to args["uri"])
444+
)
418445

419446
eventSink.endOfStream()
420447
} else {
421448
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
422449
CoroutineScope(Dispatchers.IO).launch {
423450
try {
424451
traverseDirectoryEntries(
425-
plugin.context.contentResolver,
426-
rootOnly = true,
427-
rootUri = document.uri,
428-
columns =
429-
columns
430-
.map { parseDocumentFileColumn(parseDocumentFileColumn(it as String)!!) }
431-
.toTypedArray()
452+
plugin.context.contentResolver,
453+
rootOnly = true,
454+
targetUri = document.uri,
455+
columns =
456+
columns
457+
.map { parseDocumentFileColumn(parseDocumentFileColumn(it as String)!!) }
458+
.toTypedArray()
432459
) { data, _ -> launch(Dispatchers.Main) { eventSink.success(data) } }
433460
} finally {
434461
launch(Dispatchers.Main) { eventSink.endOfStream() }

0 commit comments

Comments
 (0)