Flutter云端存储插件save_in_cloud的使用

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

Flutter云端存储插件save_in_cloud的使用

概述

save_in_cloud 是一个Flutter插件,允许你从Google Drive读取、下载、创建、编辑和搜索JSON文件。你还可以创建文件夹并将文件保存到这些文件夹中。

使用前准备

项目设置
  1. 首先登录或注册 Google Cloud Console
  2. 创建或选择一个项目。
激活API
  1. 点击左上角的导航菜单。
  2. 进入 “APIs & Services” > “Library”,选择或搜索 “Google Drive API” 并启用它。
OAuth 2.0 设置
  1. 从导航菜单中选择 “APIs and Services”,然后点击 “Credentials”。
  2. 点击顶部的 “+ CREATE CREDENTIALS”,然后选择 “OAuth client ID”。
  3. 点击 “CONFIGURE CONSENT SCREEN”。
  4. 选择用户类型 “External” 并点击 “CREATE”。
  5. 填写带有红色星号的字段并点击 “SAVE AND CONTINUE”。
  6. 点击 “ADD OR REMOVE SCOPES” 并手动输入 https://www.googleapis.com/auth/drive.file,点击 “ADD TO TABLE” 然后点击 “UPDATE”。之后点击 “SAVE AND CONTINUE”。
  7. 添加测试用户,添加完成后点击 “SAVE AND CONTINUE”。
  8. 如果所有数据正确,点击 “BACK TO THE DASHBOARD”。
  9. 再次选择 “Credentials”,在顶部点击 “+ CREATE CREDENTIALS” 选择 “OAuth Client ID”。
  10. 在 “Application type” 下选择适当的操作系统(例如 Android)。
  11. 在 “Name” 中选择控制台名称,在 “Package name” 中输入你的包名(例如 com.example.app),最后输入 SHA1。如何生成SHA-1
  12. 最后点击 “CREATE”。
API Key 设置
  1. 点击顶部的 “+ CREATE CREDENTIALS”,然后选择 “API key”。
  2. 当API Key创建完成后,复制它并关闭窗口。
  3. 在 “API Keys” 列表中点击相应的键以查看信息。
  4. 在 “API restrictions” 下选择 “Restrict key”。
  5. 在 “Select APIs” 中选择 “Google Drive API” 并确认。
  6. 点击 “SAVE”。

生成的API Key是此插件所需的。

其他信息

该插件使用了以下依赖包:

  • google_sign_in
  • googleapis
  • http
  • path_provider

示例代码

以下是一个完整的示例demo,展示了如何使用 save_in_cloud 插件进行各种操作。

