← 所有扩展

原生扩展

KlugGallery

com.klug.gallery

无需 APM。下载即用,再简单不过。 只需更新 Adobe AIR SDK。如需帮助,我们随时为您服务。

在 iOS 和 Android 上,以系统提供的最小权限,将照片和视频从您的 AIR 应用保存到设备图库。

iOS Android 已投入生产 €19 / 年起 · 购买

概览

KlugGallery 将您 AIR 应用中的图片和视频保存到设备的相册:可以是快照之类的 BitmapData,也可以是您的应用录制或下载的照片或视频文件。

它只请求保存所需的权限。在 iPhone 和 iPad 上,它请求仅添加访问权限,因此您的应用永远看不到用户的照片库。在 Android 10 及更高版本上,保存完全不需要权限;在 Android 6 至 9 上,KlugGallery 会在运行时请求存储访问权限。

文件会保存在用户查找它们的位置:iOS 上的“照片”中,Android 上的 Pictures/<app name> 或 Movies/<app name> 中。

KlugGallery 每天都在我们的应用的 iOS 和 Android 版本中使用,这就是我们的概念验证。

特性

  • 自成一体:一个 ANE,无需添加核心库或依赖 ANE
  • 将 BitmapData 保存为 PNG 或 JPEG,可指定质量和文件名
  • 将照片或视频文件复制到图库(mp4、mov 和 m4v 会保存为视频)
  • iOS:仅添加照片访问权限,用户的照片库保持私密
  • Android 10 及更高版本:无需权限;Android 6 至 9:运行时存储权限
  • Android 上每个应用拥有自己的相册文件夹
  • 权限状态,以及被拒绝后跳转应用设置的快捷方式
  • 每个结果对应一个事件,失败时附带错误消息

支持的平台

iOS iPhone · iPad · 照片,仅添加访问权限
Android 手机 · 平板 · 折叠屏设备 · MediaStore

在其他平台上,isSupported 返回 false,因此同一份代码可以保留在跨平台应用中。

入门

将扩展添加到您的应用描述文件中:

app.xml
<extensions>
    <extensionID>com.klug.gallery</extensionID>
</extensions>

iOS:在 InfoAdditions 中说明您的应用为何要保存到“照片”:

app.xml · iPhone InfoAdditions
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Saves your snapshots and videos to Photos.</string>

Android:仅 Android 6 至 9 需要;更新的版本会忽略它。

app.xml · Android manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
                 android:maxSdkVersion="28"/>
<application>
    <activity android:name="com.klug.gallery.KlugGalleryPermissionActivity" android:exported="false"
              android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
</application>

代码示例

三个完整流程,取自在我们应用中运行的 API。每次调用都会立即返回;结果以 GalleryEvent 的形式到达。完整文档 →

1 · 保存快照
Snapshot.as
import com.klug.gallery.Gallery;
import com.klug.gallery.GalleryEvent;
import flash.display.BitmapData;

var gallery:Gallery = Gallery.getInstance();
gallery.addEventListener( GalleryEvent.ADD_COMPLETE, function( e:GalleryEvent ):void {
    showToast( "Saved to your gallery" );   // your app function
});
gallery.addEventListener( GalleryEvent.ADD_ERROR, function( e:GalleryEvent ):void {
    trace( "could not save: " + e.status );   // the error message
});

function saveSnapshot( picture:BitmapData ):void
{
    if ( !gallery.isSupported ) return;
    // "png" or "jpg"; quality 0..1 counts for jpg
    gallery.addBitmapData( picture, "jpg", 0.9, "snapshot.jpg" );
}
2 · 保存录制的视频
Video.as
import flash.filesystem.File;

gallery.addEventListener( GalleryEvent.ADD_FILE_COMPLETE, function( e:GalleryEvent ):void {
    showToast( "Video saved" );
});
gallery.addEventListener( GalleryEvent.ADD_FILE_ERROR, function( e:GalleryEvent ):void {
    trace( "could not save the video: " + e.status );
});

// a File or a native path; mp4, mov and m4v are saved as videos, everything else as a photo
var clip:File = File.applicationStorageDirectory.resolvePath( "clips/last.mp4" );
gallery.addFile( clip );
3 · 仅在需要时请求权限
Permission.as
var pending:BitmapData;

function save( picture:BitmapData ):void
{
    var status:String = gallery.authorisationStatus();
    if ( status == Gallery.AUTHORISED || status == Gallery.LIMITED )
        gallery.addBitmapData( picture, "png" );
    else if ( status == Gallery.DENIED || status == Gallery.RESTRICTED )
        askToOpenSettings();                 // your dialog, then gallery.openDeviceSettings()
    else
    {
        pending = picture;                   // not asked yet: show the system prompt
        gallery.requestAuthorisation();
    }
}

gallery.addEventListener( GalleryEvent.AUTHORISATION, function( e:GalleryEvent ):void {
    if ( e.status == Gallery.AUTHORISED && pending != null )
        gallery.addBitmapData( pending, "png" );
    pending = null;
});

API 概览

Gallery.getInstance()返回唯一实例。
isSupported在 iOS 和 Android 上为 True,其他平台为 false。
authorisationStatus()AUTHORISED、DENIED、NOT_DETERMINED、SHOULD_EXPLAIN、RESTRICTED、LIMITED 或 UNKNOWN。
requestAuthorisation()在用户尚未做出决定时显示系统提示。答复以 GalleryEvent.AUTHORISATION 的形式到达。
addBitmapData(bitmapData, format, quality, filename)将图片保存为 "png" 或 "jpg"。结果:ADD_COMPLETE 或 ADD_ERROR。
addFile(file)将照片或视频文件(File 或原生路径)复制到图库。结果:ADD_FILE_COMPLETE 或 ADD_FILE_ERROR。
canOpenDeviceSettings在可以打开应用设置的平台上为 True。
openDeviceSettings()打开您应用的设置页面。

事件

GalleryEvent:type 表示发生了什么,status 携带详细信息。

GalleryEvent.AUTHORISATIONstatus = 新的权限状态
GalleryEvent.ADD_COMPLETE图片已保存
GalleryEvent.ADD_ERRORstatus = 错误消息
GalleryEvent.ADD_FILE_COMPLETE文件已保存
GalleryEvent.ADD_FILE_ERRORstatus = 错误消息

购买 KlugGallery

一个 AIR 应用的年度许可,含 12 个月内的所有更新。付款后,您将通过电子邮件收到扩展、ActionScript 库和文档,通常在一个工作日内。许可与条款

基础版
€19 / 年
  • 一个 AIR 应用的许可
  • 12 个月内的所有更新
  • 不含支持
购买基础版
标准版
€149 / 年
  • 一个 AIR 应用的许可
  • 12 个月内的所有更新
  • 7 天内通过电子邮件答复
购买标准版
优先版
€299 / 年
  • 一个 AIR 应用的许可
  • 12 个月内的所有更新
  • 48 小时内通过电子邮件答复
购买优先版
税费在结账时由 Link (Stripe) 计算。您需要在结账时输入 AIR 应用的应用 ID。

要求

AIR SDK51.x (HARMAN)
iOSiOS 13 或更高版本(仅添加访问权限需 iOS 14 起)
AndroidAndroid 6.0 (API 23) 或更高版本
iOS 描述文件InfoAdditions 中的 NSPhotoLibraryAddUsageDescription
Android 描述文件权限 Activity;Android 6 至 9 的存储权限