mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
fix importing data on Android
This commit is contained in:
@@ -10,7 +10,6 @@ import android.view.KeyEvent
|
||||
import android.Manifest
|
||||
import android.os.Environment
|
||||
import android.provider.Settings
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
@@ -34,6 +33,8 @@ class MainActivity : FlutterActivity() {
|
||||
private val storageRequestCode = 0x10
|
||||
private var storagePermissionRequest: ((Boolean) -> Unit)? = null
|
||||
|
||||
private val selectFileCode = 0x11
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (requestCode == pickDirectoryCode) {
|
||||
@@ -59,6 +60,41 @@ class MainActivity : FlutterActivity() {
|
||||
storagePermissionRequest?.invoke(Environment.isExternalStorageManager())
|
||||
}
|
||||
storagePermissionRequest = null
|
||||
} else if (requestCode == selectFileCode) {
|
||||
if (resultCode != Activity.RESULT_OK) {
|
||||
result.success(null)
|
||||
return
|
||||
}
|
||||
val uri = data?.data
|
||||
if (uri == null) {
|
||||
result.success(null)
|
||||
return
|
||||
}
|
||||
val contentResolver = context.contentResolver
|
||||
val file = DocumentFile.fromSingleUri(context, uri)
|
||||
if (file == null) {
|
||||
result.success(null)
|
||||
return
|
||||
}
|
||||
val fileName = file.name
|
||||
if (fileName == null) {
|
||||
result.success(null)
|
||||
return
|
||||
}
|
||||
// copy file to cache directory
|
||||
val cacheDir = context.cacheDir
|
||||
val newFile = File(cacheDir, fileName)
|
||||
val inputStream = contentResolver.openInputStream(uri)
|
||||
if (inputStream == null) {
|
||||
result.success(null)
|
||||
return
|
||||
}
|
||||
val outputStream = FileOutputStream(newFile)
|
||||
inputStream.copyTo(outputStream)
|
||||
inputStream.close()
|
||||
outputStream.close()
|
||||
// send file path to flutter
|
||||
result.success(newFile.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +148,12 @@ class MainActivity : FlutterActivity() {
|
||||
res.success(result)
|
||||
}
|
||||
}
|
||||
|
||||
val selectFileChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "venera/select_file")
|
||||
selectFileChannel.setMethodCallHandler { _, res ->
|
||||
openFile()
|
||||
result = res
|
||||
}
|
||||
}
|
||||
|
||||
private fun getProxy(): String {
|
||||
@@ -223,6 +265,13 @@ class MainActivity : FlutterActivity() {
|
||||
storagePermissionRequest = null
|
||||
}
|
||||
}
|
||||
|
||||
fun openFile() {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
intent.type = "*/*"
|
||||
startActivityForResult(intent, selectFileCode)
|
||||
}
|
||||
}
|
||||
|
||||
class VolumeListen{
|
||||
|
@@ -1,5 +1,3 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:mime/mime.dart';
|
||||
|
||||
class FileType {
|
||||
@@ -7,6 +5,14 @@ class FileType {
|
||||
final String mime;
|
||||
|
||||
const FileType(this.ext, this.mime);
|
||||
|
||||
static FileType fromExtension(String ext) {
|
||||
if(ext.startsWith('.')) {
|
||||
ext = ext.substring(1);
|
||||
}
|
||||
var mime = lookupMimeType('no-file.$ext');
|
||||
return FileType(".$ext", mime ?? 'application/octet-stream');
|
||||
}
|
||||
}
|
||||
|
||||
FileType detectFileType(List<int> data) {
|
||||
|
@@ -9,6 +9,7 @@ import 'package:venera/utils/ext.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:share_plus/share_plus.dart' as s;
|
||||
import 'package:file_selector/file_selector.dart' as file_selector;
|
||||
import 'package:venera/utils/file_type.dart';
|
||||
|
||||
export 'dart:io';
|
||||
export 'dart:typed_data';
|
||||
@@ -86,7 +87,7 @@ extension DirectoryExtension on Directory {
|
||||
}
|
||||
|
||||
String sanitizeFileName(String fileName) {
|
||||
if(fileName.endsWith('.')) {
|
||||
if (fileName.endsWith('.')) {
|
||||
fileName = fileName.substring(0, fileName.length - 1);
|
||||
}
|
||||
const maxLength = 255;
|
||||
@@ -126,7 +127,8 @@ Future<void> copyDirectory(Directory source, Directory destination) async {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> copyDirectoryIsolate(Directory source, Directory destination) async {
|
||||
Future<void> copyDirectoryIsolate(
|
||||
Directory source, Directory destination) async {
|
||||
await Isolate.run(() {
|
||||
copyDirectory(source, destination);
|
||||
});
|
||||
@@ -196,14 +198,32 @@ class IOSDirectoryPicker {
|
||||
}
|
||||
|
||||
Future<file_selector.XFile?> selectFile({required List<String> ext}) async {
|
||||
var extensions = App.isMacOS || App.isIOS ? null : ext;
|
||||
if (App.isAndroid) {
|
||||
for (var e in ext) {
|
||||
var fileType = FileType.fromExtension(e);
|
||||
if (fileType.mime == "application/octet-stream") {
|
||||
extensions = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
file_selector.XTypeGroup typeGroup = file_selector.XTypeGroup(
|
||||
label: 'files',
|
||||
extensions: App.isMacOS || App.isIOS ? null : ext,
|
||||
extensions: extensions,
|
||||
);
|
||||
final file_selector.XFile? file = await file_selector.openFile(
|
||||
file_selector.XFile? file;
|
||||
if (extensions == null && App.isAndroid) {
|
||||
const selectFileChannel = MethodChannel("venera/select_file");
|
||||
var filePath = await selectFileChannel.invokeMethod("selectFile");
|
||||
if (filePath == null) return null;
|
||||
file = file_selector.XFile(filePath);
|
||||
} else {
|
||||
file = await file_selector.openFile(
|
||||
acceptedTypeGroups: <file_selector.XTypeGroup>[typeGroup],
|
||||
);
|
||||
if (file == null) return null;
|
||||
}
|
||||
if (!ext.contains(file.path.split(".").last)) {
|
||||
App.rootContext.showMessage(message: "Invalid file type");
|
||||
return null;
|
||||
|
Reference in New Issue
Block a user