diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index a24b65126..2fc1c8500 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -15,7 +15,7 @@ jobs:
- uses: subosito/flutter-action@v1
with:
channel: stable
- flutter-version: '2.8.1'
+ flutter-version: '2.10.1'
- name: Clone the repository.
uses: actions/checkout@v2
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index db2cefafe..5ea3f4a01 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -17,7 +17,7 @@ jobs:
- uses: subosito/flutter-action@v1
with:
channel: stable
- flutter-version: '2.8.1'
+ flutter-version: '2.10.1'
# Workaround for this Android Gradle Plugin issue (supposedly fixed in AGP 4.1):
# https://issuetracker.google.com/issues/144111441
@@ -52,12 +52,12 @@ jobs:
rm release.keystore.asc
mkdir outputs
(cd scripts/; ./apply_flavor_play.sh)
- flutter build appbundle -t lib/main_play.dart --flavor play --bundle-sksl-path shaders_2.8.1.sksl.json
+ flutter build appbundle -t lib/main_play.dart --flavor play --bundle-sksl-path shaders_2.10.1.sksl.json
cp build/app/outputs/bundle/playRelease/*.aab outputs
- flutter build apk -t lib/main_play.dart --flavor play --bundle-sksl-path shaders_2.8.1.sksl.json
+ flutter build apk -t lib/main_play.dart --flavor play --bundle-sksl-path shaders_2.10.1.sksl.json
cp build/app/outputs/apk/play/release/*.apk outputs
(cd scripts/; ./apply_flavor_izzy.sh)
- flutter build apk -t lib/main_izzy.dart --flavor izzy --split-per-abi --bundle-sksl-path shaders_2.8.1.sksl.json
+ flutter build apk -t lib/main_izzy.dart --flavor izzy --split-per-abi --bundle-sksl-path shaders_2.10.1.sksl.json
cp build/app/outputs/apk/izzy/release/*.apk outputs
rm $AVES_STORE_FILE
env:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3e4465e83..b799ded82 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,33 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
+## [v1.6.0] - 2022-02-22
+
+### Added
+
+- optional recycle bin to keep deleted items for 30 days
+- Viewer: actions to copy/move to album
+- Indonesian translation (thanks MeFinity)
+
+### Changed
+
+- Viewer: action menu reorganization
+- Viewer: `Export` action renamed to `Convert`
+- Viewer: actual size zoom level respects device pixel ratio
+- Viewer: allow zooming out small items to actual size
+- Collection: improved performance for sort/group by name
+- load previous top items on startup
+- locale independent colors for known filters
+- upgraded Flutter to stable v2.10.1
+
+### Removed
+
+- Map: connectivity check
+
+### Fixed
+
+- navigating from Album page when picking an item for another app
+
## [v1.5.11] - 2022-01-30
### Added
diff --git a/README.md b/README.md
index c7dec61cd..4f17a28bb 100644
--- a/README.md
+++ b/README.md
@@ -85,7 +85,7 @@ At this stage this project does *not* accept PRs, except for translations.
### Translations
-If you want to translate this app in your language and share the result, [there is a guide](https://github.com/deckerst/aves/wiki/Contributing-to-Translations). English, Korean and French are already handled by me. Russian, German and Spanish are handled by generous volunteers.
+If you want to translate this app in your language and share the result, [there is a guide](https://github.com/deckerst/aves/wiki/Contributing-to-Translations). English, Korean and French are already handled by me. Russian, German, Spanish, Portuguese & Indonesian are handled by generous volunteers.
### Donations
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 8acc2d333..fed4ca45f 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -141,7 +141,7 @@ repositories {
}
dependencies {
- implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.exifinterface:exifinterface:1.3.3'
implementation 'androidx.multidex:multidex:2.0.1'
@@ -152,10 +152,10 @@ dependencies {
implementation 'com.github.deckerst:Android-TiffBitmapFactory:876e53870a'
// forked, built by JitPack, cf https://jitpack.io/p/deckerst/pixymeta-android
implementation 'com.github.deckerst:pixymeta-android:706bd73d6e'
- implementation 'com.github.bumptech.glide:glide:4.12.0'
+ implementation 'com.github.bumptech.glide:glide:4.13.0'
kapt 'androidx.annotation:annotation:1.3.0'
- kapt 'com.github.bumptech.glide:compiler:4.12.0'
+ kapt 'com.github.bumptech.glide:compiler:4.13.0'
compileOnly rootProject.findProject(':streams_channel')
}
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/AnalysisService.kt b/android/app/src/main/kotlin/deckers/thibault/aves/AnalysisService.kt
index 409f361bd..01752c888 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/AnalysisService.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/AnalysisService.kt
@@ -159,10 +159,10 @@ class AnalysisService : MethodChannel.MethodCallHandler, Service() {
COMMAND_START -> {
runBlocking {
FlutterUtils.runOnUiThread {
- val contentIds = data.get(KEY_CONTENT_IDS)?.takeIf { it is IntArray }?.let { (it as IntArray).toList() }
+ val entryIds = data.get(KEY_ENTRY_IDS)?.takeIf { it is IntArray }?.let { (it as IntArray).toList() }
backgroundChannel?.invokeMethod(
"start", hashMapOf(
- "contentIds" to contentIds,
+ "entryIds" to entryIds,
"force" to data.getBoolean(KEY_FORCE),
)
)
@@ -197,7 +197,7 @@ class AnalysisService : MethodChannel.MethodCallHandler, Service() {
const val KEY_COMMAND = "command"
const val COMMAND_START = "start"
const val COMMAND_STOP = "stop"
- const val KEY_CONTENT_IDS = "content_ids"
+ const val KEY_ENTRY_IDS = "entry_ids"
const val KEY_FORCE = "force"
}
}
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/SearchSuggestionsProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/SearchSuggestionsProvider.kt
index ca9ba2fa7..8d4472dbe 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/SearchSuggestionsProvider.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/SearchSuggestionsProvider.kt
@@ -17,15 +17,15 @@ import deckers.thibault.aves.utils.LogUtils
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.*
import java.util.*
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
class SearchSuggestionsProvider : MethodChannel.MethodCallHandler, ContentProvider() {
+ private val defaultScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
+
override fun query(uri: Uri, projection: Array?, selection: String?, selectionArgs: Array?, sortOrder: String?): Cursor? {
return selectionArgs?.firstOrNull()?.let { query ->
// Samsung Finder does not support:
@@ -77,29 +77,34 @@ class SearchSuggestionsProvider : MethodChannel.MethodCallHandler, ContentProvid
val backgroundChannel = MethodChannel(messenger, BACKGROUND_CHANNEL)
backgroundChannel.setMethodCallHandler(this)
- return suspendCoroutine { cont ->
- GlobalScope.launch {
- FlutterUtils.runOnUiThread {
- backgroundChannel.invokeMethod("getSuggestions", hashMapOf(
- "query" to query,
- "locale" to Locale.getDefault().toString(),
- "use24hour" to DateFormat.is24HourFormat(context),
- ), object : MethodChannel.Result {
- override fun success(result: Any?) {
- @Suppress("unchecked_cast")
- cont.resume(result as List)
- }
+ try {
+ return suspendCoroutine { cont ->
+ defaultScope.launch {
+ FlutterUtils.runOnUiThread {
+ backgroundChannel.invokeMethod("getSuggestions", hashMapOf(
+ "query" to query,
+ "locale" to Locale.getDefault().toString(),
+ "use24hour" to DateFormat.is24HourFormat(context),
+ ), object : MethodChannel.Result {
+ override fun success(result: Any?) {
+ @Suppress("unchecked_cast")
+ cont.resume(result as List)
+ }
- override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
- cont.resumeWithException(Exception("$errorCode: $errorMessage\n$errorDetails"))
- }
+ override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
+ cont.resumeWithException(Exception("$errorCode: $errorMessage\n$errorDetails"))
+ }
- override fun notImplemented() {
- cont.resumeWithException(NotImplementedError("getSuggestions"))
- }
- })
+ override fun notImplemented() {
+ cont.resumeWithException(NotImplementedError("getSuggestions"))
+ }
+ })
+ }
}
}
+ } catch (e: Exception) {
+ Log.e(LOG_TAG, "failed to get suggestions", e)
+ return ArrayList()
}
}
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt
index b0d144906..7f083ae55 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AnalysisHandler.kt
@@ -16,14 +16,14 @@ import deckers.thibault.aves.utils.ContextUtils.isMyServiceRunning
import deckers.thibault.aves.utils.LogUtils
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
class AnalysisHandler(private val activity: Activity, private val onAnalysisCompleted: () -> Unit) : MethodChannel.MethodCallHandler, AnalysisServiceListener {
+ private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
+
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
- "registerCallback" -> GlobalScope.launch(Dispatchers.IO) { Coresult.safe(call, result, ::registerCallback) }
+ "registerCallback" -> ioScope.launch { Coresult.safe(call, result, ::registerCallback) }
"startService" -> Coresult.safe(call, result, ::startAnalysis)
else -> result.notImplemented()
}
@@ -52,12 +52,12 @@ class AnalysisHandler(private val activity: Activity, private val onAnalysisComp
}
// can be null or empty
- val contentIds = call.argument>("contentIds")
+ val entryIds = call.argument>("entryIds")
if (!activity.isMyServiceRunning(AnalysisService::class.java)) {
val intent = Intent(activity, AnalysisService::class.java)
intent.putExtra(AnalysisService.KEY_COMMAND, AnalysisService.COMMAND_START)
- intent.putExtra(AnalysisService.KEY_CONTENT_IDS, contentIds?.toIntArray())
+ intent.putExtra(AnalysisService.KEY_ENTRY_IDS, entryIds?.toIntArray())
intent.putExtra(AnalysisService.KEY_FORCE, force)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
activity.startForegroundService(intent)
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt
index f56a7f838..ee0527d6c 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt
@@ -33,26 +33,26 @@ import deckers.thibault.aves.utils.LogUtils
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
import java.io.File
import java.util.*
import kotlin.collections.ArrayList
import kotlin.math.roundToInt
class AppAdapterHandler(private val context: Context) : MethodCallHandler {
+ private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
+
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
- "getPackages" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getPackages) }
- "getAppIcon" -> GlobalScope.launch(Dispatchers.IO) { safeSuspend(call, result, ::getAppIcon) }
- "copyToClipboard" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::copyToClipboard) }
+ "getPackages" -> ioScope.launch { safe(call, result, ::getPackages) }
+ "getAppIcon" -> ioScope.launch { safeSuspend(call, result, ::getAppIcon) }
+ "copyToClipboard" -> ioScope.launch { safe(call, result, ::copyToClipboard) }
"edit" -> safe(call, result, ::edit)
"open" -> safe(call, result, ::open)
"openMap" -> safe(call, result, ::openMap)
"setAs" -> safe(call, result, ::setAs)
"share" -> safe(call, result, ::share)
- "pinShortcut" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::pinShortcut) }
+ "pinShortcut" -> ioScope.launch { safe(call, result, ::pinShortcut) }
else -> result.notImplemented()
}
}
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt
index 4aebabf55..82c84520e 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt
@@ -32,33 +32,33 @@ import deckers.thibault.aves.utils.UriUtils.tryParseId
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
+import io.flutter.util.PathUtils
+import kotlinx.coroutines.*
import org.beyka.tiffbitmapfactory.TiffBitmapFactory
import java.io.IOException
-import java.util.*
class DebugHandler(private val context: Context) : MethodCallHandler {
+ private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
+
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
"crash" -> Handler(Looper.getMainLooper()).postDelayed({ throw TestException() }, 50)
"exception" -> throw TestException()
"safeException" -> safe(call, result) { _, _ -> throw TestException() }
- "exceptionInCoroutine" -> GlobalScope.launch(Dispatchers.IO) { throw TestException() }
- "safeExceptionInCoroutine" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result) { _, _ -> throw TestException() } }
+ "exceptionInCoroutine" -> ioScope.launch { throw TestException() }
+ "safeExceptionInCoroutine" -> ioScope.launch { safe(call, result) { _, _ -> throw TestException() } }
- "getContextDirs" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getContextDirs) }
+ "getContextDirs" -> ioScope.launch { safe(call, result, ::getContextDirs) }
"getCodecs" -> safe(call, result, ::getCodecs)
"getEnv" -> safe(call, result, ::getEnv)
- "getBitmapFactoryInfo" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getBitmapFactoryInfo) }
- "getContentResolverMetadata" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getContentResolverMetadata) }
- "getExifInterfaceMetadata" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getExifInterfaceMetadata) }
- "getMediaMetadataRetrieverMetadata" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getMediaMetadataRetrieverMetadata) }
- "getMetadataExtractorSummary" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getMetadataExtractorSummary) }
- "getPixyMetadata" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getPixyMetadata) }
- "getTiffStructure" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getTiffStructure) }
+ "getBitmapFactoryInfo" -> ioScope.launch { safe(call, result, ::getBitmapFactoryInfo) }
+ "getContentResolverMetadata" -> ioScope.launch { safe(call, result, ::getContentResolverMetadata) }
+ "getExifInterfaceMetadata" -> ioScope.launch { safe(call, result, ::getExifInterfaceMetadata) }
+ "getMediaMetadataRetrieverMetadata" -> ioScope.launch { safe(call, result, ::getMediaMetadataRetrieverMetadata) }
+ "getMetadataExtractorSummary" -> ioScope.launch { safe(call, result, ::getMetadataExtractorSummary) }
+ "getPixyMetadata" -> ioScope.launch { safe(call, result, ::getPixyMetadata) }
+ "getTiffStructure" -> ioScope.launch { safe(call, result, ::getTiffStructure) }
else -> result.notImplemented()
}
}
@@ -69,6 +69,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
"filesDir" to context.filesDir,
"obbDir" to context.obbDir,
"externalCacheDir" to context.externalCacheDir,
+ "externalFilesDir" to context.getExternalFilesDir(null),
).apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
putAll(
@@ -81,7 +82,18 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
put("dataDir", context.dataDir)
}
- }.mapValues { it.value?.path }
+ }.mapValues { it.value?.path }.toMutableMap()
+ dirs["externalCacheDirs"] = context.externalCacheDirs.joinToString { it.path }
+ dirs["externalFilesDirs"] = context.getExternalFilesDirs(null).joinToString { it.path }
+
+ // used by flutter plugin `path_provider`
+ dirs.putAll(
+ hashMapOf(
+ "flutter / cacheDir" to PathUtils.getCacheDirectory(context),
+ "flutter / dataDir" to PathUtils.getDataDirectory(context),
+ "flutter / filesDir" to PathUtils.getFilesDir(context),
+ )
+ )
result.success(dirs)
}
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt
index 61fa7d5c0..d34ef9eec 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt
@@ -34,20 +34,20 @@ import deckers.thibault.aves.utils.StorageUtils
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
import java.io.File
import java.io.InputStream
import java.util.*
class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
+ private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
+
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
- "getExifThumbnails" -> GlobalScope.launch(Dispatchers.IO) { safeSuspend(call, result, ::getExifThumbnails) }
- "extractMotionPhotoVideo" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::extractMotionPhotoVideo) }
- "extractVideoEmbeddedPicture" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::extractVideoEmbeddedPicture) }
- "extractXmpDataProp" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::extractXmpDataProp) }
+ "getExifThumbnails" -> ioScope.launch { safeSuspend(call, result, ::getExifThumbnails) }
+ "extractMotionPhotoVideo" -> ioScope.launch { safe(call, result, ::extractMotionPhotoVideo) }
+ "extractVideoEmbeddedPicture" -> ioScope.launch { safe(call, result, ::extractVideoEmbeddedPicture) }
+ "extractXmpDataProp" -> ioScope.launch { safe(call, result, ::extractXmpDataProp) }
else -> result.notImplemented()
}
}
@@ -210,7 +210,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
"mimeType" to mimeType,
)
if (isImage(mimeType) || isVideo(mimeType)) {
- GlobalScope.launch(Dispatchers.IO) {
+ ioScope.launch {
ContentImageProvider().fetchSingle(context, uri, mimeType, object : ImageProvider.ImageOpCallback {
override fun onSuccess(fields: FieldMap) {
resultFields.putAll(fields)
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GeocodingHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GeocodingHandler.kt
index ddb100edd..0821058f3 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GeocodingHandler.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GeocodingHandler.kt
@@ -6,9 +6,7 @@ import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
import java.io.IOException
import java.util.*
@@ -16,11 +14,12 @@ import java.util.*
// - `geocoder` is unmaintained
// - `geocoding` method does not return `addressLine` (v2.0.0)
class GeocodingHandler(private val context: Context) : MethodCallHandler {
+ private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private var geocoder: Geocoder? = null
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
- "getAddress" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getAddress) }
+ "getAddress" -> ioScope.launch { safe(call, result, ::getAddress) }
else -> result.notImplemented()
}
}
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt
index 48560f9a5..c4b701327 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/GlobalSearchHandler.kt
@@ -7,14 +7,14 @@ import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
class GlobalSearchHandler(private val context: Context) : MethodCallHandler {
+ private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
+
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
- "registerCallback" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::registerCallback) }
+ "registerCallback" -> ioScope.launch { safe(call, result, ::registerCallback) }
else -> result.notImplemented()
}
}
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFileHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFileHandler.kt
index 9dddda6b1..44c0cc405 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFileHandler.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFileHandler.kt
@@ -21,24 +21,23 @@ import deckers.thibault.aves.utils.StorageUtils.ensureTrailingSeparator
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
import kotlin.math.roundToInt
class MediaFileHandler(private val activity: Activity) : MethodCallHandler {
+ private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private val density = activity.resources.displayMetrics.density
private val regionFetcher = RegionFetcher(activity)
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
- "getEntry" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getEntry) }
- "getThumbnail" -> GlobalScope.launch(Dispatchers.IO) { safeSuspend(call, result, ::getThumbnail) }
- "getRegion" -> GlobalScope.launch(Dispatchers.IO) { safeSuspend(call, result, ::getRegion) }
+ "getEntry" -> ioScope.launch { safe(call, result, ::getEntry) }
+ "getThumbnail" -> ioScope.launch { safeSuspend(call, result, ::getThumbnail) }
+ "getRegion" -> ioScope.launch { safeSuspend(call, result, ::getRegion) }
"cancelFileOp" -> safe(call, result, ::cancelFileOp)
- "captureFrame" -> GlobalScope.launch(Dispatchers.IO) { safeSuspend(call, result, ::captureFrame) }
- "clearSizedThumbnailDiskCache" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::clearSizedThumbnailDiskCache) }
+ "captureFrame" -> ioScope.launch { safeSuspend(call, result, ::captureFrame) }
+ "clearSizedThumbnailDiskCache" -> ioScope.launch { safe(call, result, ::clearSizedThumbnailDiskCache) }
else -> result.notImplemented()
}
}
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaStoreHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaStoreHandler.kt
index b20b6b802..a8761be8f 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaStoreHandler.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaStoreHandler.kt
@@ -8,22 +8,25 @@ import deckers.thibault.aves.model.provider.MediaStoreImageProvider
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
class MediaStoreHandler(private val context: Context) : MethodCallHandler {
+ private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
+
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
- "checkObsoleteContentIds" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::checkObsoleteContentIds) }
- "checkObsoletePaths" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::checkObsoletePaths) }
- "scanFile" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::scanFile) }
+ "checkObsoleteContentIds" -> ioScope.launch { safe(call, result, ::checkObsoleteContentIds) }
+ "checkObsoletePaths" -> ioScope.launch { safe(call, result, ::checkObsoletePaths) }
+ "scanFile" -> ioScope.launch { safe(call, result, ::scanFile) }
else -> result.notImplemented()
}
}
private fun checkObsoleteContentIds(call: MethodCall, result: MethodChannel.Result) {
- val knownContentIds = call.argument>("knownContentIds")
+ val knownContentIds = call.argument>("knownContentIds")
if (knownContentIds == null) {
result.error("checkObsoleteContentIds-args", "failed because of missing arguments", null)
return
@@ -32,7 +35,7 @@ class MediaStoreHandler(private val context: Context) : MethodCallHandler {
}
private fun checkObsoletePaths(call: MethodCall, result: MethodChannel.Result) {
- val knownPathById = call.argument