Browse Source

ComPDFKit(flutter) - 新增选择PDF文件接口

liuxiaolong 3 months ago
parent
commit
d3b09ea92d

+ 1 - 1
android/build.gradle

@@ -40,7 +40,7 @@ android {
         implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
 
         // dependencies compdfkit pdf sdk
-        api 'com.compdf:compdfkit-tools:2.2.0-SNAPSHOT'
+        api 'com.compdf:compdfkit-tools:2.2.0'
 
         testImplementation 'junit:junit:4.13.2'
         testImplementation 'org.mockito:mockito-core:5.0.0'

+ 21 - 3
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/CompdfkitFlutterPlugin.java

@@ -28,13 +28,17 @@ public class CompdfkitFlutterPlugin implements FlutterPlugin, ActivityAware {
     private PlatformViewRegistry mRegistry;
 
     private static final String PDF_DOCUMENT_VIEW_TYPE_ID = "com.compdfkit.flutter.ui.pdfviewer";
+    private FlutterPluginBinding pluginBinding;
 
+    private ActivityPluginBinding activityPluginBinding;
+
+    private ComPDFKitSDKPlugin comPDFKitSDKPlugin;
     @Override
     public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
+        this.pluginBinding = flutterPluginBinding;
         mMessenger = flutterPluginBinding.getBinaryMessenger();
         mRegistry = flutterPluginBinding.getPlatformViewRegistry();
-        new ComPDFKitSDKPlugin(flutterPluginBinding.getApplicationContext(), mMessenger)
-                .register();
+
     }
 
     @Override
@@ -43,11 +47,25 @@ public class CompdfkitFlutterPlugin implements FlutterPlugin, ActivityAware {
 
     @Override
     public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
+        this.activityPluginBinding = binding;
+        setUp();
+    }
+
+    private void setUp(){
+        comPDFKitSDKPlugin = new ComPDFKitSDKPlugin(activityPluginBinding.getActivity(), mMessenger);
+        comPDFKitSDKPlugin.register();
+        activityPluginBinding.addActivityResultListener(comPDFKitSDKPlugin);
         if (mRegistry != null) {
             mRegistry.registerViewFactory(PDF_DOCUMENT_VIEW_TYPE_ID,new CPDFViewCtrlFactory(mMessenger));
         }
     }
 
+    private void clear(){
+        this.activityPluginBinding.removeActivityResultListener(comPDFKitSDKPlugin);
+        this.activityPluginBinding = null;
+        this.comPDFKitSDKPlugin = null;
+    }
+
     @Override
     public void onDetachedFromActivityForConfigChanges() {
 
@@ -59,6 +77,6 @@ public class CompdfkitFlutterPlugin implements FlutterPlugin, ActivityAware {
 
     @Override
     public void onDetachedFromActivity() {
-
+        clear();
     }
 }

+ 2 - 0
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/constants/CPDFConstants.java

@@ -38,6 +38,8 @@ public class CPDFConstants {
     public static final String GET_TEMP_DIRECTORY = "get_temporary_directory";
     public static final String REMOVE_SIGN_FILE_LIST = "remove_sign_file_list";
 
+    public static final String PICK_FILE = "pick_file";
+
     public static final String SAVE = "save";
 
     public static final String SET_SCALE = "set_scale";

+ 7 - 1
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/platformview/CPDFViewCtrlFlutter.java

@@ -13,6 +13,7 @@ package com.compdfkit.flutter.compdfkit_flutter.platformview;
 
 import android.content.Context;
 import android.content.MutableContextWrapper;
+import android.net.Uri;
 import android.util.Log;
 import android.view.View;
 
@@ -23,6 +24,7 @@ import androidx.fragment.app.FragmentContainerView;
 
 
 import com.compdfkit.flutter.compdfkit_flutter.plugin.CPDFViewCtrlPlugin;
+import com.compdfkit.flutter.compdfkit_flutter.utils.FileUtils;
 import com.compdfkit.tools.common.pdf.CPDFConfigurationUtils;
 import com.compdfkit.tools.common.pdf.CPDFDocumentFragment;
 import com.compdfkit.tools.common.pdf.config.CPDFConfiguration;
@@ -72,7 +74,11 @@ public class CPDFViewCtrlFlutter implements PlatformView {
 
         String configurationJson = (String) creationParams.get("configuration");
         CPDFConfiguration configuration = CPDFConfigurationUtils.fromJson(configurationJson);
-        documentFragment = CPDFDocumentFragment.newInstance(filePath, password, configuration);
+        if (filePath.startsWith(FileUtils.CONTENT_SCHEME) || filePath.startsWith(FileUtils.FILE_SCHEME)){
+            documentFragment = CPDFDocumentFragment.newInstance(Uri.parse(filePath), password, configuration);
+        }else {
+            documentFragment = CPDFDocumentFragment.newInstance(filePath, password, configuration);
+        }
         fragmentContainerView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
             @Override
             public void onViewAttachedToWindow(@NonNull View v) {

+ 48 - 4
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/plugin/ComPDFKitSDKPlugin.java

@@ -13,22 +13,28 @@ import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.Ch
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.INIT_SDK;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.INIT_SDK_KEYS;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.OPEN_DOCUMENT;
+import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.PICK_FILE;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.REMOVE_SIGN_FILE_LIST;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.SDK_BUILD_TAG;
 import static com.compdfkit.flutter.compdfkit_flutter.constants.CPDFConstants.ChannelMethod.SDK_VERSION_CODE;
 
+import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.net.Uri;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
 
+import androidx.annotation.Nullable;
 import com.compdfkit.core.document.CPDFSdk;
+import com.compdfkit.flutter.compdfkit_flutter.utils.FileUtils;
 import com.compdfkit.tools.common.pdf.CPDFConfigurationUtils;
 import com.compdfkit.tools.common.pdf.CPDFDocumentActivity;
 import com.compdfkit.tools.common.pdf.config.CPDFConfiguration;
 import com.compdfkit.tools.common.utils.CFileUtils;
 
+import io.flutter.plugin.common.PluginRegistry;
 import java.io.File;
 
 import io.flutter.plugin.common.BinaryMessenger;
@@ -36,10 +42,16 @@ import io.flutter.plugin.common.MethodCall;
 import io.flutter.plugin.common.MethodChannel;
 
 
-public class ComPDFKitSDKPlugin extends BaseMethodChannelPlugin {
+public class ComPDFKitSDKPlugin extends BaseMethodChannelPlugin implements PluginRegistry.ActivityResultListener {
+    private static final int REQUEST_CODE = (ComPDFKitSDKPlugin.class.hashCode() + 43) & 0x0000ffff;
 
-    public ComPDFKitSDKPlugin(Context context, BinaryMessenger binaryMessenger) {
-        super(context, binaryMessenger);
+    private Activity activity;
+
+    private MethodChannel.Result pendingResult;
+
+    public ComPDFKitSDKPlugin(Activity activity, BinaryMessenger binaryMessenger) {
+        super(activity, binaryMessenger);
+        this.activity = activity;
     }
 
     @Override
@@ -75,7 +87,7 @@ public class ComPDFKitSDKPlugin extends BaseMethodChannelPlugin {
                 CPDFConfiguration configuration = CPDFConfigurationUtils.fromJson(configurationJson);
                 Intent intent = new Intent(context, CPDFDocumentActivity.class);
                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                intent.putExtra(CPDFDocumentActivity.EXTRA_FILE_PATH, filePath);
+                FileUtils.parseDocument(context, filePath, intent);
                 intent.putExtra(CPDFDocumentActivity.EXTRA_FILE_PASSWORD, password);
                 intent.putExtra(CPDFDocumentActivity.EXTRA_CONFIGURATION, configuration);
                 context.startActivity(intent);
@@ -88,10 +100,42 @@ public class ComPDFKitSDKPlugin extends BaseMethodChannelPlugin {
                 boolean deleteResult = CFileUtils.deleteDirectory(dirFile.getAbsolutePath());
                 result.success(deleteResult);
                 break;
+            case PICK_FILE:
+                pendingResult = result;
+                if (activity != null) {
+                    activity.startActivityForResult(CFileUtils.getContentIntent(), REQUEST_CODE);
+                }
+                break;
             default:
                 break;
         }
     }
 
+    @Override
+    public boolean onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+        if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK){
+            if(data != null && data.getData() != null){
+                Uri uri = data.getData();
+                successResult(uri);
+            }
+            return true;
+        } else if (requestCode == REQUEST_CODE && resultCode != Activity.RESULT_OK){
+            successResult(null);
+        }
+
+        return false;
+    }
+
+    private void successResult(Uri uri){
+        if(pendingResult != null){
+            pendingResult.success(uri.toString());
+        }
+        clearPendingResult();
+    }
+
+    private void clearPendingResult() {
+        pendingResult = null;
+    }
+
 
 }

+ 44 - 0
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/utils/FileUtils.java

@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
+ *
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ *
+ */
+
+package com.compdfkit.flutter.compdfkit_flutter.utils;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import com.compdfkit.tools.common.pdf.CPDFDocumentActivity;
+import com.compdfkit.tools.common.utils.CFileUtils;
+
+
+public class FileUtils {
+
+  public static final String ASSETS_SCHEME = "file:///android_asset";
+
+  public static final String CONTENT_SCHEME = "content://";
+  public static final String FILE_SCHEME = "file://";
+
+  public static void parseDocument(Context context, String document, Intent intent) {
+    if (document.startsWith(ASSETS_SCHEME)) {
+      String assetsPath = document.replace(ASSETS_SCHEME + "/","");
+      String[] strs = document.split("/");
+      String fileName = strs[strs.length -1];
+      String samplePDFPath = CFileUtils.getAssetsTempFile(context, assetsPath, fileName);
+      intent.putExtra(CPDFDocumentActivity.EXTRA_FILE_PATH, samplePDFPath);
+    } else if (document.startsWith(CONTENT_SCHEME)) {
+      Uri uri = Uri.parse(document);
+      intent.setData(uri);
+    } else if (document.startsWith(FILE_SCHEME)) {
+      Uri uri = Uri.parse(document);
+      intent.setData(uri);
+    } else {
+      intent.putExtra(CPDFDocumentActivity.EXTRA_FILE_PATH, document);
+    }
+  }
+}

+ 3 - 3
example/lib/cpdf_reader_widget_controller_example.dart

@@ -74,7 +74,7 @@ class _CPDFReaderWidgetControllerExampleState
             });
           },
           onPageChanged: (pageIndex){
-            debugPrint('pageIndex:${pageIndex}');
+            debugPrint('pageIndex:$pageIndex');
           },
           onSaveCallback: (){
             debugPrint('CPDFDocument: save success');
@@ -172,7 +172,7 @@ class _CPDFReaderWidgetControllerExampleState
         await controller.setReadBackgroundColor(CPDFThemes.light);
         break;
       case 'isChanged':
-        bool hasChange = await controller.hasChange();
+        bool hasChange = await controller.document.hasChange();
         debugPrint('ComPDFKit:hasChange:$hasChange');
         break;
       case "documentInfo":
@@ -209,7 +209,7 @@ class _CPDFReaderWidgetControllerExampleState
         break;
       case "removeSignFileList":
         bool result = await ComPDFKit.removeSignFileList();
-        debugPrint('ComPDFKit:removeSignFileList:${result}');
+        debugPrint('ComPDFKit:removeSignFileList:$result');
         break;
     }
   }

+ 66 - 53
example/lib/examples.dart

@@ -23,38 +23,64 @@ import 'widgets/cpdf_fun_item.dart';
 
 const String _documentPath = 'pdfs/PDF_Document.pdf';
 
-List<Widget> examples(BuildContext context) => [
-  Padding(padding: const EdgeInsets.only(top: 8, bottom: 8), child: Text(
-    'Widget Examples',
-    style: Theme.of(context).textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w500),
-  )),
-  FeatureItem(
-      title: 'Show CPDFReaderWidget',
-      description: 'Display PDF view in flutter widget',
-      onTap: () => showCPDFReaderWidget(context)),
-  if (Platform.isAndroid) ...[
-    FeatureItem(title: 'CPDFReaderWidget Dark Theme',
-        description: 'Opens a document in night mode with a custom dark theme',
-        onTap: () => showDarkThemeCPDFReaderWidget(context))
-  ],
-  FeatureItem(title: 'Widget Controller Examples',
-      description: 'CPDFReaderWidget Controller fun example',
-      onTap: () => showCPDFReaderWidgetTest(context)),
+List<Widget> examples(BuildContext context) =>
+    [
+      Padding(padding: const EdgeInsets.only(top: 8, bottom: 8), child: Text(
+        'Widget Examples',
+        style: Theme
+            .of(context)
+            .textTheme
+            .bodyLarge
+            ?.copyWith(fontWeight: FontWeight.w500),
+      )),
+      FeatureItem(
+          title: 'Show CPDFReaderWidget',
+          description: 'Display PDF view in flutter widget',
+          onTap: () async {
+            File document = await extractAsset(
+                context, _documentPath, shouldOverwrite: false);
+            showCPDFReaderWidget(context, document.path);
+          }
+      ),
+      if (Platform.isAndroid) ...[
+        FeatureItem(title: 'CPDFReaderWidget Dark Theme',
+            description: 'Opens a document in night mode with a custom dark theme',
+            onTap: () => showDarkThemeCPDFReaderWidget(context))
+      ],
+      FeatureItem(title: 'Widget Controller Examples',
+          description: 'CPDFReaderWidget Controller fun example',
+          onTap: () => showCPDFReaderWidgetTest(context)),
+      FeatureItem(
+          title: 'Select External Files',
+          description: 'Select pdf document from system file manager',
+          onTap: () async {
+            String? path = await pickDocument();
+            showCPDFReaderWidget(context, path);
+          }),
+      Padding(padding: const EdgeInsets.only(top: 8, bottom: 8), child: Text(
+        'Modal View Examples',
+        style: Theme
+            .of(context)
+            .textTheme
+            .bodyLarge
+            ?.copyWith(fontWeight: FontWeight.w500),
+      )),
 
-  Padding(padding: const EdgeInsets.only(top: 8, bottom: 8), child: Text(
-    'Modal View Examples',
-    style: Theme.of(context).textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w500),
-  )),
-
-  FeatureItem(
-      title: 'Basic Example',
-      description: 'Open sample pdf document',
-      onTap: () => showDocument(context)),
-  FeatureItem(
-      title: 'Select External Files',
-      description: 'Select pdf document from system file manager',
-      onTap: () => pickDocument())
-];
+      FeatureItem(
+          title: 'Basic Example',
+          description: 'Open sample pdf document',
+          onTap: () => showDocument(context)),
+      FeatureItem(
+          title: 'Select External Files',
+          description: 'Select pdf document from system file manager',
+          onTap: () async {
+            String? path = await pickDocument();
+            if (path != null) {
+              ComPDFKit.openDocument(path,
+                  password: '', configuration: CPDFConfiguration());
+            }
+          })
+    ];
 
 
 void showDocument(context) async {
@@ -63,37 +89,24 @@ void showDocument(context) async {
       password: '', configuration: CPDFConfiguration());
 }
 
