make obtaining photo and video asynchronous
This commit is contained in:
parent
828b4f4256
commit
93e37ec8e6
3 changed files with 111 additions and 81 deletions
|
@ -3,12 +3,10 @@ package com.simplemobiletools.gallery.activities
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.WallpaperManager
|
import android.app.WallpaperManager
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.database.Cursor
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.MediaStore
|
|
||||||
import android.support.design.widget.Snackbar
|
import android.support.design.widget.Snackbar
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
|
@ -22,6 +20,7 @@ import com.simplemobiletools.filepicker.extensions.*
|
||||||
import com.simplemobiletools.gallery.Constants
|
import com.simplemobiletools.gallery.Constants
|
||||||
import com.simplemobiletools.gallery.R
|
import com.simplemobiletools.gallery.R
|
||||||
import com.simplemobiletools.gallery.adapters.MediaAdapter
|
import com.simplemobiletools.gallery.adapters.MediaAdapter
|
||||||
|
import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask
|
||||||
import com.simplemobiletools.gallery.dialogs.ChangeSortingDialog
|
import com.simplemobiletools.gallery.dialogs.ChangeSortingDialog
|
||||||
import com.simplemobiletools.gallery.extensions.getHumanizedFilename
|
import com.simplemobiletools.gallery.extensions.getHumanizedFilename
|
||||||
import com.simplemobiletools.gallery.models.Medium
|
import com.simplemobiletools.gallery.models.Medium
|
||||||
|
@ -29,7 +28,6 @@ import kotlinx.android.synthetic.main.activity_media.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.regex.Pattern
|
|
||||||
|
|
||||||
class MediaActivity : SimpleActivity(), View.OnTouchListener, MediaAdapter.MediaOperationsListener {
|
class MediaActivity : SimpleActivity(), View.OnTouchListener, MediaAdapter.MediaOperationsListener {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -45,6 +43,7 @@ class MediaActivity : SimpleActivity(), View.OnTouchListener, MediaAdapter.Media
|
||||||
private var mIsGetImageIntent = false
|
private var mIsGetImageIntent = false
|
||||||
private var mIsGetVideoIntent = false
|
private var mIsGetVideoIntent = false
|
||||||
private var mIsGetAnyIntent = false
|
private var mIsGetAnyIntent = false
|
||||||
|
private var mIsGettingMedia = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
@ -56,7 +55,7 @@ class MediaActivity : SimpleActivity(), View.OnTouchListener, MediaAdapter.Media
|
||||||
mIsGetAnyIntent = getBooleanExtra(Constants.GET_ANY_INTENT, false)
|
mIsGetAnyIntent = getBooleanExtra(Constants.GET_ANY_INTENT, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
media_holder.setOnRefreshListener({ refreshDir() })
|
media_holder.setOnRefreshListener({ getMedia() })
|
||||||
mPath = intent.getStringExtra(Constants.DIRECTORY)
|
mPath = intent.getStringExtra(Constants.DIRECTORY)
|
||||||
mToBeDeleted = ArrayList<String>()
|
mToBeDeleted = ArrayList<String>()
|
||||||
mMedia = ArrayList<Medium>()
|
mMedia = ArrayList<Medium>()
|
||||||
|
@ -74,19 +73,15 @@ class MediaActivity : SimpleActivity(), View.OnTouchListener, MediaAdapter.Media
|
||||||
|
|
||||||
private fun tryloadGallery() {
|
private fun tryloadGallery() {
|
||||||
if (hasStoragePermission()) {
|
if (hasStoragePermission()) {
|
||||||
initializeGallery()
|
val dirName = getHumanizedFilename(mPath)
|
||||||
|
title = dirName
|
||||||
|
getMedia()
|
||||||
} else {
|
} else {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeGallery() {
|
private fun initializeGallery() {
|
||||||
val newMedia = getMedia()
|
|
||||||
if (newMedia.toString() == mMedia.toString()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
mMedia = newMedia
|
|
||||||
if (isDirEmpty())
|
if (isDirEmpty())
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -97,9 +92,6 @@ class MediaActivity : SimpleActivity(), View.OnTouchListener, MediaAdapter.Media
|
||||||
media_grid.adapter = adapter
|
media_grid.adapter = adapter
|
||||||
media_grid.setOnTouchListener(this)
|
media_grid.setOnTouchListener(this)
|
||||||
mIsSnackbarShown = false
|
mIsSnackbarShown = false
|
||||||
|
|
||||||
val dirName = getHumanizedFilename(mPath)
|
|
||||||
title = dirName
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
|
@ -141,7 +133,7 @@ class MediaActivity : SimpleActivity(), View.OnTouchListener, MediaAdapter.Media
|
||||||
private fun showSortingDialog() {
|
private fun showSortingDialog() {
|
||||||
ChangeSortingDialog(this, false, object : ChangeSortingDialog.OnChangeSortingListener {
|
ChangeSortingDialog(this, false, object : ChangeSortingDialog.OnChangeSortingListener {
|
||||||
override fun sortingChanged() {
|
override fun sortingChanged() {
|
||||||
initializeGallery()
|
getMedia()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -167,55 +159,23 @@ class MediaActivity : SimpleActivity(), View.OnTouchListener, MediaAdapter.Media
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getMedia(): ArrayList<Medium> {
|
private fun getMedia() {
|
||||||
val media = ArrayList<Medium>()
|
if (mIsGettingMedia)
|
||||||
val invalidFiles = ArrayList<File>()
|
return
|
||||||
for (i in 0..1) {
|
|
||||||
if (mIsGetVideoIntent && i == 0)
|
|
||||||
continue
|
|
||||||
|
|
||||||
var uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
mIsGettingMedia = true
|
||||||
if (i == 1) {
|
GetMediaAsynctask(applicationContext, mPath, mIsGetVideoIntent, mIsGetImageIntent, mToBeDeleted, object : GetMediaAsynctask.GetMediaListener {
|
||||||
if (mIsGetImageIntent)
|
override fun gotMedia(media: ArrayList<Medium>) {
|
||||||
continue
|
mIsGettingMedia = false
|
||||||
|
media_holder.isRefreshing = false
|
||||||
uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
if (media.toString() == mMedia.toString()) {
|
||||||
}
|
return
|
||||||
val where = "${MediaStore.Images.Media.DATA} LIKE ? "
|
|
||||||
val args = arrayOf("$mPath%")
|
|
||||||
val columns = arrayOf(MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_MODIFIED)
|
|
||||||
val pattern = "${Pattern.quote(mPath)}/[^/]*"
|
|
||||||
var cursor: Cursor? = null
|
|
||||||
|
|
||||||
try {
|
|
||||||
cursor = contentResolver.query(uri, columns, where, args, null)
|
|
||||||
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
val pathIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA)
|
|
||||||
do {
|
|
||||||
val curPath = cursor.getString(pathIndex) ?: continue
|
|
||||||
|
|
||||||
if (curPath.matches(pattern.toRegex()) && !mToBeDeleted.contains(curPath.toLowerCase())) {
|
|
||||||
val file = File(curPath)
|
|
||||||
if (file.exists()) {
|
|
||||||
val dateIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATE_MODIFIED)
|
|
||||||
val timestamp = cursor.getLong(dateIndex)
|
|
||||||
media.add(Medium(file.name, curPath, i == 1, timestamp, file.length()))
|
|
||||||
} else {
|
|
||||||
invalidFiles.add(file)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (cursor.moveToNext())
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
cursor?.close()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Medium.sorting = mConfig.sorting
|
mMedia = media
|
||||||
media.sort()
|
initializeGallery()
|
||||||
scanFiles(invalidFiles) {}
|
}
|
||||||
return media
|
}).execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isDirEmpty(): Boolean {
|
private fun isDirEmpty(): Boolean {
|
||||||
|
@ -239,7 +199,7 @@ class MediaActivity : SimpleActivity(), View.OnTouchListener, MediaAdapter.Media
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun notifyDeletion(cnt: Int) {
|
private fun notifyDeletion(cnt: Int) {
|
||||||
mMedia = getMedia()
|
getMedia()
|
||||||
|
|
||||||
if (mMedia.isEmpty()) {
|
if (mMedia.isEmpty()) {
|
||||||
deleteFiles()
|
deleteFiles()
|
||||||
|
@ -299,14 +259,12 @@ class MediaActivity : SimpleActivity(), View.OnTouchListener, MediaAdapter.Media
|
||||||
mSnackbar!!.dismiss()
|
mSnackbar!!.dismiss()
|
||||||
mIsSnackbarShown = false
|
mIsSnackbarShown = false
|
||||||
mToBeDeleted.clear()
|
mToBeDeleted.clear()
|
||||||
mMedia = getMedia()
|
|
||||||
updateMediaView()
|
updateMediaView()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateMediaView() {
|
private fun updateMediaView() {
|
||||||
if (!isDirEmpty()) {
|
if (!isDirEmpty()) {
|
||||||
(media_grid.adapter as MediaAdapter).updateMedia(mMedia)
|
getMedia()
|
||||||
initializeGallery()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,15 +317,6 @@ class MediaActivity : SimpleActivity(), View.OnTouchListener, MediaAdapter.Media
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun refreshItems() {
|
override fun refreshItems() {
|
||||||
refreshDir()
|
getMedia()
|
||||||
}
|
|
||||||
|
|
||||||
private fun refreshDir() {
|
|
||||||
val dir = File(mPath)
|
|
||||||
if (dir.isDirectory) {
|
|
||||||
scanPath(mPath) {}
|
|
||||||
}
|
|
||||||
initializeGallery()
|
|
||||||
media_holder.isRefreshing = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import kotlinx.android.synthetic.main.photo_video_tmb.view.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>, val listener: MediaOperationsListener?, val itemClick: (Medium) -> Unit) :
|
class MediaAdapter(val activity: SimpleActivity, val media: MutableList<Medium>, val listener: MediaOperationsListener?, val itemClick: (Medium) -> Unit) :
|
||||||
RecyclerView.Adapter<MediaAdapter.ViewHolder>() {
|
RecyclerView.Adapter<MediaAdapter.ViewHolder>() {
|
||||||
val multiSelector = MultiSelector()
|
val multiSelector = MultiSelector()
|
||||||
val views = ArrayList<View>()
|
val views = ArrayList<View>()
|
||||||
|
@ -162,11 +162,6 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateMedia(media: MutableList<Medium>) {
|
|
||||||
this.media = media
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount() = media.size
|
override fun getItemCount() = media.size
|
||||||
|
|
||||||
class ViewHolder(view: View, val itemClick: (Medium) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
|
class ViewHolder(view: View, val itemClick: (Medium) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.simplemobiletools.gallery.asynctasks
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.database.Cursor
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import android.provider.MediaStore
|
||||||
|
import com.simplemobiletools.filepicker.extensions.scanFiles
|
||||||
|
import com.simplemobiletools.gallery.Config
|
||||||
|
import com.simplemobiletools.gallery.models.Medium
|
||||||
|
import java.io.File
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
import java.util.*
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
|
class GetMediaAsynctask(val context: Context, val mPath: String, val isPickVideo: Boolean, val isPickImage: Boolean,
|
||||||
|
val mToBeDeleted: List<String>, val listener: GetMediaListener) : AsyncTask<Void, Void, ArrayList<Medium>>() {
|
||||||
|
lateinit var mConfig: Config
|
||||||
|
lateinit var mListener: WeakReference<GetMediaListener>
|
||||||
|
|
||||||
|
override fun onPreExecute() {
|
||||||
|
super.onPreExecute()
|
||||||
|
mConfig = Config.newInstance(context)
|
||||||
|
mListener = WeakReference(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doInBackground(vararg params: Void): ArrayList<Medium> {
|
||||||
|
val media = ArrayList<Medium>()
|
||||||
|
val invalidFiles = ArrayList<File>()
|
||||||
|
for (i in 0..1) {
|
||||||
|
if (isPickVideo && i == 0)
|
||||||
|
continue
|
||||||
|
|
||||||
|
var uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||||
|
if (i == 1) {
|
||||||
|
if (isPickImage)
|
||||||
|
continue
|
||||||
|
|
||||||
|
uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
||||||
|
}
|
||||||
|
val where = "${MediaStore.Images.Media.DATA} LIKE ?"
|
||||||
|
val args = arrayOf("$mPath%")
|
||||||
|
val columns = arrayOf(MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_MODIFIED)
|
||||||
|
val pattern = "${Pattern.quote(mPath)}/[^/]*"
|
||||||
|
var cursor: Cursor? = null
|
||||||
|
|
||||||
|
try {
|
||||||
|
cursor = context.contentResolver.query(uri, columns, where, args, null)
|
||||||
|
|
||||||
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
val pathIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA)
|
||||||
|
do {
|
||||||
|
val curPath = cursor.getString(pathIndex) ?: continue
|
||||||
|
|
||||||
|
if (curPath.matches(pattern.toRegex()) && !mToBeDeleted.contains(curPath.toLowerCase())) {
|
||||||
|
val file = File(curPath)
|
||||||
|
if (file.exists()) {
|
||||||
|
val dateIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATE_MODIFIED)
|
||||||
|
val timestamp = cursor.getLong(dateIndex)
|
||||||
|
media.add(Medium(file.name, curPath, i == 1, timestamp, file.length()))
|
||||||
|
} else {
|
||||||
|
invalidFiles.add(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (cursor.moveToNext())
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
cursor?.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Medium.sorting = mConfig.sorting
|
||||||
|
media.sort()
|
||||||
|
context.scanFiles(invalidFiles) {}
|
||||||
|
return media
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPostExecute(media: ArrayList<Medium>) {
|
||||||
|
super.onPostExecute(media)
|
||||||
|
val listener = mListener.get()
|
||||||
|
listener?.gotMedia(media)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GetMediaListener {
|
||||||
|
fun gotMedia(media: ArrayList<Medium>)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue