optimize code

This commit is contained in:
Wenqi Li 2023-05-14 02:23:53 +08:00
parent eafedcb225
commit 4a2b9dcf1c
3 changed files with 180 additions and 106 deletions

View File

@ -10,7 +10,6 @@ import android.graphics.ImageDecoder
import android.os.Build
import android.provider.MediaStore
import android.util.Size
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
@ -81,18 +80,18 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
private val executor: ExecutorService = Executors.newSingleThreadExecutor()
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "photo_gallery")
val plugin = PhotoGalleryPlugin()
plugin.context = flutterPluginBinding.applicationContext
channel.setMethodCallHandler(plugin)
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
override fun onMethodCall(call: MethodCall, result: Result) {
when (call.method) {
"listAlbums" -> {
val mediumType = call.argument<String>("mediumType")
@ -102,6 +101,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
)
}
}
"listMedia" -> {
val albumId = call.argument<String>("albumId")
val mediumType = call.argument<String>("mediumType")
@ -114,6 +114,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
)
}
}
"getMedium" -> {
val mediumId = call.argument<String>("mediumId")
val mediumType = call.argument<String>("mediumType")
@ -123,6 +124,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
)
}
}
"getThumbnail" -> {
val mediumId = call.argument<String>("mediumId")
val mediumType = call.argument<String>("mediumType")
@ -135,6 +137,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
)
}
}
"getAlbumThumbnail" -> {
val albumId = call.argument<String>("albumId")
val mediumType = call.argument<String>("mediumType")
@ -148,6 +151,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
)
}
}
"getFile" -> {
val mediumId = call.argument<String>("mediumId")
val mediumType = call.argument<String>("mediumType")
@ -158,6 +162,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
)
}
}
"cleanCache" -> {
executor.submit {
result.success(
@ -165,6 +170,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
)
}
}
else -> result.notImplemented()
}
}
@ -174,9 +180,11 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
imageType -> {
listImageAlbums().values.toList()
}
videoType -> {
listVideoAlbums().values.toList()
}
else -> {
listAllAlbums().values.toList()
}
@ -224,14 +232,11 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
}
val albumLinkedMap = linkedMapOf<String, Map<String, Any>>()
albumLinkedMap.put(
allAlbumId,
hashMapOf(
albumLinkedMap[allAlbumId] = hashMapOf(
"id" to allAlbumId,
"name" to allAlbumName,
"count" to total
)
)
albumLinkedMap.putAll(albumHashMap)
return albumLinkedMap
}
@ -278,14 +283,11 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
}
val albumLinkedMap = linkedMapOf<String, Map<String, Any>>()
albumLinkedMap.put(
allAlbumId,
hashMapOf(
albumLinkedMap[allAlbumId] = hashMapOf(
"id" to allAlbumId,
"name" to allAlbumName,
"count" to total
)
)
albumLinkedMap.putAll(albumHashMap)
return albumLinkedMap
}
@ -304,18 +306,28 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
return albumMap
}
private fun listMedia(mediumType: String?, albumId: String, newest: Boolean, skip: Int?, take: Int?): Map<String, Any?> {
private fun listMedia(
mediumType: String?,
albumId: String,
newest: Boolean,
skip: Int?,
take: Int?
): Map<String, Any?> {
return when (mediumType) {
imageType -> {
listImages(albumId, newest, skip, take)
}
videoType -> {
listVideos(albumId, newest, skip, take)
}
else -> {
val images = listImages(albumId, newest, null, null)["items"] as List<Map<String, Any?>>
val videos = listVideos(albumId, newest, null, null)["items"] as List<Map<String, Any?>>
var items = (images + videos).sortedWith(compareBy<Map<String, Any?>> { it["creationDate"] as Long }.thenBy { it["modifiedDate"] as Long })
val comparator = compareBy<Map<String, Any?>> { it["creationDate"] as Long }
.thenBy { it["modifiedDate"] as Long }
var items = (images + videos).sortedWith(comparator)
if (newest) {
items = items.reversed()
}
@ -452,9 +464,11 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
imageType -> {
getImageMedia(mediumId)
}
videoType -> {
getVideoMedia(mediumId)
}
else -> {
getImageMedia(mediumId) ?: getVideoMedia(mediumId)
}
@ -505,14 +519,22 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
return videoMetadata
}
private fun getThumbnail(mediumId: String, mediumType: String?, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
private fun getThumbnail(
mediumId: String,
mediumType: String?,
width: Int?,
height: Int?,
highQuality: Boolean?
): ByteArray? {
return when (mediumType) {
imageType -> {
getImageThumbnail(mediumId, width, height, highQuality)
}
videoType -> {
getVideoThumbnail(mediumId, width, height, highQuality)
}
else -> {
getImageThumbnail(mediumId, width, height, highQuality)
?: getVideoThumbnail(mediumId, width, height, highQuality)
@ -537,7 +559,9 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
null
}
} else {
val kind = if (highQuality == true) MediaStore.Images.Thumbnails.MINI_KIND else MediaStore.Images.Thumbnails.MICRO_KIND
val kind =
if (highQuality == true) MediaStore.Images.Thumbnails.MINI_KIND
else MediaStore.Images.Thumbnails.MICRO_KIND
MediaStore.Images.Thumbnails.getThumbnail(
this.contentResolver, mediumId.toLong(),
kind, null
@ -572,7 +596,8 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
}
} else {
val kind =
if (highQuality == true) MediaStore.Video.Thumbnails.MINI_KIND else MediaStore.Video.Thumbnails.MICRO_KIND
if (highQuality == true) MediaStore.Video.Thumbnails.MINI_KIND
else MediaStore.Video.Thumbnails.MICRO_KIND
MediaStore.Video.Thumbnails.getThumbnail(
this.contentResolver, mediumId.toLong(),
kind, null
@ -589,21 +614,36 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
return byteArray
}
private fun getAlbumThumbnail(albumId: String, mediumType: String?, newest: Boolean, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
private fun getAlbumThumbnail(
albumId: String,
mediumType: String?,
newest: Boolean,
width: Int?,
height: Int?,
highQuality: Boolean?
): ByteArray? {
return when (mediumType) {
imageType -> {
getImageAlbumThumbnail(albumId, newest, width, height, highQuality)
}
videoType -> {
getVideoAlbumThumbnail(albumId, newest, width, height, highQuality)
}
else -> {
getAllAlbumThumbnail(albumId, newest, width, height, highQuality)
}
}
}
private fun getImageAlbumThumbnail(albumId: String, newest: Boolean, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
private fun getImageAlbumThumbnail(
albumId: String,
newest: Boolean,
width: Int?,
height: Int?,
highQuality: Boolean?
): ByteArray? {
return this.context.run {
val projection = arrayOf(MediaStore.Images.Media._ID)
@ -621,7 +661,13 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
}
}
private fun getVideoAlbumThumbnail(albumId: String, newest: Boolean, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
private fun getVideoAlbumThumbnail(
albumId: String,
newest: Boolean,
width: Int?,
height: Int?,
highQuality: Boolean?
): ByteArray? {
return this.context.run {
val projection = arrayOf(MediaStore.Video.Media._ID)
@ -639,7 +685,13 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
}
}
private fun getAllAlbumThumbnail(albumId: String, newest: Boolean, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
private fun getAllAlbumThumbnail(
albumId: String,
newest: Boolean,
width: Int?,
height: Int?,
highQuality: Boolean?
): ByteArray? {
return this.context.run {
val imageProjection = arrayOf(
MediaStore.Images.Media._ID,
@ -688,20 +740,16 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
}
if (imageId != null && videoId != null) {
if (imageDateAdded != null && videoDateAdded != null) {
if (newest && imageDateAdded!! > videoDateAdded!! || !newest && imageDateAdded!! < videoDateAdded!!) {
return@run getImageThumbnail(imageId.toString(), width, height, highQuality)
}
if (newest && imageDateAdded!! < videoDateAdded!! || !newest && imageDateAdded!! > videoDateAdded!!) {
return@run getVideoThumbnail(videoId.toString(), width, height, highQuality)
} else {
}
if (newest && imageDateModified!! >= videoDateModified!! || !newest && imageDateModified!! <= videoDateModified!!) {
return@run getImageThumbnail(imageId.toString(), width, height, highQuality)
}
}
if (imageDateModified != null && videoDateModified != null) {
if (newest && imageDateModified!! < videoDateModified!! || !newest && imageDateModified!! > videoDateModified!!) {
return@run getVideoThumbnail(videoId.toString(), width, height, highQuality)
} else {
return@run getImageThumbnail(imageId.toString(), width, height, highQuality)
}
}
}
if (imageId != null) {
@ -805,9 +853,11 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
imageType -> {
getImageFile(mediumId, mimeType = mimeType)
}
videoType -> {
getVideoFile(mediumId)
}
else -> {
getImageFile(mediumId, mimeType = mimeType) ?: getVideoFile(mediumId)
}
@ -874,10 +924,12 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
val bitmap: Bitmap? = this.context.run {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
try {
ImageDecoder.decodeBitmap(ImageDecoder.createSource(
ImageDecoder.decodeBitmap(
ImageDecoder.createSource(
this.contentResolver,
ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mediumId.toLong())
))
)
)
} catch (e: Exception) {
null
}
@ -891,25 +943,40 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
bitmap?.let {
val compressFormat: Bitmap.CompressFormat
if (mimeType == "image/jpeg") {
when (mimeType) {
"image/jpeg" -> {
val path = File(getCachePath(), "$mediumId.jpeg")
val out = FileOutputStream(path)
compressFormat = Bitmap.CompressFormat.JPEG
it.compress(compressFormat, 100, out)
return path.absolutePath
} else if (mimeType == "image/png") {
}
"image/png" -> {
val path = File(getCachePath(), "$mediumId.png")
val out = FileOutputStream(path)
compressFormat = Bitmap.CompressFormat.PNG
it.compress(compressFormat, 100, out)
return path.absolutePath
} else if (mimeType == "image/webp") {
}
"image/webp" -> {
val path = File(getCachePath(), "$mediumId.webp")
val out = FileOutputStream(path)
compressFormat = Bitmap.CompressFormat.WEBP_LOSSLESS
compressFormat = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
Bitmap.CompressFormat.WEBP_LOSSLESS
}
else {
Bitmap.CompressFormat.WEBP
}
it.compress(compressFormat, 100, out)
return path.absolutePath
}
else -> {
return null
}
}
}
return null
@ -1013,7 +1080,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
}
}
private fun getCachePath(): File? {
private fun getCachePath(): File {
return this.context.run {
val cachePath = File(this.cacheDir, "photo_gallery")
if (!cachePath.exists()) {
@ -1025,6 +1092,6 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
private fun cleanCache() {
val cachePath = getCachePath()
cachePath?.deleteRecursively()
cachePath.deleteRecursively()
}
}

View File

@ -83,8 +83,8 @@ class _MyAppState extends State<MyApp> {
...?_albums?.map(
(album) => GestureDetector(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => AlbumPage(album))),
MaterialPageRoute(builder: (context) => AlbumPage(album)),
),
child: Column(
children: <Widget>[
ClipRRect(
@ -95,8 +95,7 @@ class _MyAppState extends State<MyApp> {
width: gridWidth,
child: FadeInImage(
fit: BoxFit.cover,
placeholder:
MemoryImage(kTransparentImage),
placeholder: MemoryImage(kTransparentImage),
image: AlbumThumbnailProvider(
album: album,
highQuality: true,
@ -186,8 +185,9 @@ class AlbumPageState extends State<AlbumPage> {
children: <Widget>[
...?_media?.map(
(medium) => GestureDetector(
onTap: () => Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ViewerPage(medium))),
onTap: () => Navigator.of(context).push(
MaterialPageRoute(builder: (context) => ViewerPage(medium)),
),
child: Container(
color: Colors.grey[300],
child: FadeInImage(
@ -293,9 +293,7 @@ class _VideoProviderState extends State<VideoProvider> {
TextButton(
onPressed: () {
setState(() {
_controller!.value.isPlaying
? _controller!.pause()
: _controller!.play();
_controller!.value.isPlaying ? _controller!.pause() : _controller!.play();
});
},
child: Icon(

View File

@ -34,7 +34,8 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
mediumId: mediumId,
completion: { (data: [String: Any?]?, error: Error?) -> Void in
result(data)
})
}
)
}
else if(call.method == "getThumbnail") {
let arguments = call.arguments as! Dictionary<String, AnyObject>
@ -49,7 +50,8 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
highQuality: highQuality,
completion: { (data: Data?, error: Error?) -> Void in
result(data)
})
}
)
}
else if(call.method == "getAlbumThumbnail") {
let arguments = call.arguments as! Dictionary<String, AnyObject>
@ -68,7 +70,8 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
highQuality: highQuality,
completion: { (data: Data?, error: Error?) -> Void in
result(data)
})
}
)
}
else if(call.method == "getFile") {
let arguments = call.arguments as! Dictionary<String, AnyObject>
@ -79,7 +82,8 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
mimeType: mimeType,
completion: { (filepath: String?, error: Error?) -> Void in
result(filepath?.replacingOccurrences(of: "file://", with: ""))
})
}
)
}
else if(call.method == "cleanCache") {
cleanCache()
@ -254,7 +258,8 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
}
let bytes = image.jpegData(compressionQuality: CGFloat(70))
completion(bytes, nil)
})
}
)
return
}
@ -312,7 +317,8 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
}
let bytes = image.jpegData(compressionQuality: CGFloat(80))
completion(bytes, nil)
})
}
)
return
}
@ -372,7 +378,10 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
options.deliveryMode = .highQualityFormat
options.isNetworkAccessAllowed = true
manager.requestAVAsset(forVideo: asset, options: options, resultHandler: { (avAsset, avAudioMix, info) in
manager.requestAVAsset(
forVideo: asset,
options: options,
resultHandler: { (avAsset, avAudioMix, info) in
DispatchQueue.main.async(execute: {
do {
let avAsset = avAsset as? AVURLAsset