moving some file rotation related functions in activity extensions
This commit is contained in:
parent
745adda5a4
commit
c81fbdbf9d
|
@ -8,10 +8,7 @@ import android.content.Intent
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.Matrix
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.media.ExifInterface
|
import android.media.ExifInterface
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
@ -26,7 +23,6 @@ import android.view.WindowManager
|
||||||
import android.view.animation.DecelerateInterpolator
|
import android.view.animation.DecelerateInterpolator
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.viewpager.widget.ViewPager
|
import androidx.viewpager.widget.ViewPager
|
||||||
import com.bumptech.glide.Glide
|
|
||||||
import com.simplemobiletools.commons.dialogs.PropertiesDialog
|
import com.simplemobiletools.commons.dialogs.PropertiesDialog
|
||||||
import com.simplemobiletools.commons.dialogs.RenameItemDialog
|
import com.simplemobiletools.commons.dialogs.RenameItemDialog
|
||||||
import com.simplemobiletools.commons.extensions.*
|
import com.simplemobiletools.commons.extensions.*
|
||||||
|
@ -49,9 +45,6 @@ import com.simplemobiletools.gallery.pro.models.ThumbnailItem
|
||||||
import kotlinx.android.synthetic.main.activity_medium.*
|
import kotlinx.android.synthetic.main.activity_medium.*
|
||||||
import kotlinx.android.synthetic.main.bottom_actions.*
|
import kotlinx.android.synthetic.main.bottom_actions.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
|
||||||
import java.io.InputStream
|
|
||||||
import java.io.OutputStream
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, ViewPagerFragment.FragmentListener {
|
class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, ViewPagerFragment.FragmentListener {
|
||||||
|
@ -595,116 +588,15 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
||||||
SaveAsDialog(this, currPath, false) {
|
SaveAsDialog(this, currPath, false) {
|
||||||
handleSAFDialog(it) {
|
handleSAFDialog(it) {
|
||||||
Thread {
|
Thread {
|
||||||
saveImageToFile(currPath, it)
|
saveImageToFile(currPath, it, mRotationDegrees) {
|
||||||
|
mRotationDegrees = 0
|
||||||
|
invalidateOptionsMenu()
|
||||||
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveImageToFile(oldPath: String, newPath: String) {
|
|
||||||
toast(R.string.saving)
|
|
||||||
if (oldPath == newPath && oldPath.isJpg()) {
|
|
||||||
if (tryRotateByExif(oldPath)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val tmpPath = "$recycleBinPath/.tmp_${newPath.getFilenameFromPath()}"
|
|
||||||
val tmpFileDirItem = FileDirItem(tmpPath, tmpPath.getFilenameFromPath())
|
|
||||||
try {
|
|
||||||
getFileOutputStream(tmpFileDirItem) {
|
|
||||||
if (it == null) {
|
|
||||||
toast(R.string.unknown_error_occurred)
|
|
||||||
return@getFileOutputStream
|
|
||||||
}
|
|
||||||
|
|
||||||
val oldLastModified = File(oldPath).lastModified()
|
|
||||||
if (oldPath.isJpg()) {
|
|
||||||
copyFile(oldPath, tmpPath)
|
|
||||||
saveExifRotation(ExifInterface(tmpPath), mRotationDegrees)
|
|
||||||
} else {
|
|
||||||
val inputstream = getFileInputStreamSync(oldPath)
|
|
||||||
val bitmap = BitmapFactory.decodeStream(inputstream)
|
|
||||||
saveFile(tmpPath, bitmap, it as FileOutputStream)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getDoesFilePathExist(newPath)) {
|
|
||||||
tryDeleteFileDirItem(FileDirItem(newPath, newPath.getFilenameFromPath()), false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
copyFile(tmpPath, newPath)
|
|
||||||
scanPathRecursively(newPath)
|
|
||||||
toast(R.string.file_saved)
|
|
||||||
|
|
||||||
if (config.keepLastModified) {
|
|
||||||
File(newPath).setLastModified(oldLastModified)
|
|
||||||
updateLastModified(newPath, oldLastModified)
|
|
||||||
}
|
|
||||||
|
|
||||||
it.flush()
|
|
||||||
it.close()
|
|
||||||
mRotationDegrees = 0
|
|
||||||
invalidateOptionsMenu()
|
|
||||||
|
|
||||||
// we cannot refresh a specific image in Glide Cache, so just clear it all
|
|
||||||
val glide = Glide.get(applicationContext)
|
|
||||||
glide.clearDiskCache()
|
|
||||||
runOnUiThread {
|
|
||||||
glide.clearMemory()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: OutOfMemoryError) {
|
|
||||||
toast(R.string.out_of_memory_error)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
showErrorToast(e)
|
|
||||||
} finally {
|
|
||||||
tryDeleteFileDirItem(tmpFileDirItem, false, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.N)
|
|
||||||
private fun tryRotateByExif(path: String): Boolean {
|
|
||||||
return try {
|
|
||||||
val file = File(path)
|
|
||||||
val oldLastModified = file.lastModified()
|
|
||||||
if (saveImageRotation(path, mRotationDegrees)) {
|
|
||||||
if (config.keepLastModified) {
|
|
||||||
file.setLastModified(oldLastModified)
|
|
||||||
updateLastModified(path, oldLastModified)
|
|
||||||
}
|
|
||||||
mRotationDegrees = 0
|
|
||||||
invalidateOptionsMenu()
|
|
||||||
toast(R.string.file_saved)
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
showErrorToast(e)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun copyFile(source: String, destination: String) {
|
|
||||||
var inputStream: InputStream? = null
|
|
||||||
var out: OutputStream? = null
|
|
||||||
try {
|
|
||||||
out = getFileOutputStreamSync(destination, source.getMimeType())
|
|
||||||
inputStream = getFileInputStreamSync(source)
|
|
||||||
inputStream?.copyTo(out!!)
|
|
||||||
} finally {
|
|
||||||
inputStream?.close()
|
|
||||||
out?.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun saveFile(path: String, bitmap: Bitmap, out: FileOutputStream) {
|
|
||||||
val matrix = Matrix()
|
|
||||||
matrix.postRotate(mRotationDegrees.toFloat())
|
|
||||||
val bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
|
|
||||||
bmp.compress(path.getCompressionFormat(), 90, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isShowHiddenFlagNeeded(): Boolean {
|
private fun isShowHiddenFlagNeeded(): Boolean {
|
||||||
val file = File(mPath)
|
val file = File(mPath)
|
||||||
if (file.isHidden) {
|
if (file.isHidden) {
|
||||||
|
@ -1169,8 +1061,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
|
||||||
|
|
||||||
private fun getCurrentPath() = getCurrentMedium()?.path ?: ""
|
private fun getCurrentPath() = getCurrentMedium()?.path ?: ""
|
||||||
|
|
||||||
private fun getCurrentFile() = File(getCurrentPath())
|
|
||||||
|
|
||||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
|
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
|
||||||
|
|
||||||
override fun onPageSelected(position: Int) {
|
override fun onPageSelected(position: Int) {
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
package com.simplemobiletools.gallery.pro.extensions
|
package com.simplemobiletools.gallery.pro.extensions
|
||||||
|
|
||||||
|
import android.annotation.TargetApi
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.ContentProviderOperation
|
import android.content.ContentProviderOperation
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.graphics.Matrix
|
||||||
import android.media.ExifInterface
|
import android.media.ExifInterface
|
||||||
|
import android.os.Build
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||||
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
||||||
import com.simplemobiletools.commons.extensions.*
|
import com.simplemobiletools.commons.extensions.*
|
||||||
|
@ -22,6 +28,7 @@ import com.simplemobiletools.gallery.pro.helpers.NOMEDIA
|
||||||
import com.simplemobiletools.gallery.pro.helpers.RECYCLE_BIN
|
import com.simplemobiletools.gallery.pro.helpers.RECYCLE_BIN
|
||||||
import com.simplemobiletools.gallery.pro.interfaces.MediumDao
|
import com.simplemobiletools.gallery.pro.interfaces.MediumDao
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
@ -364,3 +371,105 @@ fun Activity.fixDateTaken(paths: ArrayList<String>, callback: (() -> Unit)? = nu
|
||||||
showErrorToast(e)
|
showErrorToast(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun BaseSimpleActivity.saveImageToFile(oldPath: String, newPath: String, degrees: Int, callback: () -> Unit) {
|
||||||
|
toast(R.string.saving)
|
||||||
|
if (oldPath == newPath && oldPath.isJpg()) {
|
||||||
|
if (tryRotateByExif(oldPath, degrees, callback)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val tmpPath = "$recycleBinPath/.tmp_${newPath.getFilenameFromPath()}"
|
||||||
|
val tmpFileDirItem = FileDirItem(tmpPath, tmpPath.getFilenameFromPath())
|
||||||
|
try {
|
||||||
|
getFileOutputStream(tmpFileDirItem) {
|
||||||
|
if (it == null) {
|
||||||
|
toast(R.string.unknown_error_occurred)
|
||||||
|
return@getFileOutputStream
|
||||||
|
}
|
||||||
|
|
||||||
|
val oldLastModified = File(oldPath).lastModified()
|
||||||
|
if (oldPath.isJpg()) {
|
||||||
|
copyFile(oldPath, tmpPath)
|
||||||
|
saveExifRotation(ExifInterface(tmpPath), degrees)
|
||||||
|
} else {
|
||||||
|
val inputstream = getFileInputStreamSync(oldPath)
|
||||||
|
val bitmap = BitmapFactory.decodeStream(inputstream)
|
||||||
|
saveFile(tmpPath, bitmap, it as FileOutputStream, degrees)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getDoesFilePathExist(newPath)) {
|
||||||
|
tryDeleteFileDirItem(FileDirItem(newPath, newPath.getFilenameFromPath()), false, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
copyFile(tmpPath, newPath)
|
||||||
|
scanPathRecursively(newPath)
|
||||||
|
toast(R.string.file_saved)
|
||||||
|
|
||||||
|
if (config.keepLastModified) {
|
||||||
|
File(newPath).setLastModified(oldLastModified)
|
||||||
|
updateLastModified(newPath, oldLastModified)
|
||||||
|
}
|
||||||
|
|
||||||
|
it.flush()
|
||||||
|
it.close()
|
||||||
|
callback.invoke()
|
||||||
|
|
||||||
|
// we cannot refresh a specific image in Glide Cache, so just clear it all
|
||||||
|
val glide = Glide.get(applicationContext)
|
||||||
|
glide.clearDiskCache()
|
||||||
|
runOnUiThread {
|
||||||
|
glide.clearMemory()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: OutOfMemoryError) {
|
||||||
|
toast(R.string.out_of_memory_error)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
showErrorToast(e)
|
||||||
|
} finally {
|
||||||
|
tryDeleteFileDirItem(tmpFileDirItem, false, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.N)
|
||||||
|
fun Activity.tryRotateByExif(path: String, degrees: Int, callback: () -> Unit): Boolean {
|
||||||
|
return try {
|
||||||
|
val file = File(path)
|
||||||
|
val oldLastModified = file.lastModified()
|
||||||
|
if (saveImageRotation(path, degrees)) {
|
||||||
|
if (config.keepLastModified) {
|
||||||
|
file.setLastModified(oldLastModified)
|
||||||
|
updateLastModified(path, oldLastModified)
|
||||||
|
}
|
||||||
|
callback.invoke()
|
||||||
|
toast(R.string.file_saved)
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
showErrorToast(e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun BaseSimpleActivity.copyFile(source: String, destination: String) {
|
||||||
|
var inputStream: InputStream? = null
|
||||||
|
var out: OutputStream? = null
|
||||||
|
try {
|
||||||
|
out = getFileOutputStreamSync(destination, source.getMimeType())
|
||||||
|
inputStream = getFileInputStreamSync(source)
|
||||||
|
inputStream?.copyTo(out!!)
|
||||||
|
} finally {
|
||||||
|
inputStream?.close()
|
||||||
|
out?.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveFile(path: String, bitmap: Bitmap, out: FileOutputStream, degrees: Int) {
|
||||||
|
val matrix = Matrix()
|
||||||
|
matrix.postRotate(degrees.toFloat())
|
||||||
|
val bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
|
||||||
|
bmp.compress(path.getCompressionFormat(), 90, out)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue