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
4 changes: 4 additions & 0 deletions packages/file_selector/file_selector_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.5.2+6

* Updates internal implementation to use Kotlin Pigeon.

## 0.5.2+5

* Updates build files from Groovy to Kotlin.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

group = "dev.flutter.packages.file_selector_android"
version = "1.0"

buildscript {
val kotlinVersion = "2.3.0"
repositories {
google()
mavenCentral()
}

dependencies {
classpath("com.android.tools.build:gradle:8.13.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
}
}

Expand All @@ -21,6 +25,13 @@ allprojects {

plugins {
id("com.android.library")
id("kotlin-android")
}

kotlin {
compilerOptions {
jvmTarget = JvmTarget.fromTarget(JavaVersion.VERSION_17.toString())
}
}

android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
fileSelectorApi = new FileSelectorApiImpl(binding);
GeneratedFileSelectorApi.FileSelectorApi.setUp(
pluginBinding.getBinaryMessenger(), fileSelectorApi);
FileSelectorApi.Companion.setUp(pluginBinding.getBinaryMessenger(), fileSelectorApi);
}

@Override
Expand All @@ -45,8 +44,7 @@ public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBindin
fileSelectorApi.setActivityPluginBinding(binding);
} else {
fileSelectorApi = new FileSelectorApiImpl(binding);
GeneratedFileSelectorApi.FileSelectorApi.setUp(
pluginBinding.getBinaryMessenger(), fileSelectorApi);
FileSelectorApi.Companion.setUp(pluginBinding.getBinaryMessenger(), fileSelectorApi);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import kotlin.Result;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;

public class FileSelectorApiImpl implements GeneratedFileSelectorApi.FileSelectorApi {
public class FileSelectorApiImpl implements FileSelectorApi {
private static final String TAG = "FileSelectorApiImpl";
// Request code for selecting a file.
private static final int OPEN_FILE = 221;
Expand Down Expand Up @@ -91,9 +95,8 @@ public FileSelectorApiImpl(@NonNull ActivityPluginBinding activityPluginBinding)
@Override
public void openFile(
@Nullable String initialDirectory,
@NonNull GeneratedFileSelectorApi.FileTypes allowedTypes,
@NonNull
GeneratedFileSelectorApi.NullableResult<GeneratedFileSelectorApi.FileResponse> result) {
@NonNull FileTypes allowedTypes,
@NonNull Function1<? super Result<FileResponse>, Unit> callback) {
final Intent intent = objectFactory.newIntent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);

Expand All @@ -111,32 +114,37 @@ public void onResult(int resultCode, @Nullable Intent data) {
final Uri uri = data.getData();
if (uri == null) {
// No data retrieved from opening file.
result.error(new Exception("Failed to retrieve data from opening file."));
ResultUtilsKt.<FileResponse>completeWithError(
callback, new Exception("Failed to retrieve data from opening file."));
return;
}

final GeneratedFileSelectorApi.FileResponse file = toFileResponse(uri);
final FileResponse file = toFileResponse(uri);
if (file != null) {
result.success(file);
ResultUtilsKt.<FileResponse>completeWithValue(callback, file);
} else {
result.error(new Exception("Failed to read file: " + uri));
ResultUtilsKt.completeWithError(
callback, new Exception("Failed to read file: " + uri));
}
} else {
result.success(null);
ResultUtilsKt.completeWithValue(callback, null);
}
}
});
} catch (Exception exception) {
result.error(exception);
ResultUtilsKt.completeWithError(callback, exception);
}
}

@Override
public void openFiles(
@Nullable String initialDirectory,
@NonNull GeneratedFileSelectorApi.FileTypes allowedTypes,
@NonNull FileTypes allowedTypes,
@NonNull
GeneratedFileSelectorApi.Result<List<GeneratedFileSelectorApi.FileResponse>> result) {
Function1<
? super @NotNull Result<? extends @NotNull List<@NotNull FileResponse>>, @NotNull
Unit>
callback) {
final Intent intent = objectFactory.newIntent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
Expand All @@ -155,46 +163,46 @@ public void onResult(int resultCode, @Nullable Intent data) {
// Only one file was returned.
final Uri uri = data.getData();
if (uri != null) {
final GeneratedFileSelectorApi.FileResponse file = toFileResponse(uri);
final FileResponse file = toFileResponse(uri);
if (file != null) {
result.success(Collections.singletonList(file));
ResultUtilsKt.completeWithValue(callback, Collections.singletonList(file));
} else {
result.error(new Exception("Failed to read file: " + uri));
ResultUtilsKt.completeWithError(
callback, new Exception("Failed to read file: " + uri));
}
}

// Multiple files were returned.
final ClipData clipData = data.getClipData();
if (clipData != null) {
final List<GeneratedFileSelectorApi.FileResponse> files =
new ArrayList<>(clipData.getItemCount());
final List<FileResponse> files = new ArrayList<>(clipData.getItemCount());
for (int i = 0; i < clipData.getItemCount(); i++) {
final ClipData.Item clipItem = clipData.getItemAt(i);
final GeneratedFileSelectorApi.FileResponse file =
toFileResponse(clipItem.getUri());
final FileResponse file = toFileResponse(clipItem.getUri());
if (file != null) {
files.add(file);
} else {
result.error(new Exception("Failed to read file: " + uri));
ResultUtilsKt.completeWithError(
callback, new Exception("Failed to read file: " + uri));
return;
}
}
result.success(files);
ResultUtilsKt.completeWithValue(callback, files);
}
} else {
result.success(new ArrayList<>());
ResultUtilsKt.completeWithValue(callback, new ArrayList<>());
}
}
});
} catch (Exception exception) {
result.error(exception);
ResultUtilsKt.completeWithError(callback, exception);
}
}

