0
0
mirror of https://github.com/markusfisch/BinaryEye.git synced 2024-09-20 12:02:17 +02:00

Remove resolveActivity() for opening content

Because on Android 11+ resolveActivity() can no longer be used
to query if there's an app that can handle the intent for privacy
reasons.
This commit is contained in:
Markus Fisch 2021-05-07 22:15:38 +02:00
parent 792be87283
commit 455d329fff
2 changed files with 21 additions and 28 deletions

View File

@ -8,6 +8,7 @@ import de.markusfisch.android.binaryeye.app.alertDialog
import de.markusfisch.android.binaryeye.app.parseAndNormalizeUri
import de.markusfisch.android.binaryeye.app.prefs
import de.markusfisch.android.binaryeye.content.execShareIntent
import de.markusfisch.android.binaryeye.content.startIntent
import de.markusfisch.android.binaryeye.widget.toast
import java.net.URLEncoder
@ -15,33 +16,20 @@ object OpenOrSearchAction : IAction {
override val iconResId: Int = R.drawable.ic_action_search
override val titleResId: Int = R.string.search_web
override fun canExecuteOn(data: ByteArray): Boolean = false
override fun canExecuteOn(bytes: ByteArray): Boolean = false
override suspend fun execute(context: Context, data: ByteArray) {
val intent = openUri(context, String(data)) ?: return
context.execShareIntent(intent)
override suspend fun execute(context: Context, bytes: ByteArray) {
view(context, String(bytes), true)
}
private suspend fun openUri(
context: Context,
data: String,
search: Boolean = true
): Intent? {
val uri = parseAndNormalizeUri(data)
val intent = Intent(Intent.ACTION_VIEW, uri)
return when {
// It's okay to use `resolveActivity()` at API level 30+ here
// because ACTION_VIEW is defined in `<queries>` in the Manifest.
intent.resolveActivity(context.packageManager) != null -> intent
search -> getSearchIntent(context, data)
else -> {
context.toast(R.string.cannot_resolve_action)
null
}
private suspend fun view(context: Context, s: String, search: Boolean) {
val intent = Intent(Intent.ACTION_VIEW, parseAndNormalizeUri(s))
if (!context.startIntent(intent) && search) {
openSearch(context, s)
}
}
private suspend fun getSearchIntent(context: Context, query: String): Intent? {
private suspend fun openSearch(context: Context, query: String) {
val names = context.resources.getStringArray(
R.array.search_engines_names
).toMutableList()
@ -57,7 +45,7 @@ object OpenOrSearchAction : IAction {
setItems(names.toTypedArray()) { _, which ->
resume(urls[which] + URLEncoder.encode(query, "utf-8"))
}
} ?: return null
return openUri(context, queryUri, false)
} ?: return
view(context, queryUri, false)
}
}

View File

@ -12,6 +12,12 @@ import de.markusfisch.android.binaryeye.widget.toast
import java.io.File
fun Context.execShareIntent(intent: Intent) {
if (!startIntent(intent)) {
toast(R.string.cannot_resolve_action)
}
}
fun Context.startIntent(intent: Intent) = try {
// Avoid using `intent.resolveActivity()` at API level 30+ due
// to the new package visibility restrictions. In order for
// `resolveActivity()` to "see" another package, we would need
@ -20,11 +26,10 @@ fun Context.execShareIntent(intent: Intent) {
// an exception if the Intent cannot be resolved, it's much easier
// and more robust to just try and catch that exception if
// necessary.
try {
startActivity(intent)
} catch (e: ActivityNotFoundException) {
toast(R.string.cannot_resolve_action)
}
startActivity(intent)
true
} catch (e: ActivityNotFoundException) {
false
}
fun shareText(context: Context, text: String, type: String = "text/plain") {