commit
418c59dcc6
9 changed files with 82 additions and 27 deletions
|
@ -46,7 +46,7 @@ ext {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.simplemobiletools:commons:3.14.12'
|
||||
implementation 'com.simplemobiletools:commons:3.16.1'
|
||||
implementation 'com.theartofdev.edmodo:android-image-cropper:2.6.0'
|
||||
implementation 'com.android.support:multidex:1.0.3'
|
||||
implementation 'com.google.code.gson:gson:2.8.2'
|
||||
|
|
|
@ -11,8 +11,8 @@ import android.view.Menu
|
|||
import android.view.MenuItem
|
||||
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
||||
import com.simplemobiletools.commons.extensions.isActivityDestroyed
|
||||
import com.simplemobiletools.commons.extensions.isNougatPlus
|
||||
import com.simplemobiletools.commons.extensions.toast
|
||||
import com.simplemobiletools.commons.helpers.isNougatPlus
|
||||
import com.simplemobiletools.commons.models.RadioItem
|
||||
import com.simplemobiletools.gallery.R
|
||||
import com.theartofdev.edmodo.cropper.CropImageView
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.simplemobiletools.gallery.activities
|
|||
|
||||
import android.animation.Animator
|
||||
import android.animation.ValueAnimator
|
||||
import android.annotation.TargetApi
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
|
@ -522,9 +523,16 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
|||
}
|
||||
|
||||
private fun saveImageToFile(oldPath: String, newPath: String) {
|
||||
val newFile = File(newPath)
|
||||
toast(R.string.saving)
|
||||
if (oldPath == newPath && oldPath.isJpg()) {
|
||||
if (tryRotateByExif(oldPath)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val newFile = File(newPath)
|
||||
val tmpFile = File(filesDir, ".tmp_${newPath.getFilenameFromPath()}")
|
||||
|
||||
try {
|
||||
val bitmap = BitmapFactory.decodeFile(oldPath)
|
||||
getFileOutputStream(tmpFile.toFileDirItem(applicationContext)) {
|
||||
|
@ -535,7 +543,8 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
|||
|
||||
val oldLastModified = getCurrentFile().lastModified()
|
||||
if (oldPath.isJpg()) {
|
||||
saveRotation(getCurrentFile(), tmpFile)
|
||||
copyFile(getCurrentFile(), tmpFile)
|
||||
saveExifRotation(ExifInterface(tmpFile.absolutePath))
|
||||
} else {
|
||||
saveFile(tmpFile, bitmap, it as FileOutputStream)
|
||||
}
|
||||
|
@ -573,6 +582,33 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
|||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.N)
|
||||
private fun tryRotateByExif(path: String): Boolean {
|
||||
try {
|
||||
if (!isPathOnSD(path)) {
|
||||
saveExifRotation(ExifInterface(path))
|
||||
mRotationDegrees = 0f
|
||||
invalidateOptionsMenu()
|
||||
toast(R.string.file_saved)
|
||||
return true
|
||||
} else if (isNougatPlus()) {
|
||||
val documentFile = getSomeDocumentFile(path)
|
||||
if (documentFile != null) {
|
||||
val parcelFileDescriptor = contentResolver.openFileDescriptor(documentFile.uri, "rw")
|
||||
val fileDescriptor = parcelFileDescriptor.fileDescriptor
|
||||
saveExifRotation(ExifInterface(fileDescriptor))
|
||||
mRotationDegrees = 0f
|
||||
invalidateOptionsMenu()
|
||||
toast(R.string.file_saved)
|
||||
return true
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun copyFile(source: File, destination: File) {
|
||||
var inputStream: InputStream? = null
|
||||
var out: OutputStream? = null
|
||||
|
@ -594,9 +630,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
|||
bmp.compress(file.absolutePath.getCompressionFormat(), 90, out)
|
||||
}
|
||||
|
||||
private fun saveRotation(source: File, destination: File) {
|
||||
copyFile(source, destination)
|
||||
val exif = ExifInterface(destination.absolutePath)
|
||||
private fun saveExifRotation(exif: ExifInterface) {
|
||||
val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
|
||||
val orientationDegrees = (degreesForRotation(orientation) + mRotationDegrees) % 360
|
||||
exif.setAttribute(ExifInterface.TAG_ORIENTATION, rotationFromDegrees(orientationDegrees))
|
||||
|
|
|
@ -73,7 +73,6 @@ fun Activity.launchCamera() {
|
|||
|
||||
fun SimpleActivity.launchAbout() {
|
||||
val faqItems = arrayListOf(
|
||||
FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons),
|
||||
FAQItem(R.string.faq_3_title_commons, R.string.faq_3_text_commons),
|
||||
FAQItem(R.string.faq_1_title, R.string.faq_1_text),
|
||||
FAQItem(R.string.faq_2_title, R.string.faq_2_text),
|
||||
|
@ -83,9 +82,10 @@ fun SimpleActivity.launchAbout() {
|
|||
FAQItem(R.string.faq_6_title, R.string.faq_6_text),
|
||||
FAQItem(R.string.faq_7_title, R.string.faq_7_text),
|
||||
FAQItem(R.string.faq_8_title, R.string.faq_8_text),
|
||||
FAQItem(R.string.faq_9_title, R.string.faq_9_text))
|
||||
FAQItem(R.string.faq_9_title, R.string.faq_9_text),
|
||||
FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons))
|
||||
|
||||
startAboutActivity(R.string.app_name, LICENSE_KOTLIN or LICENSE_GLIDE or LICENSE_CROPPER or LICENSE_MULTISELECT or LICENSE_RTL
|
||||
startAboutActivity(R.string.app_name, LICENSE_GLIDE or LICENSE_CROPPER or LICENSE_MULTISELECT or LICENSE_RTL
|
||||
or LICENSE_SUBSAMPLING or LICENSE_PATTERN or LICENSE_REPRINT or LICENSE_GIF_DRAWABLE or LICENSE_PHOTOVIEW, BuildConfig.VERSION_NAME, faqItems)
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ fun BaseSimpleActivity.toggleFileVisibility(oldPath: String, hide: Boolean, call
|
|||
filename.substring(1, filename.length)
|
||||
}
|
||||
|
||||
val newPath = "$path/$filename"
|
||||
val newPath = "$path$filename"
|
||||
renameFile(oldPath, newPath) {
|
||||
callback?.invoke(newPath)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import android.media.ExifInterface.*
|
|||
import android.net.Uri
|
||||
import android.os.AsyncTask
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -44,6 +45,7 @@ class PhotoFragment : ViewPagerFragment() {
|
|||
private var isFragmentVisible = false
|
||||
private var isFullscreen = false
|
||||
private var wasInit = false
|
||||
private var useHalfResolution = false
|
||||
private var imageOrientation = -1
|
||||
private var gifDrawable: GifDrawable? = null
|
||||
|
||||
|
@ -57,7 +59,7 @@ class PhotoFragment : ViewPagerFragment() {
|
|||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
view = (inflater.inflate(R.layout.pager_photo_item, container, false) as ViewGroup).apply {
|
||||
subsampling_view.setOnClickListener { photoClicked() }
|
||||
gif_view.setOnClickListener { photoClicked() }
|
||||
photo_view.setOnClickListener { photoClicked() }
|
||||
instant_prev_item.setOnClickListener { listener?.goToPrevItem() }
|
||||
instant_next_item.setOnClickListener { listener?.goToNextItem() }
|
||||
|
||||
|
@ -69,7 +71,7 @@ class PhotoFragment : ViewPagerFragment() {
|
|||
if (subsampling_view.isVisible()) {
|
||||
subsampling_view.sendFakeClick(x, y)
|
||||
} else {
|
||||
gif_view.sendFakeClick(x, y)
|
||||
photo_view.sendFakeClick(x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +219,7 @@ class PhotoFragment : ViewPagerFragment() {
|
|||
gifDrawable!!.stop()
|
||||
}
|
||||
|
||||
view.gif_view.setImageDrawable(gifDrawable)
|
||||
view.photo_view.setImageDrawable(gifDrawable)
|
||||
} catch (e: Exception) {
|
||||
gifDrawable = null
|
||||
loadBitmap()
|
||||
|
@ -231,6 +233,11 @@ class PhotoFragment : ViewPagerFragment() {
|
|||
if (degrees == 0f) {
|
||||
var targetWidth = if (ViewPagerActivity.screenWidth == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenWidth
|
||||
var targetHeight = if (ViewPagerActivity.screenHeight == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenHeight
|
||||
if (useHalfResolution) {
|
||||
targetWidth /= 2
|
||||
targetHeight /= 2
|
||||
}
|
||||
|
||||
if (imageOrientation == ORIENTATION_ROTATE_90) {
|
||||
targetWidth = targetHeight
|
||||
targetHeight = Target.SIZE_ORIGINAL
|
||||
|
@ -247,14 +254,22 @@ class PhotoFragment : ViewPagerFragment() {
|
|||
.load(getPathToLoad(medium))
|
||||
.apply(options)
|
||||
.listener(object : RequestListener<Bitmap> {
|
||||
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>?, isFirstResource: Boolean) = false
|
||||
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
|
||||
if (!useHalfResolution && e?.rootCauses?.first() is OutOfMemoryError) {
|
||||
useHalfResolution = true
|
||||
Handler().post {
|
||||
loadBitmap(degrees)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResourceReady(resource: Bitmap?, model: Any?, target: Target<Bitmap>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
|
||||
if (isFragmentVisible)
|
||||
addZoomableView()
|
||||
return false
|
||||
}
|
||||
}).into(view.gif_view)
|
||||
}).into(view.photo_view)
|
||||
} else {
|
||||
val options = RequestOptions()
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
|
@ -265,7 +280,7 @@ class PhotoFragment : ViewPagerFragment() {
|
|||
.load(getPathToLoad(medium))
|
||||
.thumbnail(0.2f)
|
||||
.apply(options)
|
||||
.into(view.gif_view)
|
||||
.into(view.photo_view)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,6 +380,7 @@ class PhotoFragment : ViewPagerFragment() {
|
|||
text = getMediumExtendedDetails(medium)
|
||||
setTextColor(context.config.textColor)
|
||||
beVisibleIf(text.isNotEmpty())
|
||||
alpha = if (!context!!.config.hideExtendedDetails || !isFullscreen) 1f else 0f
|
||||
onGlobalLayout {
|
||||
if (height != 0 && isAdded) {
|
||||
y = getExtendedDetailsY(height)
|
||||
|
@ -379,7 +395,7 @@ class PhotoFragment : ViewPagerFragment() {
|
|||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
if (activity?.isActivityDestroyed() == false) {
|
||||
Glide.with(context!!).clear(view.gif_view)
|
||||
Glide.with(context!!).clear(view.photo_view)
|
||||
view.subsampling_view.recycle()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import android.view.animation.AnimationUtils
|
|||
import android.widget.SeekBar
|
||||
import android.widget.TextView
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.isJellyBean1Plus
|
||||
import com.simplemobiletools.gallery.BuildConfig
|
||||
import com.simplemobiletools.gallery.R
|
||||
import com.simplemobiletools.gallery.activities.VideoActivity
|
||||
|
@ -27,6 +28,7 @@ import java.io.IOException
|
|||
|
||||
class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSeekBarChangeListener {
|
||||
private val PROGRESS = "progress"
|
||||
private val MIN_SKIP_LENGTH = 2000
|
||||
|
||||
private var mMediaPlayer: MediaPlayer? = null
|
||||
private var mSurfaceView: SurfaceView? = null
|
||||
|
@ -73,12 +75,12 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
|
|||
mIsFragmentVisible = true
|
||||
}
|
||||
|
||||
mIsFullscreen = activity!!.window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_FULLSCREEN == View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
setupPlayer()
|
||||
if (savedInstanceState != null) {
|
||||
mCurrTime = savedInstanceState.getInt(PROGRESS)
|
||||
}
|
||||
|
||||
mIsFullscreen = activity!!.window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_FULLSCREEN == View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
checkFullscreen()
|
||||
wasInit = true
|
||||
|
||||
|
@ -433,7 +435,7 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
|
|||
val screenWidth: Int
|
||||
val screenHeight: Int
|
||||
|
||||
if (activity!!.isJellyBean1Plus()) {
|
||||
if (isJellyBean1Plus()) {
|
||||
val realMetrics = DisplayMetrics()
|
||||
display.getRealMetrics(realMetrics)
|
||||
screenWidth = realMetrics.widthPixels
|
||||
|
@ -463,6 +465,7 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
|
|||
text = getMediumExtendedDetails(medium)
|
||||
setTextColor(context.config.textColor)
|
||||
beVisibleIf(text.isNotEmpty())
|
||||
alpha = if (!context!!.config.hideExtendedDetails || !mIsFullscreen) 1f else 0f
|
||||
onGlobalLayout {
|
||||
if (height != 0 && isAdded) {
|
||||
y = getExtendedDetailsY(height)
|
||||
|
@ -480,9 +483,11 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
|
|||
}
|
||||
|
||||
val curr = mMediaPlayer!!.currentPosition
|
||||
val twoPercents = mMediaPlayer!!.duration / 50
|
||||
val twoPercents = Math.max(mMediaPlayer!!.duration / 50, MIN_SKIP_LENGTH)
|
||||
val newProgress = if (forward) curr + twoPercents else curr - twoPercents
|
||||
setProgress(Math.round(newProgress / 1000f))
|
||||
val roundProgress = Math.round(newProgress / 1000f)
|
||||
val limitedProgress = Math.max(Math.min(mMediaPlayer!!.duration / 1000, roundProgress), 0)
|
||||
setProgress(limitedProgress)
|
||||
if (!mIsPlaying) {
|
||||
togglePlayPause()
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ class MediaFetcher(val context: Context) {
|
|||
directories.remove(it)
|
||||
}
|
||||
|
||||
searchNewFiles(directories, showHidden)
|
||||
//searchNewFiles(directories, showHidden)
|
||||
return directories
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ class MediaFetcher(val context: Context) {
|
|||
private fun getSelectionQuery(path: String): String? {
|
||||
val dataQuery = "${MediaStore.Images.Media.DATA} LIKE ?"
|
||||
return if (path.isEmpty()) {
|
||||
if (context.isAndroidFour())
|
||||
if (isAndroidFour())
|
||||
return null
|
||||
|
||||
var query = "($dataQuery)"
|
||||
|
@ -119,7 +119,7 @@ class MediaFetcher(val context: Context) {
|
|||
|
||||
private fun getSelectionArgsQuery(path: String): Array<String>? {
|
||||
return if (path.isEmpty()) {
|
||||
if (context.isAndroidFour()) {
|
||||
if (isAndroidFour()) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
android:layout_height="match_parent">
|
||||
|
||||
<com.github.chrisbanes.photoview.PhotoView
|
||||
android:id="@+id/gif_view"
|
||||
android:id="@+id/photo_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="fitCenter"/>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<external-path name="external_files" path="."/>
|
||||
<root-path name="external_files" path="/storage/" />
|
||||
<root-path name="external_files" path="/" />
|
||||
</paths>
|
||||
|
|
Loading…
Reference in a new issue