main.dart

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
import 'package:file_picker/file_picker.dart';
import 'package:permission_handler/permission_handler.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
} class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
} class _HomePageState extends State<HomePage> {
String url = "https://i.loli.net/2020/01/14/w1dcNtf4SECG6yX.jpg"; Offset _tapPosition; void _showCustomMenu() {
final RenderBox overlay = Overlay.of(context).context.findRenderObject(); showMenu(
context: context,
items: <PopupMenuEntry<int>>[
const PopupMenuItem<int>(
value: 1,
child: Text('Download'),
),
],
position: RelativeRect.fromRect(
_tapPosition & Size.zero, // smaller rect, the touch area
Offset.zero & overlay.size // Bigger rect, the entire screen
),
).then<void>((int r) {
if (r == null) {
print('cancel');
return;
} if (r == 1) _download();
});
} void _storePosition(TapDownDetails details) {
_tapPosition = details.globalPosition;
} void _download() async {
/// 自动选择文件夹
/// /Android/data/com.<appname>/files
// final directory = await getExternalStorageDirectory();
// if (directory != null) {
// var dirPath = path.join(directory.path, "images");
// var dir = Directory(dirPath); // await dir.create(recursive: true); // var name = path.basename(url);
// var p = path.join(dirPath, name); // print(p);
// await File(p).writeAsBytes(r.bodyBytes);
// print("save ok");
// } // 1. 获取权限
var storageStatus = await Permission.storage.status; // 没有权限则申请
if(storageStatus != PermissionStatus.granted) {
storageStatus = await Permission.storage.request();
if(storageStatus != PermissionStatus.granted) {
return;
}
} // 2. 获取保存目录
String dpath = await FilePicker.getDirectoryPath();
print(dpath); if (dpath != null) {
var name = path.basename(url);
var p = path.join(dpath, name); print(p); // 3. 从网络获取图片保存到用户手机
var r = await http.get(url);
await File(p).writeAsBytes(r.bodyBytes);
print("save ok");
}
} @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Center(
child: GestureDetector(
onLongPress: _showCustomMenu, // 长按打开Menu菜单
onTapDown: _storePosition, // 按下去的时候记住位置
child: Image.network(url),
),
),
);
}
}

配置权限:

    <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

可能需要安装的包:

dependencies:
http:
path_provider:
path:
file_picker:
permission_handler:

flutter 长按图片保存到手机的更多相关文章

  1. 微信小程序base64图片保存到手机相册

    问题:base64图片不能直接用wx.saveImageToPhotosAlbum保存到手机相册 解决: 先用fs.writeFile写入本地文件,再wx.saveImageToPhotosAlbum ...

  2. 微信小程序点击按钮将图片保存到手机

    SaveCard: function(e) { let that = this; console.log('保存'); var imgSrc = e.currentTarget.dataset.img ...

  3. iOS,长按图片保存实现方法,轻松搞定!

    1.添加手势识别: UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@s ...

  4. ios 点击放大图片,保存至手机相册

    直接贴.m文件代码 #import "UIImageView+Scale.h" static CGRect oldframe; @implementation UIImageVie ...

  5. 微信APP长按图片禁止保存到本地

    项目遇到一个问题,在web页面中,禁止长按图片保存, 使用css属性:  img { pointer-events: none; } 或者  img { -webkit-user-select: no ...

  6. iOS UIWebview 长按图片,保存到本地相册

    我们所要解决的问题如题目所示:ios中,长按Webview中的图片,将图片保存到本地相册.解决方案:对load的html网页,执行js注入,通过在webview中执行js代码,来响应点击事件,通过js ...

  7. 小程序base64图片格式保存至手机相册

    // 保存图片至相册 saveImg() { //获取文件管理器对象 const fs = wx.getFileSystemManager() //文件保存路径 const Imgpath = wx. ...

  8. [Egret]长按图片分享、分享图片、本地存储

    egret 分享有API可以把一个显示对象树渲染成一个位图纹理,我把它赋值给 HTML 的 Image 元素,就实现了图片的显示,在微信中,通过长按图片可以分享出去.当然在其他浏览器可以保存在本地. ...

  9. js截图及绕过服务器图片保存至本地(html2canvas)

    今天要分享的是用html2canvas根据自己的需求生成截图,并且修复html2canvas截图模糊,以及绕过服务器图片保存至本地. 只需要短短的几行代码,就能根据所需的dom截图,是不是很方便,但是 ...

随机推荐

  1. docker基本使用-安装

    一. Linux服务器安装 1. 可参考官网安装步骤,点击前往官网 2. 常见问题 a. 在执行安装docker-ce命令的时候出错:requires containerd.io >= 1.2. ...

  2. Java——变量类型

    Java变量类型: 在Java中,所有的变量在使用前必须声明.格式: type identifier [ = value ][, identifier [ =value]-.]; type为Java数 ...

  3. Spark调优,性能优化

    Spark调优,性能优化 1.使用reduceByKey/aggregateByKey替代groupByKey 2.使用mapPartitions替代普通map 3.使用foreachPartitio ...

  4. Linux和Xshell安装

    Linux安装 开启虚拟机 选择语言 软件选择 点击软件→软件选择→基础设施服务器 安装位置 网络连接 开始安装 设置root密码 建议设置成root,因为密码忘了改起来很麻烦 登录 查看IP Xsh ...

  5. 小白搭建WNMP详细教程---NGINX安装与设置

    一.Nginx下载 Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Ramble ...

  6. Java排序算法(四)希尔排序1

    希尔排序交换法:分组+冒泡排序组合 一.测试类SortTest import java.util.Arrays; public class SortTest { private static fina ...

  7. 2015ACM/ICPC亚洲区沈阳站-重现赛 D - Pagodas

    题意:有\(n\)个数,开始给你两个数\(a\)和\(b\),每次找一个没出现过的数\(i\),要求满足\(i=j+k\)或\(i=j-k\),当某个人没有数可以选的时候判他输,问谁赢. 题解:对于\ ...

  8. 记一次亲身体验的勒索病毒事件 StopV2勒索病毒

    昨天给笔记本装了 windows server 2016 操作系统,配置的差不多之后,想使用注册机激活系统.使用了几个本地以前下载的注册机激活失败后,尝试上网搜索. 于是找到下面这个网站(这个网站下载 ...

  9. Open3d之交互式可视化

    本篇教程介绍了Open3D的可视化窗口的交互功能. # -*- coding:utf-8 -*- import copy import numpy as np import open3d as o3d ...

  10. [Golang]-2 Map关联数组与下划线(_)的意义

    目录 map 下划线(underscore) 用在import 用在返回值 用在变量 map map 是 Go 内置关联数据类型(在一些其他的语言中称为哈希 或者字典 ). func main() { ...