Flutter安全打开文件插件open_file_safe_clone的使用

Flutter安全打开文件插件open_file_safe_clone的使用


插件介绍

open_file_safe 是一个可以在 Flutter 中调用原生应用打开文件的插件,支持多种平台(iOS、Android、PC 和 Web)。该插件的功能类似于 open_file,但不支持 .apk 文件类型,并且移除了 android.permission.REQUEST_INSTALL_PACKAGES 权限。


使用步骤

  1. pubspec.yaml 文件中添加依赖:

    dependencies:
      open_file_safe: ^lastVersion
    

    或者指定版本:

    dependencies:
      open_file_safe: ^1.3.0
    
  2. 运行 flutter pub get 更新依赖。


示例代码

以下是一个完整的示例代码,展示如何使用 open_file_safe 打开文件:

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:open_file_safe/open_file_safe.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // 用于存储打开文件的结果
  String _openResult = '未知';

  // 打开文件的方法
  Future<void> openFile() async {
    // 指定文件路径
    final filePath = '/storage/emulated/0/image.png';
    
    // 调用 open_file_safe 插件打开文件
    final result = await OpenFile.open(filePath);
    
    // 更新 UI 显示结果
    setState(() {
      _openResult = "type=${result.type}  message=${result.message}";
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('open_file_safe 示例'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              // 显示打开文件的结果
              Text('打开结果: $_openResult\n'),
              // 点击按钮以打开文件
              TextButton(
                child: Text('点击以打开文件'),
                onPressed: openFile,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

支持的文件类型

Android 平台

以下是一些常见的文件类型映射:

{
    ".3gp": "video/3gpp",
    ".torrent": "application/x-bittorrent",
    ".kml": "application/vnd.google-earth.kml+xml",
    ".gpx": "application/gpx+xml",
    ".csv": "application/vnd.ms-excel",
    ".asf": "video/x-ms-asf",
    ".avi": "video/x-msvideo",
    ".bin": "application/octet-stream",
    ".bmp": "image/bmp",
    ".c": "text/plain",
    ".class": "application/octet-stream",
    ".conf": "text/plain",
    ".cpp": "text/plain",
    ".doc": "application/msword",
    ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    ".xls": "application/vnd.ms-excel",
    ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    ".exe": "application/octet-stream",
    ".gif": "image/gif",
    ".gtar": "application/x-gtar",
    ".gz": "application/x-gzip",
    ".h": "text/plain",
    ".htm": "text/html",
    ".html": "text/html",
    ".jar": "application/java-archive",
    ".java": "text/plain",
    ".jpeg": "image/jpeg",
    ".jpg": "image/jpeg",
    ".js": "application/x-javascript",
    ".log": "text/plain",
    ".m3u": "audio/x-mpegurl",
    ".m4a": "audio/mp4a-latm",
    ".m4b": "audio/mp4a-latm",
    ".m4p": "audio/mp4a-latm",
    ".m4u": "video/vnd.mpegurl",
    ".m4v": "video/x-m4v",
    ".mov": "video/quicktime",
    ".mp2": "audio/x-mpeg",
    ".mp3": "audio/x-mpeg",
    ".mp4": "video/mp4",
    ".mpc": "application/vnd.mpohun.certificate",
    ".mpe": "video/mpeg",
    ".mpeg": "video/mpeg",
    ".mpg": "video/mpeg",
    ".mpg4": "video/mp4",
    ".mpga": "audio/mpeg",
    ".msg": "application/vnd.ms-outlook",
    ".ogg": "audio/ogg",
    ".pdf": "application/pdf",
    ".png": "image/png",
    ".pps": "application/vnd.ms-powerpoint",
    ".ppt": "application/vnd.ms-powerpoint",
    ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
    ".prop": "text/plain",
    ".rc": "text/plain",
    ".rmvb": "audio/x-pn-realaudio",
    ".rtf": "application/rtf",
    ".sh": "text/plain",
    ".tar": "application/x-tar",
    ".tgz": "application/x-compressed",
    ".txt": "text/plain",
    ".wav": "audio/x-wav",
    ".wma": "audio/x-ms-wma",
    ".wmv": "audio/x-ms-wmv",
    ".wps": "application/vnd.ms-works",
    ".xml": "text/plain",
    ".z": "application/x-compress",
    ".zip": "application/x-zip-compressed",
    "": "*/*"
}
不支持的文件类型

在 Android 平台上,.apk 文件类型不受支持:

{
    ".apk": "application/vnd.android.package-archive"
}

配置 Android 权限与冲突解决

  1. 解决 FileProvider 冲突
    如果与其他插件存在冲突,可在 AndroidManifest.xml 中添加以下配置:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              package="xxx.xxx.xxxxx">
        <application>
            ...
            <provider
                android:name="androidx.core.content.FileProvider"
                android:authorities="${applicationId}.fileProvider"
                android:exported="false"
                android:grantUriPermissions="true"
                tools:replace="android:authorities">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/filepaths"
                    tools:replace="android:resource" />
            </provider>
        </application>
    </manifest>
    
  2. 解决 Android 支持库版本冲突
    如果遇到依赖冲突问题,可在 build.gradle 中添加以下配置:

    subprojects {
        project.configurations.all {
            resolutionStrategy.eachDependency { details ->
                if (details.requested.group == 'com.android.support'
                        && !details.requested.name.contains('multidex') ) {
                    details.useVersion "27.1.1"
                }
            }
        }
    }
    

iOS 平台

在 iOS 上,可以使用 UTI(Uniform Type Identifiers)来描述文件类型。例如:

{
    ".rtf": "public.rtf",
    ".txt": "public.plain-text",
    ".html": "public.html",
    ".htm": "public.html",
    ".xml": "public.xml",
    ".tar": "public.tar-archive",
    ".gz": "org.gnu.gnu-zip-archive",
    ".gzip": "org.gnu.gnu-zip-archive",
    ".tgz": "org.gnu.gnu-zip-tar-archive",
    ".jpg": "public.jpeg",
    ".jpeg": "public.jpeg",
    ".png": "public.png",
    ".avi": "public.avi",
    ".mpg": "public.mpeg",
    ".mpeg": "public.mpeg",
    ".mp4": "public.mpeg-4",
    ".3gpp": "public.3gpp",
    ".3gp": "public.3gpp",
    ".mp3": "public.mp3",
    ".zip": "com.pkware.zip-archive",
    ".gif": "com.compuserve.gif",
    ".bmp": "com.microsoft.bmp",
    ".ico": "com.microsoft.ico",
    ".doc": "com.microsoft.word.doc",
    ".xls": "com.microsoft.excel.xls",
    ".ppt": "com.microsoft.powerpoint.ppt",
    ".wav": "com.microsoft.waveform-audio",
    ".wm": "com.microsoft.windows-media-wm",
    ".wmv": "com.microsoft.windows-media-wmv",
    ".pdf": "com.adobe.pdf"
}

更多关于Flutter安全打开文件插件open_file_safe_clone的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter安全打开文件插件open_file_safe_clone的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


open_file_safe_clone 是一个 Flutter 插件,用于在 Android 和 iOS 设备上安全地打开文件。它是 open_file 插件的一个安全克隆版本,旨在解决 open_file 插件在某些情况下可能存在的安全问题。以下是使用 open_file_safe_clone 插件的步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 open_file_safe_clone 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  open_file_safe_clone: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 导入插件

在你的 Dart 文件中导入 open_file_safe_clone 插件:

import 'package:open_file_safe_clone/open_file_safe_clone.dart';

3. 打开文件

使用 OpenFile.open 方法来打开文件。你需要提供文件的路径作为参数。

void openFile(String filePath) async {
  try {
    final result = await OpenFile.open(filePath);
    print('文件打开结果: ${result.message}');
  } catch (e) {
    print('打开文件时出错: $e');
  }
}

4. 处理文件路径

确保你提供的文件路径是有效的。你可以使用 path_provider 插件来获取应用程序的目录路径,或者从文件选择器插件中获取文件路径。

import 'package:path_provider/path_provider.dart';

Future<String> getFilePath() async {
  final directory = await getApplicationDocumentsDirectory();
  return '${directory.path}/example.pdf';
}

5. 调用打开文件方法

将文件路径传递给 openFile 方法来打开文件。

void openExampleFile() async {
  String filePath = await getFilePath();
  openFile(filePath);
}

6. 处理权限

在 Android 上,你可能需要请求存储权限来访问文件。你可以使用 permission_handler 插件来请求权限。

import 'package:permission_handler/permission_handler.dart';

void requestPermissions() async {
  if (await Permission.storage.request().isGranted) {
    print('存储权限已授予');
  } else {
    print('存储权限被拒绝');
  }
}

7. 完整示例

以下是一个完整的示例,展示了如何使用 open_file_safe_clone 插件打开文件:

import 'package:flutter/material.dart';
import 'package:open_file_safe_clone/open_file_safe_clone.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Open File Safe Clone Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              requestPermissions();
              openExampleFile();
            },
            child: Text('Open File'),
          ),
        ),
      ),
    );
  }
}

void openFile(String filePath) async {
  try {
    final result = await OpenFile.open(filePath);
    print('文件打开结果: ${result.message}');
  } catch (e) {
    print('打开文件时出错: $e');
  }
}

Future<String> getFilePath() async {
  final directory = await getApplicationDocumentsDirectory();
  return '${directory.path}/example.pdf';
}

void openExampleFile() async {
  String filePath = await getFilePath();
  openFile(filePath);
}

void requestPermissions() async {
  if (await Permission.storage.request().isGranted) {
    print('存储权限已授予');
  } else {
    print('存储权限被拒绝');
  }
}
回到顶部