-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathDragAndDropExtensions.kt
More file actions
56 lines (46 loc) · 1.75 KB
/
DragAndDropExtensions.kt
File metadata and controls
56 lines (46 loc) · 1.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.itsaky.androidide.dnd
import android.content.ClipData
import android.content.ClipDescription
import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import android.view.DragEvent
import androidx.core.net.toUri
/**
* Checks if the [DragEvent] contains any URIs that can be imported into the project.
*/
fun DragEvent.hasImportableContent(context: Context): Boolean {
if (localState != null) return false
return when (action) {
DragEvent.ACTION_DROP -> {
val clip = clipData ?: return false
(0 until clip.itemCount).any { index ->
clip.getItemAt(index).toImportableExternalUris(context).isNotEmpty()
}
}
else -> clipDescription?.hasImportableMimeType() == true
}
}
/**
* Resolves the [ClipData.Item] to a list of external [Uri]s, ignoring internal application URIs.
*/
fun ClipData.Item.toImportableExternalUris(context: Context): List<Uri> {
return toExternalUris().filterNot { it.isInternalDragUri(context) }
}
private fun Uri.isInternalDragUri(context: Context): Boolean {
return authority == "${context.packageName}.providers.fileprovider"
}
private fun ClipData.Item.toExternalUris(): List<Uri> {
uri?.let { return listOf(it) }
val textContent = text?.toString() ?: return emptyList()
return textContent.lineSequence()
.map { it.trim() }
.map { it.toUri() }
.filter { it.scheme == ContentResolver.SCHEME_CONTENT || it.scheme == ContentResolver.SCHEME_FILE }
.toList()
}
private fun ClipDescription.hasImportableMimeType(): Boolean {
return hasMimeType(ClipDescription.MIMETYPE_TEXT_URILIST) ||
hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN) ||
hasMimeType("*/*")
}