Merge pull request #3 from SimpleMobileTools/master

merge
This commit is contained in:
fiepi 2017-06-07 05:14:52 -05:00 committed by GitHub
commit eee507efdd
42 changed files with 386 additions and 55 deletions

View file

@ -1,6 +1,25 @@
Changelog
==========
Version 2.10.10 *(2017-06-07)*
----------------------------
* Some crashfixes
Version 2.10.9 *(2017-06-06)*
----------------------------
* Allow setting custom folder covers
* Properly handle manually included folders
* Improve the performance at opening fullscreen media
Version 2.10.8 *(2017-06-02)*
----------------------------
* Always properly show hidden files from third party intents
* Properly handle Crop intent used for example at selecting contact photos
* Couple smaller fixes and crashfixes
Version 2.10.7 *(2017-05-29)*
----------------------------

View file

@ -10,8 +10,8 @@ android {
applicationId "com.simplemobiletools.gallery"
minSdkVersion 16
targetSdkVersion 23
versionCode 106
versionName "2.10.7"
versionCode 109
versionName "2.10.10"
}
signingConfigs {
@ -32,7 +32,7 @@ android {
}
dependencies {
compile 'com.simplemobiletools:commons:2.19.0'
compile 'com.simplemobiletools:commons:2.20.1'
compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0'
compile 'com.theartofdev.edmodo:android-image-cropper:2.4.0'
compile 'com.bignerdranch.android:recyclerview-multiselect:0.2'

View file

@ -1,2 +1,5 @@
-keep class com.simplemobiletools.** { *; }
-dontwarn com.simplemobiletools.**
-renamesourcefileattribute SourceFile
-keepattributes SourceFile, LineNumberTable

View file

@ -145,6 +145,18 @@
<data android:mimeType="image/*"/>
</intent-filter>
<intent-filter>
<action android:name="com.android.camera.action.CROP"/>
<data android:scheme="content"/>
<data android:scheme="file"/>
<data android:mimeType="image/*"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.ALTERNATIVE"/>
<category android:name="android.intent.category.SELECTED_ALTERNATIVE"/>
</intent-filter>
</activity>
<activity

View file

@ -2,9 +2,11 @@ package com.simplemobiletools.gallery.activities
import android.app.Activity
import android.graphics.Bitmap
import android.graphics.Bitmap.CompressFormat
import android.graphics.Point
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.Menu
import android.view.MenuItem
@ -18,8 +20,8 @@ import com.simplemobiletools.gallery.dialogs.SaveAsDialog
import com.simplemobiletools.gallery.extensions.getRealPathFromURI
import com.theartofdev.edmodo.cropper.CropImageView
import kotlinx.android.synthetic.main.view_crop_image.*
import java.io.File
import java.io.OutputStream
import java.io.*
class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener {
val TAG = EditActivity::class.java.simpleName
@ -113,7 +115,23 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
override fun onCropImageComplete(view: CropImageView, result: CropImageView.CropResult) {
if (result.error == null) {
if (uri.scheme == "file") {
if (isCropIntent && intent.extras?.containsKey(MediaStore.EXTRA_OUTPUT) == true) {
val targetUri = intent.extras!!.get(MediaStore.EXTRA_OUTPUT) as Uri
var inputStream: InputStream? = null
var outputStream: OutputStream? = null
try {
val stream = ByteArrayOutputStream()
result.bitmap.compress(CompressFormat.JPEG, 100, stream)
inputStream = ByteArrayInputStream(stream.toByteArray())
outputStream = contentResolver.openOutputStream(targetUri)
inputStream.copyTo(outputStream)
} finally {
inputStream?.close()
outputStream?.close()
}
setResult(RESULT_OK)
finish()
} else if (uri.scheme == "file") {
SaveAsDialog(this, uri.path) {
saveBitmapToFile(result.bitmap, it)
}

View file

@ -28,6 +28,9 @@ import com.simplemobiletools.gallery.models.Directory
import com.simplemobiletools.gallery.views.MyScalableRecyclerView
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.io.OutputStream
import java.util.*
class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
@ -291,9 +294,23 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
val path = resultData.data.path
val uri = Uri.fromFile(File(path))
if (mIsGetImageContentIntent || mIsGetVideoContentIntent || mIsGetAnyContentIntent) {
if (intent.extras?.containsKey(MediaStore.EXTRA_OUTPUT) == true) {
var inputStream: InputStream? = null
var outputStream: OutputStream? = null
try {
val output = intent.extras.get(MediaStore.EXTRA_OUTPUT) as Uri
inputStream = FileInputStream(File(path))
outputStream = contentResolver.openOutputStream(output)
inputStream.copyTo(outputStream)
} finally {
inputStream?.close()
outputStream?.close()
}
} else {
val type = File(path).getMimeType("image/jpeg")
setDataAndTypeAndNormalize(uri, type)
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
}
} else if (mIsPickImageIntent || mIsPickVideoIntent) {
data = uri
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
@ -417,6 +434,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
add(Release(94, R.string.release_94))
add(Release(97, R.string.release_97))
add(Release(98, R.string.release_98))
add(Release(108, R.string.release_108))
checkWhatsNew(this, BuildConfig.VERSION_CODE)
}
}

View file

@ -46,6 +46,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
private var mLoadedInitialPhotos = false
private var mStoredAnimateGifs = true
private var mStoredCropThumbnails = true
private var mLastDrawnHashCode = 0
private var mLastMediaModified = 0
private var mLastMediaHandler = Handler()
@ -393,9 +394,13 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
media_refresh_layout.isRefreshing = false
checkLastMediaChanged()
if (media.hashCode() == mMedia.hashCode())
if (mLastDrawnHashCode == 0)
mLastDrawnHashCode = media.hashCode()
if (media.hashCode() == mMedia.hashCode() && media.hashCode() == mLastDrawnHashCode)
return
mLastDrawnHashCode = media.hashCode()
mMedia = media
setupAdapter()
storeFolder()
@ -422,6 +427,9 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
override fun refreshItems() {
getMedia()
Handler().postDelayed({
getMedia()
}, 1000)
}
override fun itemLongClicked(position: Int) {

View file

@ -21,6 +21,7 @@ import com.simplemobiletools.gallery.extensions.*
import com.simplemobiletools.gallery.fragments.PhotoFragment
import com.simplemobiletools.gallery.fragments.VideoFragment
import com.simplemobiletools.gallery.fragments.ViewPagerFragment
import com.simplemobiletools.gallery.helpers.IS_VIEW_INTENT
import com.simplemobiletools.gallery.helpers.MEDIUM
import com.simplemobiletools.gallery.models.Medium
import kotlinx.android.synthetic.main.fragment_holder.*
@ -119,6 +120,7 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
private fun sendViewPagerIntent(path: String) {
Intent(this, ViewPagerActivity::class.java).apply {
putExtra(IS_VIEW_INTENT, true)
putExtra(MEDIUM, path)
startActivity(this)
}

View file

@ -94,8 +94,13 @@ class SetWallpaperActivity : SimpleActivity(), CropImageView.OnCropImageComplete
val wantedHeight = wallpaperManager.desiredMinimumHeight
val ratio = wantedHeight / bitmap.height.toFloat()
val wantedWidth = (bitmap.width * ratio).toInt()
try {
wallpaperManager.setBitmap(Bitmap.createScaledBitmap(bitmap, wantedWidth, wantedHeight, true))
setResult(Activity.RESULT_OK)
} catch (e: OutOfMemoryError) {
toast(R.string.out_of_memory_error)
setResult(Activity.RESULT_CANCELED)
}
finish()
}).start()
} else {

View file

@ -3,7 +3,7 @@ package com.simplemobiletools.gallery.activities
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.dialogs.PickAlbumDialog
import com.simplemobiletools.gallery.dialogs.PickDirectoryDialog
import java.io.File
import java.util.*
@ -15,7 +15,7 @@ open class SimpleActivity : BaseSimpleActivity() {
}
val source = if (files[0].isFile) files[0].parent else files[0].absolutePath
PickAlbumDialog(this, source) {
PickDirectoryDialog(this, source) {
copyMoveFilesTo(files, source.trimEnd('/'), it, isCopyOperation, true, callback)
}
}

View file

@ -27,6 +27,7 @@ import com.simplemobiletools.commons.dialogs.PropertiesDialog
import com.simplemobiletools.commons.dialogs.RenameItemDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.MediaActivity.Companion.mMedia
import com.simplemobiletools.gallery.adapters.MyPagerAdapter
import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask
import com.simplemobiletools.gallery.dialogs.SaveAsDialog
@ -42,7 +43,6 @@ import java.util.*
class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, ViewPagerFragment.FragmentListener {
lateinit var mOrientationEventListener: OrientationEventListener
private var mMedia = ArrayList<Medium>()
private var mPath = ""
private var mDirectory = ""
@ -51,6 +51,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private var mShowAll = false
private var mRotationDegrees = 0f
private var mLastHandledOrientation = 0
private var mPrevHashcode = 0
companion object {
var screenWidth = 0
@ -73,10 +74,8 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
try {
val proj = arrayOf(MediaStore.Images.Media.DATA)
cursor = contentResolver.query(uri, proj, null, null, null)
if (cursor != null) {
val dataIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor.moveToFirst()
mPath = cursor.getString(dataIndex)
if (cursor?.moveToFirst() == true) {
mPath = cursor.getStringValue(MediaStore.Images.Media.DATA)
}
} finally {
cursor?.close()
@ -92,14 +91,18 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
return
}
mMedia = ArrayList<Medium>()
if (intent.extras?.containsKey(IS_VIEW_INTENT) == true) {
config.temporarilyShowHidden = true
}
showSystemUI()
mDirectory = File(mPath).parent
title = mPath.getFilenameFromPath()
if (MediaActivity.mMedia.isNotEmpty())
gotMedia(MediaActivity.mMedia)
if (mMedia.isNotEmpty()) {
gotMedia(mMedia)
}
reloadViewPager()
scanPath(mPath) {}
@ -109,6 +112,13 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
view_pager.background = ColorDrawable(Color.BLACK)
}
override fun onDestroy() {
super.onDestroy()
if (intent.extras?.containsKey(IS_VIEW_INTENT) == true) {
config.temporarilyShowHidden = false
}
}
private fun setupOrientationEventListener() {
mOrientationEventListener = object : OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
override fun onOrientationChanged(orientation: Int) {
@ -424,10 +434,11 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
private fun gotMedia(media: ArrayList<Medium>) {
if (isDirEmpty(media) || mMedia.hashCode() == media.hashCode()) {
if (isDirEmpty(media) || media.hashCode() == mPrevHashcode) {
return
}
mPrevHashcode = media.hashCode()
mMedia = media
if (mPos == -1) {
mPos = getProperPosition()
@ -493,12 +504,14 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private fun updateActionbarTitle() {
runOnUiThread {
if (mPos < mMedia.size) {
title = mMedia[mPos].path.getFilenameFromPath()
}
}
}
private fun getCurrentMedium(): Medium? {
return if (mMedia.isEmpty())
return if (mMedia.isEmpty() || mPos == -1)
null
else
mMedia[Math.min(mPos, mMedia.size - 1)]

View file

@ -10,6 +10,7 @@ import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
import com.bignerdranch.android.multiselector.MultiSelector
import com.bignerdranch.android.multiselector.SwappingHolder
import com.bumptech.glide.Glide
import com.google.gson.Gson
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.PropertiesDialog
import com.simplemobiletools.commons.dialogs.RenameItemDialog
@ -20,7 +21,9 @@ import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.dialogs.ExcludeFolderDialog
import com.simplemobiletools.gallery.dialogs.PickMediumDialog
import com.simplemobiletools.gallery.extensions.*
import com.simplemobiletools.gallery.models.AlbumCover
import com.simplemobiletools.gallery.models.Directory
import kotlinx.android.synthetic.main.directory_item.view.*
import kotlinx.android.synthetic.main.directory_tmb.view.*
@ -111,6 +114,8 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList<Direc
R.id.cab_move_to -> copyMoveTo(false)
R.id.cab_select_all -> selectAll()
R.id.cab_delete -> askConfirmDelete()
R.id.cab_select_photo -> changeAlbumCover(false)
R.id.cab_use_default -> changeAlbumCover(true)
else -> return false
}
return true
@ -125,6 +130,7 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList<Direc
override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
menu.findItem(R.id.cab_rename).isVisible = selectedPositions.size <= 1
menu.findItem(R.id.cab_change_cover_image).isVisible = selectedPositions.size <= 1
checkHideBtnVisibility(menu)
checkPinBtnVisibility(menu)
@ -250,10 +256,10 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList<Direc
}
private fun copyMoveTo(isCopyOperation: Boolean) {
val files = ArrayList<File>()
if (selectedPositions.isEmpty())
return
val files = ArrayList<File>()
selectedPositions.forEach {
val dir = File(dirs[it].path)
files.addAll(dir.listFiles().filter { it.isFile && it.isImageVideoGif() })
@ -320,6 +326,31 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList<Direc
}
}
private fun changeAlbumCover(useDefault: Boolean) {
if (selectedPositions.size != 1)
return
val path = dirs[selectedPositions.first()].path
var albumCovers = config.parseAlbumCovers()
if (useDefault) {
albumCovers = albumCovers.filterNot { it.path == path } as ArrayList
storeCovers(albumCovers)
} else {
PickMediumDialog(activity, path) {
albumCovers = albumCovers.filterNot { it.path == path } as ArrayList
albumCovers.add(AlbumCover(path, it))
storeCovers(albumCovers)
}
}
}
private fun storeCovers(albumCovers: ArrayList<AlbumCover>) {
activity.config.albumCovers = Gson().toJson(albumCovers)
actMode?.finish()
listener?.refreshItems()
}
private fun getSelectedPaths(): HashSet<String> {
val paths = HashSet<String>(selectedPositions.size)
selectedPositions.forEach { paths.add(dirs[it].path) }

View file

@ -35,6 +35,7 @@ class GetDirectoriesAsynctask(val context: Context, val isPickVideo: Boolean, va
}
private fun groupDirectories(media: ArrayList<Medium>): Map<String, Directory> {
val albumCovers = config.parseAlbumCovers()
val hidden = context.resources.getString(R.string.hidden)
val directories = LinkedHashMap<String, Directory>()
for ((name, path, isVideo, dateModified, dateTaken, size) in media) {
@ -62,7 +63,14 @@ class GetDirectoriesAsynctask(val context: Context, val isPickVideo: Boolean, va
continue
}
val directory = Directory(parentDir, path, dirName, 1, dateModified, dateTaken, size)
var thumbnail = path
albumCovers.forEach {
if (it.path == parentDir && File(it.tmb).exists()) {
thumbnail = it.tmb
}
}
val directory = Directory(parentDir, thumbnail, dirName, 1, dateModified, dateTaken, size)
directories.put(parentDir, directory)
}
}

View file

@ -13,15 +13,15 @@ import com.simplemobiletools.gallery.asynctasks.GetDirectoriesAsynctask
import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.extensions.getCachedDirectories
import com.simplemobiletools.gallery.models.Directory
import kotlinx.android.synthetic.main.dialog_album_picker.view.*
import kotlinx.android.synthetic.main.dialog_directory_picker.view.*
class PickAlbumDialog(val activity: SimpleActivity, val sourcePath: String, val callback: (path: String) -> Unit) {
class PickDirectoryDialog(val activity: SimpleActivity, val sourcePath: String, val callback: (path: String) -> Unit) {
var dialog: AlertDialog
var directoriesGrid: RecyclerView
var shownDirectories: ArrayList<Directory> = ArrayList()
init {
val view = LayoutInflater.from(activity).inflate(R.layout.dialog_album_picker, null)
val view = LayoutInflater.from(activity).inflate(R.layout.dialog_directory_picker, null)
directoriesGrid = view.directories_grid
dialog = AlertDialog.Builder(activity)

View file

@ -0,0 +1,56 @@
package com.simplemobiletools.gallery.dialogs
import android.support.v7.app.AlertDialog
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.adapters.MediaAdapter
import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask
import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.models.Medium
import kotlinx.android.synthetic.main.dialog_medium_picker.view.*
class PickMediumDialog(val activity: SimpleActivity, val path: String, val callback: (path: String) -> Unit) {
var dialog: AlertDialog
var mediaGrid: RecyclerView
var shownMedia: ArrayList<Medium> = ArrayList()
init {
val view = LayoutInflater.from(activity).inflate(R.layout.dialog_medium_picker, null)
mediaGrid = view.media_grid
dialog = AlertDialog.Builder(activity)
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.cancel, null)
.create().apply {
activity.setupDialogStuff(view, this, R.string.select_photo)
val token = object : TypeToken<List<Medium>>() {}.type
val media = Gson().fromJson<ArrayList<Medium>>(activity.config.loadFolderMedia(path), token) ?: ArrayList<Medium>(1)
if (media.isNotEmpty()) {
gotMedia(media)
}
GetMediaAsynctask(activity, path, false, true, false) {
gotMedia(it)
}.execute()
}
}
private fun gotMedia(media: ArrayList<Medium>) {
if (media.hashCode() == shownMedia.hashCode())
return
shownMedia = media
val adapter = MediaAdapter(activity, media, null) {
callback(it.path)
dialog.dismiss()
}
mediaGrid.adapter = adapter
}
}

View file

@ -57,8 +57,12 @@ fun Context.getFilesFrom(curPath: String, isPickImage: Boolean, isPickVideo: Boo
val selection = if (curPath.isEmpty()) null else "(${MediaStore.Images.Media.DATA} LIKE ? AND ${MediaStore.Images.Media.DATA} NOT LIKE ?)"
val selectionArgs = if (curPath.isEmpty()) null else arrayOf("$curPath/%", "$curPath/%/%")
try {
val cur = contentResolver.query(uri, projection, selection, selectionArgs, getSortingForFolder(curPath))
return parseCursor(this, cur, isPickImage, isPickVideo, curPath)
} catch (e: Exception) {
return ArrayList()
}
}
private fun parseCursor(context: Context, cur: Cursor, isPickImage: Boolean, isPickVideo: Boolean, curPath: String): ArrayList<Medium> {
@ -66,23 +70,15 @@ private fun parseCursor(context: Context, cur: Cursor, isPickImage: Boolean, isP
val config = context.config
val showMedia = config.showMedia
val showHidden = config.shouldShowHidden
cur.use { cur ->
if (cur.moveToFirst()) {
var filename: String
var path: String
var dateTaken: Long
var dateModified: Long
var size: Long
var isImage: Boolean
var isVideo: Boolean
val excludedFolders = config.excludedFolders
val noMediaFolders = context.getNoMediaFolders()
cur.use { cur ->
if (cur.moveToFirst()) {
do {
try {
path = cur.getStringValue(MediaStore.Images.Media.DATA)
size = cur.getLongValue(MediaStore.Images.Media.SIZE)
val path = cur.getStringValue(MediaStore.Images.Media.DATA)
var size = cur.getLongValue(MediaStore.Images.Media.SIZE)
if (size == 0L) {
size = File(path).length()
}
@ -91,12 +87,12 @@ private fun parseCursor(context: Context, cur: Cursor, isPickImage: Boolean, isP
continue
}
filename = cur.getStringValue(MediaStore.Images.Media.DISPLAY_NAME) ?: ""
var filename = cur.getStringValue(MediaStore.Images.Media.DISPLAY_NAME) ?: ""
if (filename.isEmpty())
filename = path.getFilenameFromPath()
isImage = filename.isImageFast() || filename.isGif()
isVideo = if (isImage) false else filename.isVideoFast()
val isImage = filename.isImageFast() || filename.isGif()
val isVideo = if (isImage) false else filename.isVideoFast()
if (!isImage && !isVideo)
continue
@ -130,8 +126,8 @@ private fun parseCursor(context: Context, cur: Cursor, isPickImage: Boolean, isP
}
if (!isExcluded) {
dateTaken = cur.getLongValue(MediaStore.Images.Media.DATE_TAKEN)
dateModified = cur.getIntValue(MediaStore.Images.Media.DATE_MODIFIED) * 1000L
val dateTaken = cur.getLongValue(MediaStore.Images.Media.DATE_TAKEN)
val dateModified = cur.getIntValue(MediaStore.Images.Media.DATE_MODIFIED) * 1000L
val medium = Medium(filename, path, isVideo, dateModified, dateTaken, size)
curMedia.add(medium)
@ -143,6 +139,38 @@ private fun parseCursor(context: Context, cur: Cursor, isPickImage: Boolean, isP
}
}
if (curPath.isEmpty()) {
config.includedFolders.mapNotNull { File(it).listFiles() }.forEach {
for (file in it) {
val size = file.length()
if (size <= 0L) {
continue
}
val filename = file.name
val isImage = filename.isImageFast() || filename.isGif()
val isVideo = if (isImage) false else filename.isVideoFast()
if (!isImage && !isVideo)
continue
if (isVideo && (isPickImage || showMedia == IMAGES))
continue
if (isImage && (isPickVideo || showMedia == VIDEOS))
continue
val dateTaken = file.lastModified()
val dateModified = file.lastModified()
val medium = Medium(filename, file.absolutePath, isVideo, dateModified, dateTaken, size)
val isAlreadyAdded = curMedia.any { it.path == file.absolutePath }
if (!isAlreadyAdded)
curMedia.add(medium)
}
}
}
Medium.sorting = config.getFileSorting(curPath)
curMedia.sort()

View file

@ -302,7 +302,7 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
if (mSurfaceHolder == null)
mSurfaceHolder = mSurfaceView!!.holder
if (activity == null || !mSurfaceHolder!!.surface.isValid)
if (activity == null || mSurfaceHolder == null || !mSurfaceHolder!!.surface.isValid)
return
initMediaPlayer()

View file

@ -1,10 +1,13 @@
package com.simplemobiletools.gallery.helpers
import android.content.Context
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.simplemobiletools.commons.helpers.BaseConfig
import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED
import com.simplemobiletools.commons.helpers.SORT_DESCENDING
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.models.AlbumCover
import java.util.*
class Config(context: Context) : BaseConfig(context) {
@ -167,4 +170,13 @@ class Config(context: Context) : BaseConfig(context) {
var directories: String
get() = prefs.getString(DIRECTORIES, "")
set(directories) = prefs.edit().putString(DIRECTORIES, directories).apply()
var albumCovers: String
get() = prefs.getString(ALBUM_COVERS, "")
set(albumCovers) = prefs.edit().putString(ALBUM_COVERS, albumCovers).apply()
fun parseAlbumCovers(): ArrayList<AlbumCover> {
val listType = object : TypeToken<List<AlbumCover>>() {}.type
return Gson().fromJson<ArrayList<AlbumCover>>(albumCovers, listType) ?: ArrayList(1)
}
}

View file

@ -23,6 +23,7 @@ val SAVE_FOLDER_PREFIX = "folder2_"
val HIDE_FOLDER_TOOLTIP_SHOWN = "hide_folder_tooltip_shown"
val EXCLUDED_FOLDERS = "excluded_folders"
val INCLUDED_FOLDERS = "included_folders"
val ALBUM_COVERS = "album_covers"
val NOMEDIA = ".nomedia"
@ -33,6 +34,7 @@ val GET_VIDEO_INTENT = "get_video_intent"
val GET_ANY_INTENT = "get_any_intent"
val SET_WALLPAPER_INTENT = "set_wallpaper_intent"
val DIRECTORIES = "directories2"
val IS_VIEW_INTENT = "is_view_intent"
val REQUEST_EDIT_IMAGE = 1
val REQUEST_SET_WALLPAPER = 2

View file

@ -0,0 +1,3 @@
package com.simplemobiletools.gallery.models
data class AlbumCover(val path: String, val tmb: String)

View file

@ -5,5 +5,6 @@
android:id="@+id/directories_grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
app:layoutManager="android.support.v7.widget.GridLayoutManager"
app:spanCount="@integer/directory_columns"/>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/media_grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
app:layoutManager="android.support.v7.widget.GridLayoutManager"
app:spanCount="@integer/media_columns"/>

View file

@ -24,12 +24,12 @@
<item
android:id="@+id/cab_hide"
android:icon="@drawable/ic_hide"
android:title="@string/hide"
android:title="@string/hide_folder"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/cab_unhide"
android:icon="@drawable/ic_unhide"
android:title="@string/unhide"
android:title="@string/unhide_folder"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/cab_exclude"
@ -48,6 +48,19 @@
android:icon="@drawable/ic_select_all"
android:title="@string/select_all"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/cab_change_cover_image"
android:title="@string/change_cover_image"
app:showAsAction="never">
<menu>
<item
android:id="@+id/cab_select_photo"
android:title="@string/select_photo"/>
<item
android:id="@+id/cab_use_default"
android:title="@string/use_default"/>
</menu>
</item>
<item
android:id="@+id/cab_delete"
android:icon="@drawable/ic_delete"

View file

@ -22,11 +22,11 @@
app:showAsAction="ifRoom"/>
<item
android:id="@+id/hide_folder"
android:title="@string/hide"
android:title="@string/hide_folder"
app:showAsAction="never"/>
<item
android:id="@+id/unhide_folder"
android:title="@string/unhide"
android:title="@string/unhide_folder"
app:showAsAction="never"/>
<item
android:id="@+id/exclude_folder"

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Zvýšit počet sloupců</string>
<string name="reduce_column_count">Snížit počet sloupců</string>
<string name="temporarily_show_hidden">Dočasně zobrazit skryté</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">Tato funkce skryje složku, včetně podsložek, přidáním souboru \'.nomedia\'. Zobrazíte je zvolením možnosti \'Zobrazit skryté složky\' v nastavení. Pokračovat?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Device rotation</string>
<string name="screen_rotation_aspect_ratio">Aspect ratio</string>
<string name="dark_background_at_fullscreen">Dark background at fullscreen media</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Kacheln verkleinern</string>
<string name="reduce_column_count">Kacheln vergrößern</string>
<string name="temporarily_show_hidden">Verstecktes temporär zeigen</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">Diese Funktion versteckt ausgewählte Ordner (auch für andere Apps), indem dort im Dateisystem eine \'.nomedia\'-Datei abgelegt wird. Dadurch werden auch deren Unterordner versteckt. Solche Ordner werden nur gezeigt, wenn die Einstellung \'Versteckte Ordner zeigen\' aktiv ist (auch andere Apps bieten üblicherweise eine solche Option). Fortfahren?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Gerätedrehung</string>
<string name="screen_rotation_aspect_ratio">Seitenverhältnis</string>
<string name="dark_background_at_fullscreen">Schwarzer Hintergrund im Vollbild</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Aumentar el número de columnas</string>
<string name="reduce_column_count">Reducir el número de columnas</string>
<string name="temporarily_show_hidden">Mostrar ocultos temporalmente</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">Esta función oculta la carpeta agregando un archivo \'.nomedia\' en ella, y ocultará también las subcarpetas. Puede mostrarlas cambiando la opción \'Mostrar carpetas ocultas\' en los Ajustes. ¿Continuar?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Rotación del dispositivo</string>
<string name="screen_rotation_aspect_ratio">Relación de aspecto</string>
<string name="dark_background_at_fullscreen">Utilizar siempre fondo oscuro en pantalla completa</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Augmenter le nombre de colonnes</string>
<string name="reduce_column_count">Réduire le nombre de colonnes</string>
<string name="temporarily_show_hidden">Afficher temporairement les fichiers masqués</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">Cette option masque le dossier en ajoutant un fichier \'.nomedia\' à l\'intérieur, cela masquera aussi tous les sous-dossiers. Vous pouvez les voir en modifiant l\'option \'Afficher les dossiers cachés\' dans les Paramètres. Continuer ?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Rotation de l\'appareil</string>
<string name="screen_rotation_aspect_ratio">Ratio d\'aspect</string>
<string name="dark_background_at_fullscreen">Dark background at fullscreen media</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Increase column count</string>
<string name="reduce_column_count">Reduce column count</string>
<string name="temporarily_show_hidden">Temporarily show hidden</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">This function hides the folder by adding a \'.nomedia\' file into it, it will hide all subfolders too. You can see them by toggling the \'Show hidden folders\' option in Settings. Continue?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Device rotation</string>
<string name="screen_rotation_aspect_ratio">Aspect ratio</string>
<string name="dark_background_at_fullscreen">Dark background at fullscreen media</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Aumenta numero colonne</string>
<string name="reduce_column_count">Riduci numero colonne</string>
<string name="temporarily_show_hidden">Mostra temporaneamente nascosti</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">Questa funzione nasconde la cartella aggiungendo un file \'.nomedia\' all\'interno, nasconderà anche tutte le sottocartelle. Puoi vederle attivando l\'opzione \'Mostra cartelle nascoste\' nelle impostazioni. Continuare?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Rotazione dispositivo</string>
<string name="screen_rotation_aspect_ratio">Proporzioni</string>
<string name="dark_background_at_fullscreen">Sfondo scuro a schermo intero</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Increase column count</string>
<string name="reduce_column_count">Reduce column count</string>
<string name="temporarily_show_hidden">Temporarily show hidden</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">This function hides the folder by adding a \'.nomedia\' file into it, it will hide all subfolders too. You can see them by toggling the \'Show hidden folders\' option in Settings. Continue?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Device rotation</string>
<string name="screen_rotation_aspect_ratio">Aspect ratio</string>
<string name="dark_background_at_fullscreen">Dark background at fullscreen media</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Zwiększ liczbę kolumn</string>
<string name="reduce_column_count">Zmniejsz liczbę kolumn</string>
<string name="temporarily_show_hidden">Temporarily show hidden</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">Ta funkcja ukrywa folder dodając \'. \' Nomedia plik do niego, można tak ukryć wszystkie podfoldery. Można je zobaczyć poprzez przełączanie \'Pokaż ukryte foldery \' opcję w ustawieniach. Kontyntynuj?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Device rotation</string>
<string name="screen_rotation_aspect_ratio">Aspect ratio</string>
<string name="dark_background_at_fullscreen">Dark background at fullscreen media</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Aumentar número de colunas</string>
<string name="reduce_column_count">Reduzir número de colunas</string>
<string name="temporarily_show_hidden">Mostrar pastas ocultas temporariamente</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">Esta opção oculta uma pasta com a adição de um arquivo \'.nomedia\' dentro dela, e irá ocultar todas as subpastas que estejam dentro da mesma. Você poderá rever essas pastas com a opção \'Mostrar pastas ocultas\'. Continuar?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Sensor do aparelho</string>
<string name="screen_rotation_aspect_ratio">Proporção da mídia</string>
<string name="dark_background_at_fullscreen">Fundo de tela escuro em mídia tela cheia</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Aumentar número de colunas</string>
<string name="reduce_column_count">Reduzir número de colunas</string>
<string name="temporarily_show_hidden">Mostrar ocultas temporariamente</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">Esta opção oculta uma pasta com a adição de um ficheiro \'.nomedia\' na pasta, e irá ocultar todas as subpastas existentes. Pode ver as pastas com a opção \'Mostrar pastas ocultas\'. Continuar?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Rotação do dispositivo</string>
<string name="screen_rotation_aspect_ratio">Proporção</string>
<string name="dark_background_at_fullscreen">Usar sempre um fundo escuro se em ecrã completo</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Добавить 1 столбец</string>
<string name="reduce_column_count">Убрать 1 столбец</string>
<string name="temporarily_show_hidden">Временный показ скрытых</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">Эта опция скрывает папку, добавляя в неё файл \'.nomedia\'; будут скрыты все подпапки. Можно показывать их, переключая \'Показать скрытые папки\' в настройках. Продолжить?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Поворот устройства</string>
<string name="screen_rotation_aspect_ratio">Соотношение сторон</string>
<string name="dark_background_at_fullscreen">Dark background at fullscreen media</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Zvýšiť počet stĺpcov</string>
<string name="reduce_column_count">Znížiť počet stĺpcov</string>
<string name="temporarily_show_hidden">Dočasne zobraziť skryté</string>
<string name="change_cover_image">Zmeniť obal albumu</string>
<string name="select_photo">Zvoliť foto</string>
<string name="use_default">Použiť predvolený</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">Táto funkcia skryje priečinok pridaním súboru \'.nomedia\', skryté budú aj podpriečinky. Môžete ich vidieť zvolením možnosti \'Zobraziť skryté priečinky\' v nastaveniach. Pokračovať?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Otočenia zariadenia</string>
<string name="screen_rotation_aspect_ratio">Pomeru strán</string>
<string name="dark_background_at_fullscreen">Tmavé pozadie pri médiách na celú obrazovku</string>
<string name="scroll_thumbnails_horizontally">Prehliadať miniatúry vodorovne</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Increase column count</string>
<string name="reduce_column_count">Reduce column count</string>
<string name="temporarily_show_hidden">Temporarily show hidden</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">This function hides the folder by adding a \'.nomedia\' file into it, it will hide all subfolders too. You can see them by toggling the \'Show hidden folders\' option in Settings. Continue?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Device rotation</string>
<string name="screen_rotation_aspect_ratio">Aspect ratio</string>
<string name="dark_background_at_fullscreen">Dark background at fullscreen media</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Sütun sayısını artır</string>
<string name="reduce_column_count">Sütun sayısını azalt</string>
<string name="temporarily_show_hidden">Geçici olarak gizli göster</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">Bu işlev, klasöre\'.medya yok\'dosyası ekleyerek gizler; tüm alt klasörleri de gizler. Bunları Ayarlar\'da\'Gizli klasörleri göster\'seçeneğine basarak görebilirsiniz. Devam et?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Cihaz döndürme</string>
<string name="screen_rotation_aspect_ratio">En-boy oranı</string>
<string name="dark_background_at_fullscreen">Dark background at fullscreen media</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">增加一行</string>
<string name="reduce_column_count">减少一行</string>
<string name="temporarily_show_hidden">显示/隐藏缓存内容</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">通过添加一个 \'.nomedia\' 文件到目录下,该目录包括子目录下的所有媒体都不会被扫描。 你可以通过设置中的 \'Show hidden folders\' 选项改变设置, 继续?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">设备方向</string>
<string name="screen_rotation_aspect_ratio">根据长宽比</string>
<string name="dark_background_at_fullscreen">全屏时黑色背景</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Increase column count</string>
<string name="reduce_column_count">Reduce column count</string>
<string name="temporarily_show_hidden">Temporarily show hidden</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">This function hides the folder by adding a \'.nomedia\' file into it, it will hide all subfolders too. You can see them by toggling the \'Show hidden folders\' option in Settings. Continue?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Device rotation</string>
<string name="screen_rotation_aspect_ratio">Aspect ratio</string>
<string name="dark_background_at_fullscreen">Dark background at fullscreen media</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->

View file

@ -2,6 +2,7 @@
<resources>
<!-- Release notes -->
<string name="release_108">Allow setting custom folder covers</string>
<string name="release_98">
Allow selecting multiple items by finger dragging\n
Added an option to always use black background at fullscreen media

View file

@ -20,6 +20,9 @@
<string name="increase_column_count">Increase column count</string>
<string name="reduce_column_count">Reduce column count</string>
<string name="temporarily_show_hidden">Temporarily show hidden</string>
<string name="change_cover_image">Change cover image</string>
<string name="select_photo">Select photo</string>
<string name="use_default">Use default</string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">This function hides the folder by adding a \'.nomedia\' file into it, it will hide all subfolders too. You can see them by toggling the \'Show hidden folders\' option in Settings. Continue?</string>
@ -95,6 +98,7 @@
<string name="screen_rotation_device_rotation">Device rotation</string>
<string name="screen_rotation_aspect_ratio">Aspect ratio</string>
<string name="dark_background_at_fullscreen">Dark background at fullscreen media</string>
<string name="scroll_thumbnails_horizontally">Scroll thumbnails horizontally</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->