update "mediumType" to be optional parameter of "listAlbums" to allow fetch both type of media
This commit is contained in:
parent
1db9b6966e
commit
6976ab8d3b
@ -98,7 +98,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
||||
val mediumType = call.argument<String>("mediumType")
|
||||
executor.submit {
|
||||
result.success(
|
||||
listAlbums(mediumType!!)
|
||||
listAlbums(mediumType)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -111,11 +111,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
||||
val take = call.argument<Int>("take")
|
||||
executor.submit {
|
||||
result.success(
|
||||
when (mediumType) {
|
||||
imageType -> listImages(albumId!!, newest!!, total!!, skip, take)
|
||||
videoType -> listVideos(albumId!!, newest!!, total!!, skip, take)
|
||||
else -> null
|
||||
}
|
||||
listMedia(mediumType, albumId!!, newest!!, total!!, skip, take)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -173,24 +169,24 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private fun listAlbums(mediumType: String): List<Map<String, Any>> {
|
||||
private fun listAlbums(mediumType: String?): List<Map<String, Any?>> {
|
||||
return when (mediumType) {
|
||||
imageType -> {
|
||||
listImageAlbums()
|
||||
listImageAlbums().values.toList()
|
||||
}
|
||||
videoType -> {
|
||||
listVideoAlbums()
|
||||
listVideoAlbums().values.toList()
|
||||
}
|
||||
else -> {
|
||||
listOf()
|
||||
listAllAlbums().values.toList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun listImageAlbums(): List<Map<String, Any>> {
|
||||
private fun listImageAlbums(): Map<String, Map<String, Any>> {
|
||||
this.context.run {
|
||||
var total = 0
|
||||
val albumHashMap = mutableMapOf<String, MutableMap<String, Any>>()
|
||||
val albumHashMap = hashMapOf<String, HashMap<String, Any>>()
|
||||
|
||||
val imageProjection = arrayOf(
|
||||
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
|
||||
@ -214,7 +210,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
||||
val album = albumHashMap[bucketId]
|
||||
if (album == null) {
|
||||
val folderName = cursor.getString(bucketColumn)
|
||||
albumHashMap[bucketId] = mutableMapOf(
|
||||
albumHashMap[bucketId] = hashMapOf(
|
||||
"id" to bucketId,
|
||||
"mediumType" to imageType,
|
||||
"name" to folderName,
|
||||
@ -228,25 +224,25 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
||||
}
|
||||
}
|
||||
|
||||
val albumList = mutableListOf<Map<String, Any>>()
|
||||
albumList.add(
|
||||
mapOf(
|
||||
val albumLinkedMap = linkedMapOf<String, Map<String, Any>>()
|
||||
albumLinkedMap.put(
|
||||
allAlbumId,
|
||||
hashMapOf(
|
||||
"id" to allAlbumId,
|
||||
"mediumType" to imageType,
|
||||
"name" to allAlbumName,
|
||||
"count" to total
|
||||
)
|
||||
)
|
||||
albumList.addAll(albumHashMap.values)
|
||||
return albumList
|
||||
albumLinkedMap.putAll(albumHashMap)
|
||||
return albumLinkedMap
|
||||
}
|
||||
return listOf()
|
||||
}
|
||||
|
||||
private fun listVideoAlbums(): List<Map<String, Any>> {
|
||||
private fun listVideoAlbums(): Map<String, Map<String, Any>> {
|
||||
this.context.run {
|
||||
var total = 0
|
||||
val albumHashMap = mutableMapOf<String, MutableMap<String, Any>>()
|
||||
val albumHashMap = hashMapOf<String, HashMap<String, Any>>()
|
||||
|
||||
val videoProjection = arrayOf(
|
||||
MediaStore.Video.Media.BUCKET_DISPLAY_NAME,
|
||||
@ -270,7 +266,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
||||
val album = albumHashMap[bucketId]
|
||||
if (album == null) {
|
||||
val folderName = cursor.getString(bucketColumn)
|
||||
albumHashMap[bucketId] = mutableMapOf(
|
||||
albumHashMap[bucketId] = hashMapOf(
|
||||
"id" to bucketId,
|
||||
"mediumType" to videoType,
|
||||
"name" to folderName,
|
||||
@ -284,16 +280,58 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
||||
}
|
||||
}
|
||||
|
||||
val albumList = mutableListOf<Map<String, Any>>()
|
||||
albumList.add(mapOf(
|
||||
"id" to allAlbumId,
|
||||
"mediumType" to videoType,
|
||||
"name" to allAlbumName,
|
||||
"count" to total))
|
||||
albumList.addAll(albumHashMap.values)
|
||||
return albumList
|
||||
val albumLinkedMap = linkedMapOf<String, Map<String, Any>>()
|
||||
albumLinkedMap.put(
|
||||
allAlbumId,
|
||||
hashMapOf(
|
||||
"id" to allAlbumId,
|
||||
"mediumType" to videoType,
|
||||
"name" to allAlbumName,
|
||||
"count" to total
|
||||
)
|
||||
)
|
||||
albumLinkedMap.putAll(albumHashMap)
|
||||
return albumLinkedMap
|
||||
}
|
||||
}
|
||||
|
||||
private fun listAllAlbums(): Map<String, Map<String, Any?>> {
|
||||
val imageMap = this.listImageAlbums()
|
||||
val videoMap = this.listVideoAlbums()
|
||||
val albumMap = (imageMap.keys + videoMap.keys).associateWith {
|
||||
mapOf(
|
||||
"id" to it,
|
||||
"mediumType" to null,
|
||||
"name" to imageMap[it]?.get("name"),
|
||||
"count" to (imageMap[it]?.get("count") ?: 0) as Int + (videoMap[it]?.get("count") ?: 0) as Int,
|
||||
)
|
||||
}
|
||||
return albumMap
|
||||
}
|
||||
|
||||
private fun listMedia(mediumType: String?, albumId: String, newest: Boolean, total: Int, skip: Int?, take: Int?): Map<String, Any?> {
|
||||
return when (mediumType) {
|
||||
imageType -> {
|
||||
listImages(albumId, newest, total, skip, take)
|
||||
}
|
||||
videoType -> {
|
||||
listVideos(albumId, newest, total, skip, take)
|
||||
}
|
||||
else -> {
|
||||
val images = listImages(albumId, newest, total, skip, take).get("items") as List<Map<String, Any?>>
|
||||
val videos = listVideos(albumId, newest, total, skip, take).get("items") as List<Map<String, Any?>>
|
||||
var items = (images +videos).sortedWith(compareBy<Map<String, Any?>> {it.get("creationDate") as Long}.thenBy { it.get("modifiedDate") as Long })
|
||||
if (newest) {
|
||||
items = items.reversed()
|
||||
}
|
||||
mapOf(
|
||||
"newest" to newest,
|
||||
"start" to (skip ?: 0),
|
||||
"total" to total,
|
||||
"items" to items
|
||||
)
|
||||
}
|
||||
}
|
||||
return listOf()
|
||||
}
|
||||
|
||||
private fun listImages(albumId: String, newest: Boolean, total: Int, skip: Int?, take: Int?): Map<String, Any> {
|
||||
|
@ -29,8 +29,7 @@ class _MyAppState extends State<MyApp> {
|
||||
|
||||
Future<void> initAsync() async {
|
||||
if (await _promptPermissionSetting()) {
|
||||
List<Album> albums =
|
||||
await PhotoGallery.listAlbums(mediumType: MediumType.image);
|
||||
List<Album> albums = await PhotoGallery.listAlbums();
|
||||
setState(() {
|
||||
_albums = albums;
|
||||
_loading = false;
|
||||
|
@ -14,14 +14,14 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
if(call.method == "listAlbums") {
|
||||
let arguments = call.arguments as! Dictionary<String, AnyObject>
|
||||
let mediumType = arguments["mediumType"] as! String
|
||||
let mediumType = arguments["mediumType"] as? String
|
||||
let hideIfEmpty = arguments["hideIfEmpty"] as? Bool
|
||||
result(listAlbums(mediumType: mediumType, hideIfEmpty: hideIfEmpty))
|
||||
}
|
||||
else if(call.method == "listMedia") {
|
||||
let arguments = call.arguments as! Dictionary<String, AnyObject>
|
||||
let albumId = arguments["albumId"] as! String
|
||||
let mediumType = arguments["mediumType"] as! String
|
||||
let mediumType = arguments["mediumType"] as? String
|
||||
let newest = arguments["newest"] as! Bool
|
||||
let skip = arguments["skip"] as? NSNumber
|
||||
let take = arguments["take"] as? NSNumber
|
||||
@ -90,11 +90,13 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
||||
|
||||
private var assetCollections : [PHAssetCollection] = []
|
||||
|
||||
private func listAlbums(mediumType: String, hideIfEmpty: Bool? = true) -> [NSDictionary] {
|
||||
private func listAlbums(mediumType: String?, hideIfEmpty: Bool? = true) -> [[String: Any?]] {
|
||||
self.assetCollections = []
|
||||
let fetchOptions = PHFetchOptions()
|
||||
var total = 0
|
||||
var albums = [NSDictionary]()
|
||||
if #available(iOS 9, *) {
|
||||
fetchOptions.fetchLimit = 1
|
||||
}
|
||||
var albums = [[String: Any?]]()
|
||||
var albumIds = Set<String>()
|
||||
|
||||
func addCollection (collection: PHAssetCollection, hideIfEmpty: Bool) -> Void {
|
||||
@ -106,14 +108,8 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
||||
guard !albumIds.contains(albumId) else { return }
|
||||
albumIds.insert(albumId)
|
||||
|
||||
let options = PHFetchOptions()
|
||||
options.predicate = self.predicateFromMediumType(mediumType: mediumType)
|
||||
if #available(iOS 9, *) {
|
||||
fetchOptions.fetchLimit = 1
|
||||
}
|
||||
let count = PHAsset.fetchAssets(in: collection, options: options).count
|
||||
let count = countMedia(collection: collection, mediumType: mediumType)
|
||||
if(count > 0 || !hideIfEmpty) {
|
||||
total+=count
|
||||
self.assetCollections.append(collection)
|
||||
albums.append([
|
||||
"id": collection.localIdentifier,
|
||||
@ -156,15 +152,15 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
||||
"id": "__ALL__",
|
||||
"mediumType": mediumType,
|
||||
"name": "All",
|
||||
"count" : countMedia(collection: nil, mediumTypes: [mediumType]),
|
||||
"count" : countMedia(collection: nil, mediumType: mediumType),
|
||||
], at: 0)
|
||||
|
||||
return albums
|
||||
}
|
||||
|
||||
private func countMedia(collection: PHAssetCollection?, mediumTypes: [String]) -> Int {
|
||||
private func countMedia(collection: PHAssetCollection?, mediumType: String?) -> Int {
|
||||
let options = PHFetchOptions()
|
||||
options.predicate = self.predicateFromMediumTypes(mediumTypes: mediumTypes)
|
||||
options.predicate = self.predicateFromMediumType(mediumType: mediumType)
|
||||
if(collection == nil) {
|
||||
return PHAsset.fetchAssets(with: options).count
|
||||
}
|
||||
@ -172,13 +168,13 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
||||
return PHAsset.fetchAssets(in: collection ?? PHAssetCollection.init(), options: options).count
|
||||
}
|
||||
|
||||
private func listMedia(albumId: String, mediumType: String, newest: Bool, skip: NSNumber?, take: NSNumber?) -> NSDictionary {
|
||||
private func listMedia(albumId: String, mediumType: String?, newest: Bool, skip: NSNumber?, take: NSNumber?) -> NSDictionary {
|
||||
let fetchOptions = PHFetchOptions()
|
||||
fetchOptions.predicate = predicateFromMediumType(mediumType: mediumType)
|
||||
fetchOptions.sortDescriptors = [
|
||||
NSSortDescriptor(key: "creationDate", ascending: newest ? false : true),
|
||||
NSSortDescriptor(key: "modificationDate", ascending: newest ? false : true)
|
||||
]
|
||||
fetchOptions.predicate = predicateFromMediumType(mediumType: mediumType)
|
||||
|
||||
let collection = self.assetCollections.first(where: { (collection) -> Bool in
|
||||
collection.localIdentifier == albumId
|
||||
@ -277,9 +273,7 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
||||
) {
|
||||
let manager = PHImageManager.default()
|
||||
let fetchOptions = PHFetchOptions()
|
||||
if (mediumType != nil) {
|
||||
fetchOptions.predicate = self.predicateFromMediumType(mediumType: mediumType!)
|
||||
}
|
||||
fetchOptions.predicate = self.predicateFromMediumType(mediumType: mediumType)
|
||||
fetchOptions.sortDescriptors = [
|
||||
NSSortDescriptor(key: "creationDate", ascending: false),
|
||||
NSSortDescriptor(key: "modificationDate", ascending: false)
|
||||
@ -509,16 +503,14 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
private func predicateFromMediumTypes(mediumTypes: [String]) -> NSPredicate {
|
||||
let predicates = mediumTypes.map { (dartValue) -> NSPredicate in
|
||||
return predicateFromMediumType(mediumType: dartValue)
|
||||
private func predicateFromMediumType(mediumType: String?) -> NSPredicate? {
|
||||
guard let type = mediumType else {
|
||||
return nil
|
||||
}
|
||||
return NSCompoundPredicate(type: NSCompoundPredicate.LogicalType.or, subpredicates: predicates)
|
||||
}
|
||||
|
||||
private func predicateFromMediumType(mediumType: String) -> NSPredicate {
|
||||
let swiftType = toSwiftMediumType(value: mediumType)
|
||||
return NSPredicate(format: "mediaType = %d", swiftType!.rawValue)
|
||||
guard let swiftType = toSwiftMediumType(value: type) else {
|
||||
return nil
|
||||
}
|
||||
return NSPredicate(format: "mediaType = %d", swiftType.rawValue)
|
||||
}
|
||||
|
||||
private func extractFileExtensionFromUTI(uti: String?) -> String {
|
||||
|
@ -22,7 +22,7 @@ class PhotoGallery {
|
||||
|
||||
/// List all available gallery albums and counts number of items of [MediumType].
|
||||
static Future<List<Album>> listAlbums({
|
||||
required MediumType mediumType,
|
||||
MediumType? mediumType,
|
||||
bool? hideIfEmpty = true,
|
||||
}) async {
|
||||
final json = await _channel.invokeMethod('listAlbums', {
|
||||
|
Loading…
x
Reference in New Issue
Block a user