Flutter云存储插件dropbox_client的使用

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

Flutter云存储插件dropbox_client的使用

dropbox_client 是一个用于访问Dropbox的Flutter插件。本文将介绍如何在Flutter项目中集成和使用该插件。

设置

注册Dropbox API应用

首先,你需要从 Dropbox开发者平台 注册一个Dropbox API应用,并获取你的Dropbox Key和Secret。

Android设置

AndroidManifest.xml文件中添加以下内容(替换DROPBOXKEY为你的Key):

<activity
    android:name="com.dropbox.core.android.AuthActivity"
    android:configChanges="orientation|keyboard"
    android:launchMode="singleTask">
    <intent-filter>
        <data android:scheme="db-DROPBOXKEY" />
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.BROWSABLE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

更多信息请参考 Dropbox Java SDK设置指南

iOS设置

  1. Info.plist中添加以下内容:
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>dbapi-8-emm</string>
    <string>dbapi-2</string>
</array>
  1. Info.plist中添加以下内容(替换DROPBOXKEY为你的Key):
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>db-DROPBOXKEY</string>
    </array>
    <key>CFBundleURLName</key>
    <string></string>
  </dict>
</array>
  1. 如果你使用Swift,请在AppDelegate.swift中添加以下代码:
import ObjectiveDropboxOfficial

override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    if let authResult = DBClientsManager.handleRedirectURL(url) {
        if authResult.isSuccess() {
            print("dropbox auth success")
        } else if (authResult.isCancel()) {
            print("dropbox auth cancel")
        } else if (authResult.isError()) {
            print("dropbox auth error \(authResult.errorDescription)")
        }
    }
    return true
}

更多信息请参考 Dropbox Objective-C SDK设置指南

使用示例

以下是一个完整的Flutter示例应用,展示了如何使用dropbox_client插件进行授权、上传和下载文件等操作。

import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:dropbox_client/dropbox_client.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

