I'm trying to wrap a java method from the android ...
# coroutines
c
I'm trying to wrap a java method from the android sdk in a coroutine. Interestingly, the java method executes a task but only invokes the callback on success. Does this mean I should also wrap it in a timeout? Is there another means to know the underlying task completed even it doesn't invoke my callback?
Copy code
suspendCancellableCoroutine { continuation ->
    MyJavaTaskWithCallback() { myValueOnlyOnSuccess ->
        continuation.resume(myValueOnlyOnSuccess)
    }
}
The actual android method - only runs callback if the scanner finds any paths
Copy code
public static void scanFile(Context context, String[] paths, String[] mimeTypes,
    OnScanCompletedListener callback) {
BackgroundThread.getExecutor().execute(() -> {
    try (ContentProviderClient client = context.getContentResolver()
            .acquireContentProviderClient(MediaStore.AUTHORITY)) {
        for (String path : paths) {
            final Uri uri = scanFileQuietly(client, new File(path));
            runCallBack(context, callback, path, uri);
        }
    }
});
}
s
only invokes the callback on success
Are you sure? My reading of the code is that the callback will always be called exactly once for each item in the
paths
array, regardless of success or failure. In that case, you can just count the callbacks and stop when you've had the expected number. Are you seeing something different from that when you run the code?
I think you could do something like this:
Copy code
suspend fun scan(context: Context, paths: Array<String>): Map<String, Uri?> {
  val results = callbackFlow {
    MediaScannerConnection.scanFile(context, paths, null) { path, uri ->
      trySend(path to uri)
    }
  }
  return results.take(paths.size).toList().toMap()
}