diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d95c4e96..ff06f437 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -46,7 +46,7 @@ - + diff --git a/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt b/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt index 8d31d327..35980b5e 100644 --- a/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt +++ b/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt @@ -1,6 +1,7 @@ package im.cwtch.flwtch import android.app.* +import android.os.Environment import android.content.Context import android.content.Intent import android.graphics.BitmapFactory @@ -430,12 +431,13 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) : } "ExportProfile" -> { val profileOnion = (a.get("ProfileOnion") as? String) ?: "" - val file = (a.get("file") as? String) ?: "" - Cwtch.exportProfile(profileOnion, file) + val file = StringBuilder().append(this.applicationContext.cacheDir).append("/").append((a.get("file") as? String) ?: "").toString() + Log.i("FlwtchWorker", "constructing exported file " + file); + Cwtch.exportProfile(profileOnion,file) } "ImportProfile" -> { val file = (a.get("file") as? String) ?: "" - val password = (a.get("pass") as? String) ?: "" + val pass = (a.get("pass") as? String) ?: "" return Result.success(Data.Builder().putString("result", Cwtch.importProfile(file, pass)).build()); } else -> { diff --git a/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt b/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt index 499c01ce..383887bb 100644 --- a/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt +++ b/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt @@ -62,6 +62,7 @@ class MainActivity: FlutterActivity() { // "Download to..." prompt extra arguments private val FILEPICKER_REQUEST_CODE = 234 private val PREVIEW_EXPORT_REQUEST_CODE = 235 + private val PROFILE_EXPORT_REQUEST_CODE = 236 private var dlToProfile = "" private var dlToHandle = "" private var dlToFileKey = "" @@ -110,8 +111,6 @@ class MainActivity: FlutterActivity() { )), ErrorLogResult(""));//placeholder; this Result is never actually invoked } else if (requestCode == PREVIEW_EXPORT_REQUEST_CODE) { val targetPath = intent!!.getData().toString() - var srcFile = File(this.exportFromPath) - Log.i("MainActivity:PREVIEW_EXPORT", "exporting previewed file") val sourcePath = Paths.get(this.exportFromPath); val targetUri = Uri.parse(targetPath); val os = this.applicationContext.getContentResolver().openOutputStream(targetUri); @@ -122,6 +121,20 @@ class MainActivity: FlutterActivity() { os?.close(); //Files.delete(sourcePath); } + } else if (requestCode == PROFILE_EXPORT_REQUEST_CODE ) { + val targetPath = intent!!.getData().toString() + val srcFile = StringBuilder().append(this.applicationContext.cacheDir).append("/").append(this.exportFromPath).toString(); + Log.i("MainActivity:PREVIEW_EXPORT", "exporting previewed file " + srcFile); + val sourcePath = Paths.get(srcFile); + val targetUri = Uri.parse(targetPath); + val os = this.applicationContext.getContentResolver().openOutputStream(targetUri); + val bytesWritten = Files.copy(sourcePath, os); + Log.d("MainActivity:PREVIEW_EXPORT", "copied " + bytesWritten.toString() + " bytes"); + if (bytesWritten != 0L) { + os?.flush(); + os?.close(); + //Files.delete(sourcePath); + } } } @@ -211,6 +224,14 @@ class MainActivity: FlutterActivity() { } startActivityForResult(intent, PREVIEW_EXPORT_REQUEST_CODE) return + } else if (call.method == "ExportProfile") { + this.exportFromPath = argmap["file"] ?: "" + val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { + addCategory(Intent.CATEGORY_OPENABLE) + type = "application/gzip" + putExtra(Intent.EXTRA_TITLE, argmap["file"]) + } + startActivityForResult(intent, PROFILE_EXPORT_REQUEST_CODE) } // ...otherwise fallthru to a normal ffi method call (and return the result using the result callback) diff --git a/lib/views/addeditprofileview.dart b/lib/views/addeditprofileview.dart index bdf707a1..7caa717f 100644 --- a/lib/views/addeditprofileview.dart +++ b/lib/views/addeditprofileview.dart @@ -297,13 +297,19 @@ class _AddEditProfileViewState extends State { message: AppLocalizations.of(context)!.exportProfileTooltip, child: ElevatedButton.icon( onPressed: () { - showCreateFilePicker(context).then((name) { - if (name != null) { - Provider.of(context, listen: false).cwtch.ExportProfile(ctrlrOnion.value.text, name); - final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.fileSavedTo + " " + name)); - ScaffoldMessenger.of(context).showSnackBar(snackBar); - } - }); + if (Platform.isAndroid) { + Provider.of(context, listen: false).cwtch.ExportProfile(ctrlrOnion.value.text, ctrlrOnion.value.text + ".tar.gz"); + final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.fileSavedTo + " " + ctrlrOnion.value.text + ".tar.gz")); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + } else { + showCreateFilePicker(context).then((name) { + if (name != null) { + Provider.of(context, listen: false).cwtch.ExportProfile(ctrlrOnion.value.text, name); + final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.fileSavedTo + " " + name)); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + } + }); + } }, icon: Icon(Icons.import_export), label: Text(AppLocalizations.of(context)!.exportProfile),