You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter使用RepaintBoundary截图并通过image_gallery_saver保存后图片不显示在相册的问题解决

问题:Flutter使用RepaintBoundary截图后保存到相册不显示

我在Flutter中用RepaintBoundary组件实现Widget截图功能,搭配image_gallery_saver插件把截图保存到系统相册,但保存完成后相册里完全看不到新图片。相关代码如下:

class Utils {
 static Future capture(GlobalKey key) async {
 DateTime now;
 now = DateTime.now();
 if (key == null) return null;
 final RenderRepaintBoundary boundary = key.currentContext.findRenderObject();
 final image = await boundary.toImage(pixelRatio: 3.0);
 final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
 final pngByte = byteData.buffer.asUint8List();
 // print(pngByte);
 if (!(await Permission.storage.status.isGranted)) {
 await Permission.storage.request();
 }
 final result = await ImageGallerySaver.saveImage(
 Uint8List.fromList(pngByte),
 quality: 90,
 name: 'Screeshoot_${now.day.toString()}${now.hour.toString()}${now.minute.toString()}${now.second.toString()}');
 return result;
 // return pngByte;
 }
 }

请问该怎么解决这个问题?


解决方案

这种情况大多是因为系统媒体库没及时扫描到新保存的图片,或是权限、插件配置有遗漏,你可以按下面的步骤逐一排查解决:

  • 补全权限配置
    虽然你请求了storage权限,但不同Android版本的权限规则有差异:

    • Android 12及以下:需要在AndroidManifest.xml里添加<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    • Android 13+:要替换成<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
      iOS端则必须在Info.plist中添加NSPhotoLibraryAddUsageDescriptionNSPhotoLibraryUsageDescription,说明访问相册的原因,否则会直接权限失败。
  • 手动触发媒体库扫描
    部分设备上image_gallery_saver保存图片后,系统不会自动触发媒体库更新,导致相册看不到新图。你可以通过MethodChannel调用原生代码手动扫描:
    先在Flutter端添加调用逻辑:

    if (result != null && result['isSuccess']) {
      final path = result['filePath'];
      const platform = MethodChannel('your_app_channel/media_scanner');
      try {
        await platform.invokeMethod('scanFile', {'path': path});
      } on PlatformException catch (e) {
        print("扫描失败: ${e.message}");
      }
    }
    

    然后在Android的MainActivity中实现扫描方法:

    new MethodChannel(getFlutterView(), "your_app_channel/media_scanner").setMethodCallHandler(
      (call, result) -> {
        if (call.method.equals("scanFile")) {
          String path = call.argument("path");
          MediaScannerConnection.scanFile(this, new String[]{path}, null,
              (filePath, uri) -> result.success(null));
        } else {
          result.notImplemented();
        }
      }
    );
    
  • 检查保存结果与文件路径
    先打印result看看是否返回isSuccess: true,以及对应的filePath是否有效。如果路径不存在,说明保存过程本身出错,要排查截图生成或权限请求的逻辑;如果文件存在但相册不显示,就是媒体扫描的问题。另外你的文件名拼写有个小错误(Screeshoot应该是Screenshot),不过这不会影响显示。

  • 更新插件版本
    旧版本的image_gallery_saverpermission_handler可能对新系统版本兼容性不好,比如Android 13的权限适配。去pub.dev查一下这两个插件的最新版本,更新pubspec.yaml后重新执行flutter pub get

  • 重启相册或设备
    有时候系统缓存会导致新图片不显示,试试关闭相册应用再重新打开,或者直接重启设备,很多时候这就能解决问题。

内容的提问来源于stack exchange,提问作者Sunny Rahi

火山引擎 最新活动