const String dropbox_clientId = 'test-flutter-dropbox';
const String dropbox_key = 'your_dropbox_key';
const String dropbox_secret = 'your_dropbox_secret';

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

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

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  String? accessToken;
  String? credentials;
  bool showInstruction = false;

  @override
  void initState() {
    super.initState();
    initDropbox();
  }

  Future<void> initDropbox() async {
    if (dropbox_key == 'your_dropbox_key') {
      showInstruction = true;
      return;
    }

    await Dropbox.init(dropbox_clientId, dropbox_key, dropbox_secret);

    SharedPreferences prefs = await SharedPreferences.getInstance();
    accessToken = prefs.getString('dropboxAccessToken');
    credentials = prefs.getString('dropboxCredentials');

    setState(() {});
  }

  Future<bool> checkAuthorized(bool authorize) async {
    final _credentials = await Dropbox.getCredentials();
    if (_credentials != null) {
      if (credentials == null || _credentials.isEmpty) {
        credentials = _credentials;
        SharedPreferences prefs = await SharedPreferences.getInstance();
        prefs.setString('dropboxCredentials', credentials!);
      }
      return true;
    }

    final token = await Dropbox.getAccessToken();
    if (token != null) {
      if (accessToken == null || accessToken!.isEmpty) {
        accessToken = token;
        SharedPreferences prefs = await SharedPreferences.getInstance();
        prefs.setString('dropboxAccessToken', accessToken!);
      }
      return true;
    }

    if (authorize) {
      if (credentials != null && credentials!.isNotEmpty) {
        await Dropbox.authorizeWithCredentials(credentials!);
        final _credentials = await Dropbox.getCredentials();
        if (_credentials != null) {
          print('authorizeWithCredentials!');
          return true;
        }
      }
      if (accessToken != null && accessToken!.isNotEmpty) {
        await Dropbox.authorizeWithAccessToken(accessToken!);
        final token = await Dropbox.getAccessToken();
        if (token != null) {
          print('authorizeWithAccessToken!');
          return true;
        }
      } else {
        await Dropbox.authorize();
        print('authorize!');
      }
    }
    return false;
  }

  Future<void> authorize() async {
    await Dropbox.authorize();
  }

  Future<void> authorizePKCE() async {
    await Dropbox.authorizePKCE();
  }

  Future<void> unlinkToken() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.remove('dropboxAccessToken');

    setState(() {
      accessToken = null;
    });
    await Dropbox.unlink();
  }

  Future<void> unlinkCredentials() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.remove('dropboxCredentials');

    setState(() {
      credentials = null;
    });
    await Dropbox.unlink();
  }

  Future<void> authorizeWithAccessToken() async {
    await Dropbox.authorizeWithAccessToken(accessToken!);
  }

  Future<void> authorizeWithCredentials() async {
    await Dropbox.authorizeWithCredentials(credentials!);
  }

  Future<void> getAccountName() async {
    if (await checkAuthorized(true)) {
      final user = await Dropbox.getAccountName();
      print('user = $user');
    }
  }

  Future<void> listFolder(String path) async {
    if (await checkAuthorized(true)) {
      final result = await Dropbox.listFolder(path);
      setState(() {
        list.clear();
        list.addAll(result);
      });
    }
  }

  Future<void> uploadTest() async {
    if (await checkAuthorized(true)) {
      var tempDir = await getTemporaryDirectory();
      var filepath = '${tempDir.path}/test_upload.txt';
      File(filepath).writeAsStringSync(
          'contents.. from ' + (Platform.isIOS ? 'iOS' : 'Android') + '\n');

      final result =
          await Dropbox.upload(filepath, '/test_upload.txt', (uploaded, total) {
        print('progress $uploaded / $total');
      });
      print(result);
    }
  }

  Future<void> downloadTest() async {
    if (await checkAuthorized(true)) {
      var tempDir = await getTemporaryDirectory();
      var filepath = '${tempDir.path}/test_download.zip'; // for iOS only!!
      print(filepath);

      final result = await Dropbox.download('/file_in_dropbox.zip', filepath,
          (downloaded, total) {
        print('progress $downloaded / $total');
      });

      print(result);
      print(File(filepath).statSync());
    }
  }

  final list = List<dynamic>.empty(growable: true);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Dropbox example app'),
      ),
      body: showInstruction
          ? Instructions()
          : Builder(
              builder: (context) {
                return Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Wrap(
                      children: <Widget>[
                        ElevatedButton(
                          child: Text('authorize'),
                          onPressed: authorize,
                        ),
                        ElevatedButton(
                          child: Text('authorizeWithAccessToken'),
                          onPressed: accessToken == null
                              ? null
                              : authorizeWithAccessToken,
                        ),
                        ElevatedButton(
                          child: Text('unlink'),
                          onPressed: unlinkToken,
                        ),
                      ],
                    ),
                    Wrap(
                      children: <Widget>[
                        ElevatedButton(
                          child: Text('authorizePKCE'),
                          onPressed: authorizePKCE,
                        ),
                        ElevatedButton(
                          child: Text('authorizeWithCredentials'),
                          onPressed: credentials == null
                              ? null
                              : authorizeWithCredentials,
                        ),
                        ElevatedButton(
                          child: Text('unlink'),
                          onPressed: unlinkCredentials,
                        ),
                      ],
                    ),
                    Wrap(
                      children: <Widget>[
                        ElevatedButton(
                          child: Text('list root folder'),
                          onPressed: () async {
                            await listFolder('');
                          },
                        ),
                        ElevatedButton(
                          child: Text('test upload'),
                          onPressed: () async {
                            await uploadTest();
                          },
                        ),
                        ElevatedButton(
                          child: Text('test download'),
                          onPressed: () async {
                            await downloadTest();
                          },
                        ),
                      ],
                    ),
                    Expanded(
                      child: ListView.builder(
                        itemCount: list.length,
                        itemBuilder: (context, index) {
                          final item = list[index];
                          final filesize = item['filesize'];
                          final path = item['pathLower'];
                          bool isFile = false;
                          var name = item['name'];
                          if (filesize == null) {
                            name += '/';
                          } else {
                            isFile = true;
                          }
                          return ListTile(
                              title: Text(name),
                              onTap: () async {
                                if (isFile) {
                                  final link = await Dropbox.getTemporaryLink(path);
                                  ScaffoldMessenger.of(context).showSnackBar(
                                      SnackBar(
                                          content: Text(link ??
                                              'getTemporaryLink error: $path')));
                                } else {
                                  await listFolder(path);
                                }
                              });
                        },
                      ),
                    ),
                  ],
                );
              },
            ),
    );
  }
}

