搜尋分類、套件與程式碼儲存庫

add_to_gallery 封面
套件詳情v1.0.0

add_to_gallery

將圖片和影片的副本儲存至 Android 相簿和 iOS 照片

AndroidiOS
近 30 天下載
149
喜歡數
28
Pub 分數
160

安裝套件

flutter pub add add_to_gallery

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

add_to_gallery 套件讓 Flutter 應用程式能夠將影像與影片儲存至 Android 與 iOS 裝置的原生相簿中。它提供一個簡單的介面來匯出媒體檔案,確保它們會出現在使用者的預設相簿應用程式中。這對於產生或捕捉媒體的應用程式(例如照片編輯器、相機工具或內容創作者)特別有用。該套件能順暢處理平台特定的差異,於兩個作業系統上提供一致的行為。它不會修改原始檔案,而是在系統的媒體儲存空間中建立一份複本。

適用情境

  • 從相機保存捕獲的照片
  • 從照片編輯器匯出已編輯的影像
  • 將生成的影片新增至使用者的資料庫
  • 與系統相簿共享使用者建立的內容
  • 自動化媒體備份到原生儲存

主要特色

  • 對 Android 和 iOS 的跨平台支援
  • 儲存副本到原生圖庫
  • 所需設定最少
  • 處理平台特定的檔案路徑
  • 保留原始媒體檔案

適合對象

  • 照片編輯應用
  • 相機整合功能
  • 內容創作工具
  • 需要媒體共享的應用程式
  • 希望自動同步畫廊的用戶

使用建議

  • 需要在兩個平台上具備適當的權限
  • 不支援網頁或桌面端
  • 檔案大小可能會影響效能
  • 畫廊元資料的自訂有限
  • 某些設備可能需要使用者確認

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

Add to Gallery

Adds images and videos to the Android Gallery and iOS Photos

View example app

💡 There are a couple of important notes about Google photos and iOS filepaths. Jump to the end of this page for info!

Installation

Add add_to_gallery as a dependency in your pubspec.yaml file.

Permissions

You need the following permissions in your app:

  • iOS
    • NSPhotoLibraryUsageDescription
    • This allows the plugin to use the PHPhotoLibrary APIs to add assets to the user's photo library.
  • Android
    • READ_EXTERNAL_STORAGE
    • WRITE_EXTERNAL_STORAGE
    • If you target Android 10, you will also need the requestLegacyExternalStorage="true" in your AndroidManifest.
    • NB: Android < 13 needs storge permission
    • NB: Android >= 13 needs photos permission
      • ^ the example app shows how to request these permissions

This plugin does not manage permissions for you. By excluding permissions from our plugin we have created a simple, reliable plugin.

We recommend using permission_handler to handle permissions.

Usage

There's only one method. It copies the source file to the gallery and returns the new file.

File file = await AddToGallery.addToGallery(
  originalFile: File('/Some/Media/Path.jpg'),
  albumName: 'My Awesome App',
  deleteOriginalFile: false,
  keepFilename: true,
);
print("Savd to gallery with Path: ${file.path}");

Using permission_handler, this may look like:

Future<void> _addToGalleryExample() async {
  try {
    await _grantPermissions();
    File file = await AddToGallery.addToGallery(
      originalFile: File('/Some/Media/Path.jpg'),
      albumName: 'My Awesome App',
      deleteOriginalFile: true,
      keepFilename: true,
    );
    print("Savd to gallery with Path: ${file.path}");
  } catch(e) {
    print("Error: $e");
  }
}

Future<void> _grantPermissions() async {
  final int? androidVersion = Platform.isAndroid
      ? (await DeviceInfoPlugin().androidInfo).version.sdkInt
      : null;
  // We need storage on:
  // - iOS to pick files from other apps
  // - Android < 13 for legacy access
  if (Platform.isIOS || (androidVersion != null && androidVersion <= 32)) {
    if (!await Permission.storage.request().isGranted) {
      throw ('Storage Permission Required');
    }
  }
  // We need photos on:
  // - iOS to pick files from this app
  // - Android >= 13
  if (Platform.isIOS || (androidVersion != null && androidVersion >= 33)) {
    if (!await Permission.photos.request().isGranted) {
      throw ('Photos Permission Required');
    }
  }
}

Example app

The example app shows a few more edge-cases in action.

  • Uses permission_handler to request permissions
  • Uses image_picker to take photos with the camera
  • Copies assets to the gallery
  • Uses shared_preferences to save and read the file path locally
    • This shows that the assets are still accessible between reboots

Credits & Comparison

Add to Gallery is based on gallery_saver with some notable differences. Enough to warrant a new package rather than a pull-request. Generally speaking, I've simplified the API and unified the behaviour on iOS and Android. It also supports scoped storage on Android (which will be enforced with Android 11)

Big thanks to the Tecocraft LTD team for Android functionality on Android 10 and 11.

Feature gallery_saver
original package
add_to_gallery
this package
General Behaviour Android
  • 🔥 Source file is copied to the gallery
  • 🔥 The copy is not a tmp file
  • 👎 The file path is not returned
  • 👎 No way to find the new file path
iOS
  • 🔥 Source file is linked to the gallery
  • 👎 If the source file is in a tmp directory it may be garbage collected
  • 👎 The file path is not returned
  • 🔥 The original file path is correct
Android and iOS
  • 🔥 Source file is copied to the getApplicationDocumentsDirectory for persistence
  • 🔥 Your app has permission to access the file
  • 🔥 The new file path is returned
  • Automatically deletes sourceFile - defaults to false
Return Value Returns bool for the success of the operation Returns a File pointing to the new file in the gallery
Remote Files Automatically downloads files that start with http Does not download files that start with http
Album Name Optional with default values Is required
Image Manipulation Android
  • Rotates images according to EXIF data
  • Creates Thumbnails
iOS
  • Does not manipulate images
Does not manipulate images
Permissions Handled within the plugin. The first-call fails silently due to permissions race-condition Not handled within the plugin

💡 An Important Note about Google photos

Google Photos has a built-in feature to remove exact duplicates. It can be confusing to see your media disappearing like this. I considered addressing this behaviour in the plugin, but decided against it. I expect plugin users to be creating unique images with the camera or other methods.

💡 An Important Note about iOS Filepaths

Simply, it will change when new versions of your app are released. For example:

  • The user installs 1.0.0 of your app, the path is: .../<A-UNIQUE-DIRECTORY>/Documents/your-file.jpg
  • The user upgrades to 2.0.0, the path is now: .../<A-DIFFERENT-UNIQUE-DIRECTORY>/Documents/your-file.jpg

This becomes an issue when you try to access the file later, as the path has changed.

To handle this, you can use the path_provider package to build the path dynamically. Here's an example:

// 1. We used `add_to_gallery` to save a file, and stored the `file.path` locally (in a db, shared preferences etc.)
// 2. The user then updated their app
// 3. They re-opened the app, and we want to access the file again:
import 'package:path_provider/path_provider.dart';
final fileName = basename(filePath);
storageDirectory = await getApplicationDocumentsDirectory();
final sourcePath = '${storageDirectory.path}/$fileName'; // This is the new path

所屬分類

依賴

依賴清單 3 項

原始碼儲存庫

使用此套件的專案

暫無相關資料。