import 'dart:developer';

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

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomeScreen(),
    );
  }
}

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

  [@override](/user/override)
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  Map content = {
    "Map": {},
    "String": "string",
    "int": 0,
    "bool": true,
    "List": []
  };
  Map newContent = {
    "Map": {},
    "String": "string",
    "int": 0,
    "bool": true,
    "List": ["updated"]
  };
  String filename = "file";
  String folderName = "Folder";
  String description = "This is a description of the folder";
  String apiKey = "YOUR_API_KEY"; // todo: insert the API key here

  /// 登录Google,权限范围为:https://www.googleapis.com/auth/drive.file
  void _signIn() async {
    bool signIn = await GoogleDriveWrite.signIn();

    if (signIn) {
      log("用户已登录", name: "Sign in");
    } else {
      log("用户未登录", name: "Sign in");
    }
  }

  /// 注销
  void _signOut() async {
    await GoogleDriveWrite.signOut();
    log("用户已注销", name: "Sign out");
  }

  /// 创建JSON文件
  void _createJsonFile() async {
    int? createJsonFileCode = await GoogleDriveWrite.createJsonFile(
        filename: filename, content: content);

    if (createJsonFileCode == 1) {
      log("用户未登录", name: "_createJsonFile()");
    } else if (createJsonFileCode == 2) {
      log("创建空文件时出错", name: "_createJsonFile()");
    } else if (createJsonFileCode == 3) {
      log("上传文件时出错", name: "_createJsonFile()");
    } else {
      log("文件创建成功", name: "_createJsonFile()");
    }
  }

  /// 创建无描述的文件夹
  void _createFolder() async {
    bool createFolder =
        await GoogleDriveWrite.createFolder(folderName: folderName);

    if (createFolder) {
      log("文件夹创建成功", name: "_createFolder()");
    } else {
      log("用户未登录", name: "_createFolder()");
    }
  }

  /// 创建带描述的文件夹
  void _createFolderWithDescription() async {
    bool createFolder = await GoogleDriveWrite.createFolder(
        folderName: folderName, description: description);

    if (createFolder) {
      log("文件夹创建成功", name: "_createFolderWithDescription()");
    } else {
      log("用户未登录", name: "_createFolderWithDescription()");
    }
  }

  /// 更新现有文件
  void _updateJsonFile() async {
    int? updateJsonFileCode = await GoogleDriveWrite.updateJsonFile(
        filename: filename, content: newContent);

    if (updateJsonFileCode == 1) {
      log("用户未登录", name: "_updateJsonFile()");
    } else if (updateJsonFileCode == 2) {
      log("HTTP连接错误", name: "_updateJsonFile()");
      log("错误代码指南", name: "Error code guide");
    } else if (updateJsonFileCode == 3) {
      log("文件未找到", name: "_updateJsonFile()");
    } else if (updateJsonFileCode == 4) {
      log("文件创建失败", name: "_updateJsonFile()");
      log("错误代码指南", name: "Error code guide");
    } else {
      log("文件更新成功", name: "_updateJsonFile()");
    }
  }

  /// 在现有文件夹中创建JSON文件
  void _createJsonFileInFolder() async {
    int createJsonFileInFolderCode =
        await GoogleDriveWrite.createJsonFileInFolder(
            folderName: folderName, filename: filename, content: content);

    if (createJsonFileInFolderCode == 1) {
      log("用户未登录", name: "_createJsonFileInFolder()");
    } else if (createJsonFileInFolderCode == 2) {
      log("HTTP连接错误", name: "_createJsonFileInFolder()");
      log("错误代码指南", name: "Error code guide");
    } else {
      log("文件创建成功", name: "_createJsonFileInFolder()");
    }
  }

  /// 搜索文件或文件夹
  void _searchFile() async {
    Map? searchFileMap = await GoogleDriveRead.searchFile(filename);

    if (searchFileMap == null) {
      log("用户未登录", name: "_searchFile()");
    } else if (searchFileMap.isEmpty) {
      log("未找到文件", name: "_searchFile()");
    } else if (searchFileMap.keys.toList().first == "search error") {
      log("搜索错误: $searchFileMap", name: "_searchFile()");
    } else {
      log("文件已找到.\n$searchFileMap", name: "_searchFile()");
    }
  }

  /// 下载文件到: /storage/emulated/0/Android/data/com.YOUR_ORGANIZE.APP_NAME/files/downloads
  void _downloadFile() async {
    int downloadFileCode =
        await GoogleDriveRead.downloadFile(filename: filename, apiKey: apiKey);

    if (downloadFileCode == 1) {
      log("用户未登录", name: "_downloadFile()");
    } else if (downloadFileCode == 2) {
      log("未找到文件", name: "_downloadFile()");
    } else {
      log("文件下载成功", name: "_downloadFile()");
    }
  }

  /// 读取本地JSON文件
  void _readJsonFile() async {
    Map? readJsonFileMap =
        await GoogleDriveRead.readJsonFile(filename: filename, apiKey: apiKey);

    if (readJsonFileMap == null) {
      log("用户未登录", name: "_readJsonFile()");
    } else if (readJsonFileMap.isEmpty) {
      log("未找到文件", name: "_readJsonFile()");
    } else {
      log("JSON 文件: \n$readJsonFileMap\n", name: "_readJsonFile()");
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("首页"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              child: const Text("登录"),
              onPressed: () => _signIn(),
            ),
            ElevatedButton(
              child: const Text("注销"),
              onPressed: () => _signOut(),
            ),
            ElevatedButton(
              child: const Text("创建JSON文件"),
              onPressed: () => _createJsonFile(),
            ),
            ElevatedButton(
              child: const Text("创建文件夹"),
              onPressed: () => _createFolder(),
            ),
            ElevatedButton(
              child: const Text("创建带描述的文件夹"),
              onPressed: () => _createFolderWithDescription(),
            ),
            ElevatedButton(
              child: const Text("更新JSON文件"),
              onPressed: () => _updateJsonFile(),
            ),
            ElevatedButton(
              child: const Text("在文件夹中创建JSON文件"),
              onPressed: () => _createJsonFileInFolder(),
            ),
            ElevatedButton(
              child: const Text("搜索文件或文件夹"),
              onPressed: () => _searchFile(),
            ),
            ElevatedButton(
              child: const Text("下载JSON文件"),
              onPressed: () => _downloadFile(),
            ),
            ElevatedButton(
              child: const Text("读取JSON文件"),
              onPressed: () => _readJsonFile(),
            ),
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


当然,关于Flutter中的云端存储插件save_in_cloud(请注意,实际中可能没有名为save_in_cloud的官方或广泛使用的插件,这里我将以一个通用的Flutter云端存储插件为例,比如使用Firebase Storage,来展示如何实现云端存储功能),以下是一个简单的代码案例,展示如何在Flutter应用中使用Firebase Storage进行文件上传。

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

dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^1.10.0 # 确保使用最新版本
  firebase_storage: ^10.0.0 # 确保使用最新版本

然后,运行flutter pub get来安装依赖。

接下来,按照Firebase的官方文档设置你的Firebase项目,并获取所需的配置信息(如google-services.json文件)。

在你的main.dart文件中,你可以这样使用Firebase Storage进行文件上传:

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'dart:io';
import 'package:image_picker/image_picker.dart'; // 用于选择图片

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final ImagePicker _picker = ImagePicker();
  File? _imageFile;

  Future<void> _pickImage(ImageSource source) async {
    final pickedFile = await _picker.pickImage(source: source);

    if (pickedFile != null) {
      setState(() {
        _imageFile = File(pickedFile.path);
      });

      // 上传图片到Firebase Storage
      _uploadImageToFirebase(_imageFile!);
    }
  }

  Future<void> _uploadImageToFirebase(File imageFile) async {
    // 创建一个Firebase Storage的引用
    final Reference storageRef = FirebaseStorage.instance.ref().child('images/${imageFile.basename}');

    // 上传文件到Storage
    final UploadTask uploadTask = storageRef.putFile(imageFile);

    // 监听上传进度
    uploadTask.snapshotEvents.listen((TaskSnapshot snapshot) {
      if (snapshot.hasError) {
        print('Upload failed: ${snapshot.error}');
      } else {
        // 上传百分比
        double progress = (snapshot.bytesTransferred / snapshot.totalBytes!) * 100;
        print('Upload is ${progress.toStringAsFixed(2)}% done');
      }
    });

    // 等待上传完成并获取下载URL
    final UploadTaskSnapshot uploadTaskSnapshot = await uploadTask.whenComplete(() {});
    final String downloadUrl = await uploadTaskSnapshot.ref.getDownloadURL();

    print('File uploaded successfully: $downloadUrl');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Firebase Storage Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _imageFile == null
                ? Text('No image selected.')
                : Image.file(_imageFile!),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => _pickImage(ImageSource.gallery),
              child: Text('Pick Image from Gallery'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: () => _pickImage(ImageSource.camera),
              child: Text('Pick Image from Camera'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个例子中,我们使用了firebase_corefirebase_storage插件,以及image_picker插件来选择图片。用户可以从图库或相机中选择图片,然后该图片会被上传到Firebase Storage。

请确保你的Firebase项目已经正确配置,并且你的应用拥有访问Firebase Storage的权限。你可能还需要在Firebase控制台中设置存储规则。

注意:由于save_in_cloud可能不是一个真实存在的插件,上述代码使用了Firebase Storage作为替代方案来展示云端存储的基本用法。如果你确实有一个名为save_in_cloud的特定插件,请参考该插件的官方文档进行集成。

回到顶部