class Instructions extends StatelessWidget {
  const Instructions({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text(
              'You need to get dropbox_key & dropbox_secret from https://www.dropbox.com/developers'),
          SizedBox(height: 20),
          Text('1. Update dropbox_key and dropbox_secret from main.dart'),
          SizedBox(height: 20),
          Text(
              "  const String dropbox_key = 'DROPBOXKEY';\n  const String dropbox_secret = 'DROPBOXSECRET';"),
          SizedBox(height: 20),
          Text(
              '2. (Android) Update dropbox_key from android/app/src/main/AndroidManifest.xml.\n  <data android:scheme="db-DROPBOXKEY" />'),
          SizedBox(height: 20),
          Text(
              '2. (iOS) Update dropbox_key from ios/Runner/Info.plist.\n  <string>db-DROPBOXKEY</string>'),
        ],
      ),
    );
  }
}

以上示例展示了如何初始化Dropbox客户端、授权用户、列出文件夹、上传和下载文件等基本操作。你可以根据自己的需求进一步扩展和修改这个示例。


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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用dropbox_client插件进行云存储操作的示例。这个插件允许你与Dropbox API进行交互,实现文件的上传、下载等功能。

首先,你需要在你的Flutter项目中添加dropbox_client插件。你可以通过修改pubspec.yaml文件来完成这一步:

dependencies:
  flutter:
    sdk: flutter
  dropbox_client: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来安装该插件。

接下来,你需要在Dropbox开发者门户中创建一个应用,并获取相应的API密钥和访问令牌。这些信息将用于在Flutter应用中认证和访问Dropbox。

下面是一个基本的示例,展示了如何使用dropbox_client插件上传文件到Dropbox:

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

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

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

class DropboxUploadPage extends StatefulWidget {
  @override
  _DropboxUploadPageState createState() => _DropboxUploadPageState();
}

class _DropboxUploadPageState extends State<DropboxUploadPage> {
  String _accessToken = '你的Dropbox访问令牌';  // 替换为你的Dropbox访问令牌
  String _uploadStatus = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Dropbox 文件上传示例'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(_uploadStatus),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                await uploadFileToDropbox();
              },
              child: Text('上传文件'),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> uploadFileToDropbox() async {
    setState(() {
      _uploadStatus = '正在上传...';
    });

    final DropboxClient dropboxClient = DropboxClient(_accessToken);

    // 读取本地文件
    final file = File('/path/to/your/local/file.txt');  // 替换为你的本地文件路径
    final fileBytes = await file.readAsBytes();

    // 准备上传参数
    final uploadRequest = UploadFileRequest(
      path: '/path/in/dropbox/folder/file.txt',  // 替换为你在Dropbox中的目标路径
      mode: WriteMode.overwrite,
      input: fileBytes,
    );

    try {
      final response = await dropboxClient.uploadFile(uploadRequest);
      setState(() {
        _uploadStatus = '上传成功: ${response.metadata?.pathLower}';
      });
    } catch (e) {
      setState(() {
        _uploadStatus = '上传失败: ${e.message}';
      });
    }
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,它包含一个按钮,用于上传本地文件到Dropbox。你需要替换以下占位符:

  • '你的Dropbox访问令牌':用你在Dropbox开发者门户获取的访问令牌替换。
  • '/path/to/your/local/file.txt':用你想要上传的本地文件的实际路径替换。
  • '/path/in/dropbox/folder/file.txt':用你在Dropbox中希望存储文件的目标路径替换。

确保你的Dropbox访问令牌是有效的,并且你的应用具有相应的权限来访问Dropbox API。

这个示例展示了基本的文件上传功能。dropbox_client插件还支持更多功能,如文件下载、文件列表获取等,你可以查阅插件的官方文档获取更多信息和示例。

回到顶部