Flutter媒体存储管理插件media_store_plus的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter媒体存储管理插件media_store_plus的使用

media_store_plus简介

media_store_plus 插件用于在Flutter中使用Android MediaStore API,支持所有Android版本的读写操作,并根据需要请求适当的权限。从API级别30开始,必须使用Scoped Storage来写文件;而从API级别33开始,读取文件也需要遵循这一规则。

动机

  • API 30+: 必须使用Scoped Storage进行文件写入。
  • API 32及以下: 可以通过直接路径读取文件。
  • API 33及以上: 需要使用Scoped Storage进行读取,并引入了特定的权限(如READ_MEDIA_IMAGES, READ_MEDIA_AUDIO, READ_MEDIA_VIDEO)来访问图片、音频和视频文件。

由于这些限制,在Flutter中直接使用MediaStore API变得复杂,因此创建了media_store_plus插件来简化这些操作。

使用方法

添加依赖

首先,在pubspec.yaml文件中添加media_store_plus依赖:

dependencies:
  media_store_plus: ^0.1.3

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

Android配置

编辑AndroidManifest.xml文件,添加必要的权限声明:

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

<uses-permission
    android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="29" />

<application
    ...
    android:requestLegacyExternalStorage="true">
</application>

此外,根据GSON的要求修改proguard-rules.pro文件。

示例代码

下面是一个完整的示例应用程序,展示了如何使用media_store_plus插件进行文件的保存和读取操作:

import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:media_store_plus/media_store_plus.dart';
import 'package:permission_handler/permission_handler.dart';

final mediaStorePlugin = MediaStore();

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  if (Platform.isAndroid) {
    await MediaStore.ensureInitialized();
  }

  List<Permission> permissions = [Permission.storage];

  if ((await mediaStorePlugin.getPlatformSDKInt()) >= 33) {
    permissions.addAll([Permission.photos, Permission.audio, Permission.videos]);
  }

  await permissions.request();

  MediaStore.appFolder = "MediaStorePlugin";

  runApp(
    MaterialApp(
      theme: ThemeData(primarySwatch: Colors.teal),
      home: const MyApp(),
    ),
  );
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int _platformSDKVersion = 0;

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  Future<void> initPlatformState() async {
    try {
      _platformSDKVersion = await mediaStorePlugin.getPlatformSDKInt();
    } on PlatformException {
      _platformSDKVersion = -1;
    }

    if (!mounted) return;

    setState(() {
      _platformSDKVersion = _platformSDKVersion;
    });

    print(await mediaStorePlugin.getFilePathFromUri(
        uriString: 'content://media/external/images/media/1000000056'));
    print(await mediaStorePlugin.getFilePathFromUri(
        uriString: 'content://media/external_primary/images/media/1000000057'));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('media_store_plus_example'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text.rich(
              TextSpan(text: 'Running on: ', children: [
                TextSpan(
                    text: _platformSDKVersion.toString(),
                    style: const TextStyle(fontWeight: FontWeight.bold)),
              ]),
            ),
            const SizedBox(height: 10),
            const Text(
              'Save file in...',
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                // Navigate to ImageSaveScreen
              },
              child: const Text("Image Folder"),
            ),
            ElevatedButton(
              onPressed: () {
                // Navigate to AudioSaveScreen
              },
              child: const Text("Audio Folder"),
            ),
            ElevatedButton(
              onPressed: () {
                // Navigate to VideoSaveScreen
              },
              child: const Text("Video Folder"),
            ),
            ElevatedButton(
              onPressed: () {
                // Navigate to Download folder screen
              },
              child: const Text("Download Folder"),
            ),
            ElevatedButton(
              onPressed: () {
                // Navigate to ReadWriteScreenAPI33OrUp
              },
              child: const Text("Read/Write API 33 or Upper Folder"),
            ),
          ],
        ),
      ),
    );
  }
}

此示例代码包括了初始化插件、请求必要权限、设置应用专属文件夹以及展示当前设备的API级别等基本功能。每个按钮点击后可以导航到不同的页面,实现对不同类型的媒体文件(图像、音频、视频)的保存和读取操作。

更多信息

更多详细文档请参阅官方文档。此外,查看插件源码也能帮助理解其工作原理。如果您有任何问题或建议,欢迎通过GitHub Issues提交反馈。


更多关于Flutter媒体存储管理插件media_store_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter媒体存储管理插件media_store_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用Flutter媒体存储管理插件media_store_plus的代码案例。这个插件允许你访问和管理设备上的媒体文件,如图片和视频。

首先,确保你的Flutter项目中已经添加了media_store_plus插件。你可以在你的pubspec.yaml文件中添加以下依赖项:

dependencies:
  flutter:
    sdk: flutter
  media_store_plus: ^x.y.z  # 请使用最新版本号

然后运行flutter pub get来安装该插件。

接下来是一个完整的示例代码,展示了如何使用media_store_plus插件来访问设备的媒体存储,并列出其中的图片和视频文件。

示例代码

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Media Store Plus Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MediaStoreScreen(),
    );
  }
}

class MediaStoreScreen extends StatefulWidget {
  @override
  _MediaStoreScreenState createState() => _MediaStoreScreenState();
}

class _MediaStoreScreenState extends State<MediaStoreScreen> {
  List<MediaFile> _mediaFiles = [];

  @override
  void initState() {
    super.initState();
    _getMediaFiles();
  }

  Future<void> _getMediaFiles() async {
    try {
      // 获取图片文件
      List<MediaFile> images = await MediaStore.getImages(
        type: MediaType.image,
        pageSize: 20, // 每次请求的数量
      );

      // 获取视频文件
      List<MediaFile> videos = await MediaStore.getVideos(
        type: MediaType.video,
        pageSize: 20, // 每次请求的数量
      );

      // 合并图片和视频文件
      List<MediaFile> allMediaFiles = [...images, ...videos];

      // 更新状态
      setState(() {
        _mediaFiles = allMediaFiles;
      });
    } catch (e) {
      print('Error fetching media files: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Media Store Plus Demo'),
      ),
      body: _mediaFiles.isEmpty
          ? Center(child: Text('Loading media files...'))
          : ListView.builder(
              itemCount: _mediaFiles.length,
              itemBuilder: (context, index) {
                MediaFile mediaFile = _mediaFiles[index];
                return ListTile(
                  leading: Image.memory(
                    mediaFile.thumbnail?.data ?? Uint8List(),
                    fit: BoxFit.cover,
                    width: 50,
                    height: 50,
                  ),
                  title: Text(mediaFile.displayName ?? 'Unknown'),
                  subtitle: Text(mediaFile.path),
                  trailing: IconButton(
                    icon: Icon(Icons.open_in_new),
                    onPressed: () {
                      // 打开文件(需要额外的插件或方法来实现)
                      // 例如:使用url_launcher插件打开视频或图片
                      // 这里仅作为示例,不做具体实现
                    },
                  ),
                );
              }),
    );
  }
}

注意事项

  1. 权限处理: 在使用media_store_plus插件之前,你需要在AndroidManifest.xml中添加相应的权限(如READ_EXTERNAL_STORAGE)。同时,你还需要在运行时请求这些权限,可以使用permission_handler插件来处理权限请求。

  2. 依赖关系: 确保你的FlutterDart环境是最新的,并且media_store_plus插件的版本与你的Flutter SDK兼容。

  3. 其他功能media_store_plus插件还提供了其他功能,如删除媒体文件、创建缩略图等。你可以查阅其官方文档以获取更多信息和示例代码。

希望这个示例代码对你有所帮助!

回到顶部