Commit de721de

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2023-10-12 12:38:06
implement file sharing
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 0da68a7
Changed files (7)
android
app
src
lib
model
platform_integration
android/app/src/main/kotlin/com/derdilla/blood_pressure_app/FileSharer.java
@@ -0,0 +1,10 @@
+package com.derdilla.blood_pressure_app;
+
+
+import androidx.core.content.FileProvider;
+
+public class FileSharer extends FileProvider {
+    public FileSharer() {
+        super(R.xml.file_paths);
+    }
+}
android/app/src/main/kotlin/com/derdilla/blood_pressure_app/MainActivity.kt
@@ -1,6 +1,17 @@
 package com.derdilla.blood_pressure_app
 
 import io.flutter.embedding.android.FlutterActivity
+import io.flutter.embedding.engine.FlutterEngine
+import io.flutter.plugin.common.MethodChannel
+import java.io.File
 
 class MainActivity: FlutterActivity() {
+    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
+        super.configureFlutterEngine(flutterEngine)
+        val shareFolder = File(context.cacheDir, "share")
+        if (shareFolder.exists()) shareFolder.deleteRecursively();
+
+        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, StorageProvider.CHANNEL)
+            .setMethodCallHandler(StorageProvider(context, shareFolder))
+    }
 }
android/app/src/main/kotlin/com/derdilla/blood_pressure_app/StorageProvider.kt
@@ -0,0 +1,48 @@
+package com.derdilla.blood_pressure_app
+
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import androidx.core.content.ContextCompat.startActivity
+import androidx.core.content.FileProvider.getUriForFile
+import io.flutter.plugin.common.MethodCall
+import io.flutter.plugin.common.MethodChannel
+import java.io.File
+
+class StorageProvider(private var context: Context,
+    private var shareFolder: File
+    ): MethodChannel.MethodCallHandler {
+    companion object {
+        const val CHANNEL = "bloodPressureApp.derdilla.com/storage"
+    }
+
+    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
+         when (call.method) {
+             "shareFile" -> shareFile(call.argument<String>("path")!!, call.argument<String>("mimeType")!!)
+        }
+    }
+
+    /**
+     * Show the share sheet for saving a file.
+     */
+    private fun shareFile(path: String, mimeType: String) {
+        val uri = sharableUriFromPath(path)
+
+        val sendIntent: Intent = Intent().apply {
+            action = Intent.ACTION_SEND
+            putExtra(Intent.EXTRA_STREAM, uri)
+            type = mimeType
+        }
+
+        val shareIntent = Intent.createChooser(sendIntent, null)
+        startActivity(context, shareIntent, null)
+    }
+
+
+    private fun sharableUriFromPath(path: String): Uri {
+        val initialFile = File(path)
+        val sharablePath = File(shareFolder, initialFile.name)
+        initialFile.copyTo(sharablePath)
+        return getUriForFile(context, "com.derdilla.bloodPressureApp.share", sharablePath)
+    }
+}
\ No newline at end of file
android/app/src/main/res/xml/file_paths.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<paths>
+    <cache-path name="share" path="share/"/>
+</paths>
\ No newline at end of file
android/app/src/main/AndroidManifest.xml
@@ -38,5 +38,15 @@
         <meta-data
             android:name="flutterEmbedding"
             android:value="2" />
-    </application>
+       <provider
+           android:name="com.derdilla.blood_pressure_app.FileSharer"
+           android:authorities="com.derdilla.bloodPressureApp.share"
+           android:exported="false"
+           android:grantUriPermissions="true">
+           <meta-data
+               android:name="android.support.FILE_PROVIDER_PATHS"
+               android:resource="@xml/file_paths" />
+       </provider>
+
+   </application>
 </manifest>
lib/model/export_import.dart
@@ -9,6 +9,7 @@ import 'package:blood_pressure_app/model/storage/export_csv_settings_store.dart'
 import 'package:blood_pressure_app/model/storage/export_pdf_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
+import 'package:blood_pressure_app/platform_integration/platform_client.dart';
 import 'package:csv/csv.dart';
 import 'package:file_picker/file_picker.dart';
 import 'package:file_saver/file_saver.dart';
@@ -20,7 +21,6 @@ import 'package:path/path.dart';
 import 'package:pdf/pdf.dart';
 import 'package:pdf/widgets.dart' as pw;
 import 'package:provider/provider.dart';
-import 'package:share_plus/share_plus.dart';
 import 'package:sqflite/sqflite.dart';
 
 import 'blood_pressure.dart';
@@ -305,12 +305,13 @@ class Exporter {
         );
         messenger.showSnackBar(SnackBar(content: Text(localizations.success(exportSettings.defaultExportDir))));
       } else {
-        Share.shareXFiles([
+        PlatformClient.shareFile(path, 'text/csv'); // TODO: set mime type according to data type
+        /*Share.shareXFiles([
           XFile(
               path,
               mimeType: MimeType.csv.type
           )
-        ]);
+        ]);*/
       }
     } else {
       messenger.showSnackBar(const SnackBar(content: Text('UNSUPPORTED PLATFORM')));
lib/platform_integration/platform_client.dart
@@ -0,0 +1,19 @@
+import 'package:flutter/services.dart';
+
+class PlatformClient {
+  /// Platform channel for sharing files, loading files, saving files and asking for directory permissions.
+  static const storagePlatform = MethodChannel('bloodPressureApp.derdilla.com/storage');
+
+
+  static Future<bool> shareFile(String path, String mimeType) async { // TODO: arguments from platform
+    try {
+      await storagePlatform.invokeMethod('shareFile', {
+        'path': path,
+        'mimeType': mimeType
+      });
+      return true;
+    } on PlatformException {
+      return false;
+    }
+  }
+}
\ No newline at end of file