-void pickDocument() async {
-  if (Platform.isIOS) {
-    await ComPDFKit.getPdfFilePath().then((value) {
-      ComPDFKit.openDocument(value!,
-          password: '', configuration: CPDFConfiguration());
-    });
-  } else {
-    FilePickerResult? result = await FilePicker.platform.pickFiles(
-      type: FileType.custom,
-      allowedExtensions: ['pdf'],
-    );
-
-    if (result != null) {
-      ComPDFKit.openDocument(result.files.first.path!,
-          password: '', configuration: CPDFConfiguration());
-    }
-  }
+Future<String?> pickDocument() async {
+  return await ComPDFKit.pickFile();
 }
 
-void showCPDFReaderWidget(context) async {
-  File document = await extractAsset(context, _documentPath, shouldOverwrite: false);
-  goTo(CPDFReaderWidgetExample(documentPath: document.path), context);
+void showCPDFReaderWidget(context, String? path) async {
+  goTo(CPDFReaderWidgetExample(documentPath: path!), context);
 }
 
+
 void showDarkThemeCPDFReaderWidget(context) async {
-  File document = await extractAsset(context, _documentPath, shouldOverwrite: false);
+  File document = await extractAsset(
+      context, _documentPath, shouldOverwrite: false);
   goTo(CPDFDarkThemeExample(documentPath: document.path), context);
 }
 
 void showCPDFReaderWidgetTest(context) async {
-  File document = await extractAsset(context, _documentPath, shouldOverwrite: false);
+  File document = await extractAsset(
+      context, _documentPath, shouldOverwrite: false);
   goTo(CPDFReaderWidgetControllerExample(documentPath: document.path), context);
 }
 

+ 1 - 1
example/lib/utils/file_util.dart

@@ -11,7 +11,7 @@ import 'package:compdfkit_flutter/compdfkit.dart';
 import 'package:flutter/material.dart';
 
 Future<File> extractAsset(BuildContext context, String assetPath,
-    {bool shouldOverwrite = true, String prefix = ''}) async {
+    {bool shouldOverwrite = false, String prefix = ''}) async {
   final bytes = await DefaultAssetBundle.of(context).load(assetPath);
   final list = bytes.buffer.asUint8List();
 

+ 1 - 1
ios/Classes/CompdfkitFlutterPlugin.swift

@@ -91,7 +91,7 @@ public class CompdfkitFlutterPlugin: NSObject, FlutterPlugin, CPDFViewBaseContro
         case "get_temporary_directory":
             result(self.getTemporaryDirectory())
             
-        case "get_pdf_file_path":
+        case "pick_file":
             let documentTypes = ["com.adobe.pdf"]
             let documentPickerViewController = UIDocumentPickerViewController(documentTypes: documentTypes, in: .open)
             documentPickerViewController.delegate = self

+ 2 - 2
lib/compdfkit.dart

@@ -97,8 +97,8 @@ class ComPDFKit {
     return await _methodChannel.invokeMethod('remove_sign_file_list');
   }
 
-  static Future<String?> getPdfFilePath() async {
-    final String? filePath = await _methodChannel.invokeMethod('get_pdf_file_path');
+  static Future<String?> pickFile() async {
+    final String? filePath = await _methodChannel.invokeMethod('pick_file');
     return filePath;
   }
 }

+ 0 - 1
lib/configuration/cpdf_configuration.dart

@@ -7,7 +7,6 @@
 
 
 import 'dart:convert';
-import 'dart:ffi';
 
 import 'package:compdfkit_flutter/configuration/attributes/cpdf_annot_attr.dart';
 

+ 0 - 4
lib/configuration/cpdf_options.dart

@@ -6,10 +6,6 @@
 // This notice may not be removed from this file.
 
 
-import 'dart:ui';
-
-import 'package:compdfkit_flutter/util/extension/cpdf_color_extension.dart';
-
 enum CPDFViewMode { viewer, annotations, contentEditor, forms, signatures }
 
 /// The [CPDFToolbarAction.back] button will only be displayed on the leftmost side of the top toolbar on the Android platform

+ 1 - 2
lib/document/cpdf_document.dart

@@ -7,7 +7,6 @@
 
 import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
 import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
 
 /// A class to handle PDF documents without using [CPDFReaderWidget]
 ///
@@ -23,7 +22,7 @@ import 'package:flutter/widgets.dart';
 /// var fileName = await document.getFileName();
 /// ```
 class CPDFDocument {
-  late MethodChannel _channel;
+  late final MethodChannel _channel;
 
   bool _isValid = false;