上一篇博客中讲解了sentry的基本使用,文后提到了sentry的扩展使用,关于异常上报的同时截图进行上传。
要知道,在iOS或者安卓中截屏是一件很困难的事,涉及到的权限根本绕不过去,但是却可以通过绘制的方式拿到截屏,考虑到代码的一致性,降低iOS和安卓的开发,所以选择在flutter中对屏幕进行截屏。
图片的上传推荐两种方式:
1.通过接口上传到oss云服务器中,但相对的可能会有很多异常,导致服务器存储大量无用的图片,但也可以通过一定的方式定期清理;
2.通过将图片进行base64编码字符串,通过sentry提供的方式上传到sentry服务器,然后利用工具对编码字符串进行解码得到图片,缺点是图片太大的话base64字符串会非常长,有上传限制的话字符串会被截取,如果对图片进行压缩,会导致解码的图片又小又糊,只能看清哪个界面,不能看清界面上的文字;
第一种oss的方法就不再过多的解释。
下面先把如何截图并保存到本地的方式分享给大家:
1.在项目中任何地方都能进行截图的方式
//main中runApp中的MyApp中包一层RepaintBoundary
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
//写一个全局的globalKey,在全局任何地方都能使用
Glb().gKey = GlobalKey();
//使用这个组件来进行截图
return RepaintBoundary(
//key为定义的全局globalKey
key: Glb().gKey,
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyCenter(),
),
);
}
}
//获取截图,并保存到本地
Future<Uint8List> _capturePng(String eventID) async {
try {
//这里要用那个key,博主猜想,这里使用localKey也能解决问题,如Key('xxx')
RenderRepaintBoundary boundary =
Glb().gKey.currentContext.findRenderObject();
//pixelRatio压缩比例
var image = await boundary.toImage(pixelRatio: 1.0);
ByteData byteData = await image.toByteData(format: ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List(0);
//path_provider
Directory documentsDir = await getApplicationDocumentsDirectory();
Directory directory = new Directory(documentsDir.path+'/flutter');
if(!directory.existsSync()) {
directory.createSync();
}
final filename = eventID;
print('${directory.path}/$filename');
File('${directory.path}/$filename')
..createSync(recursive: true)
..writeAsBytesSync(pngBytes);
return pngBytes;//这个对象就是图片数据
} catch (e) {
print(e);
}
return null;
}
//关于存入iOS和安卓的路径,这里要引入一个pub:path_provider,可以帮助我们拿到iOS和安卓的路径,不需要自己再去写plugin。
//然后就可以自己来根据路径获取图片,上传图片,删除图片,删除图片的方法直接用delete函数就可以,Directory也可以直接用delete删除文件夹。
这篇博客就介绍到这里,相信看完你已经明白如何截图并存储到本地和删除的方法,上传oss的方法大家自己拿路径获取二进制数据直接上传就行。下一篇,将完整的讲述图片base64上传的方式。