Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Activity
import android.app.Activity.RESULT_OK
import android.content.ActivityNotFoundException
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.net.Uri
Expand All @@ -19,8 +20,11 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File

interface ActivityProvider : CoroutineScope {
interface ContextProvider : CoroutineScope {
val activity: Activity?

val applicationContext: Context?

fun logDebug(message: String, e: Throwable? = null)
@MainThread
fun openFile(fileInfo: Map<String, String>)
Expand All @@ -29,7 +33,7 @@ interface ActivityProvider : CoroutineScope {
}

class FilePickerWritableImpl(
private val plugin: ActivityProvider
private val plugin: ContextProvider
) : PluginRegistry.ActivityResultListener, PluginRegistry.NewIntentListener {

companion object {
Expand Down Expand Up @@ -175,8 +179,8 @@ class FilePickerWritableImpl(
fileUri: Uri,
initialFileContent: File
) {
val activity = requireActivity()
val contentResolver = activity.applicationContext.contentResolver
val context = requireContext()
val contentResolver = context.applicationContext.contentResolver
val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
contentResolver.takePersistableUriPermission(fileUri, takeFlags)
Expand Down Expand Up @@ -213,9 +217,9 @@ class FilePickerWritableImpl(

@MainThread
private suspend fun copyContentUriAndReturnFileInfo(fileUri: Uri): Map<String, String> {
val activity = requireActivity()
val context = requireContext()

val contentResolver = activity.applicationContext.contentResolver
val contentResolver = context.applicationContext.contentResolver

return withContext(Dispatchers.IO) {
var persistable = false
Expand All @@ -235,7 +239,7 @@ class FilePickerWritableImpl(
// use a maximum of 20 characters.
// It's just a temp file name so does not really matter.
fileName.take(20),
null, activity.cacheDir
null, context.cacheDir
)
plugin.logDebug("Copy file $fileUri to $tempFile")
contentResolver.openInputStream(fileUri).use { input ->
Expand Down Expand Up @@ -301,8 +305,8 @@ class FilePickerWritableImpl(
throw FilePickerException("File at source not found. $file")
}
val fileUri = Uri.parse(identifier)
val activity = requireActivity()
val contentResolver = activity.contentResolver
val context = requireContext()
val contentResolver = context.contentResolver
withContext(Dispatchers.IO) {
// with Android 10 and later, use wt
// https://issuetracker.google.com/issues/135714729?pli=1
Expand All @@ -319,16 +323,16 @@ class FilePickerWritableImpl(
}

fun disposeIdentifier(identifier: String) {
val activity = requireActivity()
val contentResolver = activity.applicationContext.contentResolver
val context = requireContext()
val contentResolver = context.applicationContext.contentResolver
val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
contentResolver.releasePersistableUriPermission(Uri.parse(identifier), takeFlags)
}

fun disposeAllIdentifiers() {
val activity = requireActivity()
val contentResolver = activity.applicationContext.contentResolver
val context = requireContext()
val contentResolver = context.applicationContext.contentResolver
val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
for (permission in contentResolver.persistedUriPermissions) {
Expand All @@ -340,6 +344,9 @@ class FilePickerWritableImpl(
private fun requireActivity() = (plugin.activity
?: throw FilePickerException("Illegal state, expected activity to be there."))

private fun requireContext() = (plugin.activity ?: plugin.applicationContext
?: throw FilePickerException("Illegal state, expected application context or activity to be there."))

private val CONTENT_PROVIDER_SCHEMES = setOf(
ContentResolver.SCHEME_CONTENT,
ContentResolver.SCHEME_FILE,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package codeux.design.filepicker.file_picker_writable

import android.app.Activity
import android.content.Context
import android.net.Uri
import android.util.Log
import androidx.annotation.MainThread
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
Expand All @@ -25,7 +25,7 @@ private const val TAG = "FilePickerWritable"
/** FilePickerWritablePlugin */
class FilePickerWritablePlugin : FlutterPlugin, MethodCallHandler,
ActivityAware,
ActivityProvider, CoroutineScope by MainScope() {
ContextProvider, CoroutineScope by MainScope() {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
Expand All @@ -34,23 +34,26 @@ class FilePickerWritablePlugin : FlutterPlugin, MethodCallHandler,
private val impl: FilePickerWritableImpl = FilePickerWritableImpl(this)
private var currentBinding: ActivityPluginBinding? = null

override var applicationContext: Context? = null

private val eventQueue = LinkedList<Map<String, String>>()
private var eventSink: EventChannel.EventSink? = null

override fun onAttachedToEngine(
@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding
) {
initializePlugin(flutterPluginBinding.binaryMessenger)
initializePlugin(flutterPluginBinding)
}

private fun initializePlugin(binaryMessenger: BinaryMessenger) {
private fun initializePlugin(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
applicationContext = flutterPluginBinding.applicationContext
channel = MethodChannel(
binaryMessenger,
flutterPluginBinding.binaryMessenger,
"design.codeux.file_picker_writable"
)
channel.setMethodCallHandler(this)
EventChannel(
binaryMessenger,
flutterPluginBinding.binaryMessenger,
"design.codeux.file_picker_writable/events"
).setStreamHandler(object :
EventChannel.StreamHandler {
Expand Down