flutter 長按圖片儲存到手機
阿新 • • 發佈:2020-08-09
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: