개요
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에서 앱별 전용 앨범 폴더
- 권한 상태와 거부 후 앱 설정 바로가기
- 결과마다 하나의 이벤트, 실패 시 오류 메시지 포함
지원 플랫폼
다른 플랫폼에서는 isSupported가 false를 반환하므로 동일한 코드를 크로스 플랫폼 앱에 그대로 둘 수 있습니다.
시작하기
애플리케이션 디스크립터에 확장을 추가합니다:
<extensions>
<extensionID>com.klug.gallery</extensionID>
</extensions>
iOS: 앱이 사진에 저장하는 이유를 InfoAdditions에 설명하세요:
<key>NSPhotoLibraryAddUsageDescription</key> <string>Saves your snapshots and videos to Photos.</string>
Android: Android 6~9에서만 필요하며, 이후 버전에서는 무시됩니다.
<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로 전달됩니다. 전체 문서 →
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" ); }
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 );
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.AUTHORISATION | status = 새 권한 상태 |
| GalleryEvent.ADD_COMPLETE | 이미지가 저장됨 |
| GalleryEvent.ADD_ERROR | status = 오류 메시지 |
| GalleryEvent.ADD_FILE_COMPLETE | 파일이 저장됨 |
| GalleryEvent.ADD_FILE_ERROR | status = 오류 메시지 |
KlugGallery 구매
AIR 애플리케이션 1개에 대한 연간 라이선스이며 12개월간 모든 업데이트를 제공합니다. 결제 후 확장, ActionScript 라이브러리, 문서를 이메일로 보내 드리며, 보통 영업일 기준 1일 이내입니다. 라이선스 및 약관
요구 사항
| AIR SDK | 51.x (HARMAN) |
| iOS | iOS 13 이상(추가 전용 접근은 iOS 14부터) |
| Android | Android 6.0 (API 23) 이상 |
| iOS 디스크립터 | InfoAdditions의 NSPhotoLibraryAddUsageDescription |
| Android 디스크립터 | 권한 액티비티, Android 6~9용 저장소 권한 |