@Override
public void getDirectoryPath(
@Nullable String initialDirectory,
@NonNull GeneratedFileSelectorApi.NullableResult<String> result) {
@NonNull Function1<? super @NotNull Result<String>, @NotNull Unit> callback) {
final Intent intent = objectFactory.newIntent(Intent.ACTION_OPEN_DOCUMENT_TREE);
trySetInitialDirectory(intent, initialDirectory);

Expand All @@ -209,7 +217,8 @@ public void onResult(int resultCode, @Nullable Intent data) {
final Uri uri = data.getData();
if (uri == null) {
// No data retrieved from opening directory.
result.error(new Exception("Failed to retrieve data from opening directory."));
ResultUtilsKt.completeWithError(
callback, new Exception("Failed to retrieve data from opening directory."));
return;
}

Expand All @@ -219,17 +228,17 @@ public void onResult(int resultCode, @Nullable Intent data) {
try {
final String path =
FileUtils.getPathFromUri(activityPluginBinding.getActivity(), docUri);
result.success(path);
ResultUtilsKt.completeWithValue(callback, path);
} catch (UnsupportedOperationException exception) {
result.error(exception);
ResultUtilsKt.completeWithError(callback, exception);
}
} else {
result.success(null);
ResultUtilsKt.<String>completeWithValue(callback, null);
}
}
});
} catch (Exception exception) {
result.error(exception);
ResultUtilsKt.completeWithError(callback, exception);
}
}

Expand All @@ -240,8 +249,7 @@ public void setActivityPluginBinding(@Nullable ActivityPluginBinding activityPlu
// Setting the mimeType with `setType` is required when opening files. This handles setting the
// mimeType based on the `mimeTypes` list and converts extensions to mimeTypes.
// See https://developer.android.com/guide/components/intents-common#OpenFile
private void setMimeTypes(
@NonNull Intent intent, @NonNull GeneratedFileSelectorApi.FileTypes allowedTypes) {
private void setMimeTypes(@NonNull Intent intent, @NonNull FileTypes allowedTypes) {
final Set<String> allMimetypes = new HashSet<>();
allMimetypes.addAll(allowedTypes.getMimeTypes());
allMimetypes.addAll(tryConvertExtensionsToMimetypes(allowedTypes.getExtensions()));
Expand Down Expand Up @@ -307,7 +315,7 @@ public boolean onActivityResult(int requestCode, int resultCode, @Nullable Inten
}

@Nullable
GeneratedFileSelectorApi.FileResponse toFileResponse(@NonNull Uri uri) {
FileResponse toFileResponse(@NonNull Uri uri) {
if (activityPluginBinding == null) {
Log.d(TAG, "Activity is not available.");
return null;
Expand Down Expand Up @@ -351,7 +359,7 @@ GeneratedFileSelectorApi.FileResponse toFileResponse(@NonNull Uri uri) {
}

String uriPath;
GeneratedFileSelectorApi.FileSelectorNativeException nativeError = null;
FileSelectorNativeException nativeError = null;

try {
uriPath = FileUtils.getPathFromCopyOfFileFromUri(activityPluginBinding.getActivity(), uri);
Expand All @@ -370,20 +378,11 @@ GeneratedFileSelectorApi.FileResponse toFileResponse(@NonNull Uri uri) {
} catch (IllegalArgumentException e) {
uriPath = FILE_SELECTOR_EXCEPTION_PLACEHOLDER_PATH;
nativeError =
new GeneratedFileSelectorApi.FileSelectorNativeException.Builder()
.setMessage(e.getMessage() == null ? "" : e.getMessage())
.setFileSelectorExceptionCode(
GeneratedFileSelectorApi.FileSelectorExceptionCode.ILLEGAL_ARGUMENT_EXCEPTION)
.build();
new FileSelectorNativeException(
FileSelectorExceptionCode.ILLEGAL_ARGUMENT_EXCEPTION,
e.getMessage() == null ? "" : e.getMessage());
}

return new GeneratedFileSelectorApi.FileResponse.Builder()
.setName(name)
.setBytes(bytes)
.setPath(uriPath)
.setMimeType(contentResolver.getType(uri))
.setSize(size.longValue())
.setFileSelectorNativeException(nativeError)
.build();
return new FileResponse(uriPath, contentResolver.getType(uri), name, size, bytes, nativeError);
}
}
Loading
Loading