0
0
mirror of https://github.com/florisboard/florisboard.git synced 2024-09-19 19:42:20 +02:00

Fix random rotated images in threema (#2369)

* fix random rotated images in threema

* add filter for the projection

* do not filter only for orientation request but also for every other column

* Apply the suggestion

* get the orientation of the image on insert
This commit is contained in:
Lars Mühlbauer 2024-03-07 00:46:36 +01:00 committed by GitHub
parent 44f0c9cd89
commit 74dd67642c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 32 additions and 2 deletions

View File

@ -221,6 +221,7 @@ dependencies {
implementation(libs.androidx.core.splashscreen) implementation(libs.androidx.core.splashscreen)
implementation(libs.androidx.emoji2) implementation(libs.androidx.emoji2)
implementation(libs.androidx.emoji2.views) implementation(libs.androidx.emoji2.views)
implementation(libs.androidx.exifinterface)
implementation(libs.androidx.navigation.compose) implementation(libs.androidx.navigation.compose)
implementation(libs.androidx.profileinstaller) implementation(libs.androidx.profileinstaller)
ksp(libs.androidx.room.compiler) ksp(libs.androidx.room.compiler)

View File

@ -22,6 +22,7 @@ import android.content.Context
import android.database.Cursor import android.database.Cursor
import android.net.Uri import android.net.Uri
import android.provider.BaseColumns import android.provider.BaseColumns
import android.provider.MediaStore.Images.Media
import android.provider.OpenableColumns import android.provider.OpenableColumns
import androidx.core.database.getStringOrNull import androidx.core.database.getStringOrNull
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
@ -307,6 +308,7 @@ data class ClipboardFileInfo(
@PrimaryKey @ColumnInfo(name=BaseColumns._ID, index=true) val id: Long, @PrimaryKey @ColumnInfo(name=BaseColumns._ID, index=true) val id: Long,
@ColumnInfo(name=OpenableColumns.DISPLAY_NAME) val displayName: String, @ColumnInfo(name=OpenableColumns.DISPLAY_NAME) val displayName: String,
@ColumnInfo(name=OpenableColumns.SIZE) val size: Long, @ColumnInfo(name=OpenableColumns.SIZE) val size: Long,
@ColumnInfo(name=Media.ORIENTATION) val orientation: Int,
val mimeTypes: Array<String>, val mimeTypes: Array<String>,
) { ) {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
@ -340,6 +342,9 @@ interface ClipboardFilesDao {
@Query("SELECT * FROM $CLIPBOARD_FILES_TABLE WHERE ${BaseColumns._ID} == (:uid)") @Query("SELECT * FROM $CLIPBOARD_FILES_TABLE WHERE ${BaseColumns._ID} == (:uid)")
fun getCursorById(uid: Long) : Cursor fun getCursorById(uid: Long) : Cursor
@Query("SELECT (:projection) FROM $CLIPBOARD_FILES_TABLE WHERE ${BaseColumns._ID} == (:uid)")
fun getCurserByIdWithColums(uid: Long, projection: String) : Cursor
@Query("DELETE FROM $CLIPBOARD_FILES_TABLE WHERE ${BaseColumns._ID} == (:id)") @Query("DELETE FROM $CLIPBOARD_FILES_TABLE WHERE ${BaseColumns._ID} == (:id)")
fun delete(id: Long) fun delete(id: Long)
@ -350,7 +355,7 @@ interface ClipboardFilesDao {
fun getAll(): List<ClipboardFileInfo> fun getAll(): List<ClipboardFileInfo>
} }
@Database(entities = [ClipboardFileInfo::class], version = 1) @Database(entities = [ClipboardFileInfo::class], version = 2)
@TypeConverters(Converters::class) @TypeConverters(Converters::class)
abstract class ClipboardFilesDatabase : RoomDatabase() { abstract class ClipboardFilesDatabase : RoomDatabase() {
abstract fun clipboardFilesDao() : ClipboardFilesDao abstract fun clipboardFilesDao() : ClipboardFilesDao

View File

@ -25,7 +25,9 @@ import android.content.UriMatcher
import android.database.Cursor import android.database.Cursor
import android.net.Uri import android.net.Uri
import android.os.ParcelFileDescriptor import android.os.ParcelFileDescriptor
import android.provider.MediaStore
import android.provider.OpenableColumns import android.provider.OpenableColumns
import androidx.exifinterface.media.ExifInterface
import dev.patrickgold.florisboard.BuildConfig import dev.patrickgold.florisboard.BuildConfig
import dev.patrickgold.florisboard.lib.devtools.flogError import dev.patrickgold.florisboard.lib.devtools.flogError
import dev.patrickgold.florisboard.lib.kotlin.tryOrNull import dev.patrickgold.florisboard.lib.kotlin.tryOrNull
@ -91,6 +93,14 @@ class ClipboardMediaProvider : ContentProvider() {
sortOrder: String? sortOrder: String?
): Cursor? { ): Cursor? {
val id = tryOrNull { ContentUris.parseId(uri) } ?: return null val id = tryOrNull { ContentUris.parseId(uri) } ?: return null
if (projection != null) {
if (projection.contains(MediaStore.Images.Media.ORIENTATION)) {
clipboardFilesDao?.getCurserByIdWithColums(id, MediaStore.Images.Media.ORIENTATION)
} else {
//Return null if the projection query is invalid
return null
}
}
return clipboardFilesDao?.getCursorById(id) return clipboardFilesDao?.getCursorById(id)
} }
@ -128,11 +138,23 @@ class ClipboardMediaProvider : ContentProvider() {
return try { return try {
values as ContentValues values as ContentValues
val mediaUri = Uri.parse(values.getAsString(Columns.MediaUri)) val mediaUri = Uri.parse(values.getAsString(Columns.MediaUri))
// Get the orientation of the image
val exifInterface = ExifInterface(context!!.contentResolver.openInputStream(mediaUri)!!)
var rotation = 0
val orientation = exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL
)
when (orientation) {
ExifInterface.ORIENTATION_ROTATE_90 -> rotation = 90
ExifInterface.ORIENTATION_ROTATE_180 -> rotation = 180
ExifInterface.ORIENTATION_ROTATE_270 -> rotation = 270
}
val id = ClipboardFileStorage.cloneUri(context!!, mediaUri) val id = ClipboardFileStorage.cloneUri(context!!, mediaUri)
val size = ClipboardFileStorage.getFileForId(context!!, id).length() val size = ClipboardFileStorage.getFileForId(context!!, id).length()
val mimeTypes = values.getAsString(Columns.MimeTypes).split(",").toTypedArray() val mimeTypes = values.getAsString(Columns.MimeTypes).split(",").toTypedArray()
val displayName = values.getAsString(OpenableColumns.DISPLAY_NAME) val displayName = values.getAsString(OpenableColumns.DISPLAY_NAME)
val fileInfo = ClipboardFileInfo(id, displayName, size, mimeTypes) val fileInfo = ClipboardFileInfo(id, displayName, size, rotation, mimeTypes)
cachedFileInfos[id] = fileInfo cachedFileInfos[id] = fileInfo
ioScope.launch { ioScope.launch {
clipboardFilesDao?.insert(fileInfo) clipboardFilesDao?.insert(fileInfo)

View File

@ -11,6 +11,7 @@ androidx-compose-compiler = "1.5.9"
androidx-core = "1.12.0" androidx-core = "1.12.0"
androidx-core-splashscreen = "1.0.1" androidx-core-splashscreen = "1.0.1"
androidx-emoji2 = "1.3.0" androidx-emoji2 = "1.3.0"
androidx-exifinterface = "1.3.6"
androidx-navigation = "2.7.7" androidx-navigation = "2.7.7"
androidx-profileinstaller = "1.3.1" androidx-profileinstaller = "1.3.1"
androidx-room = "2.4.3" androidx-room = "2.4.3"
@ -50,6 +51,7 @@ androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx
androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "androidx-core-splashscreen" } androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "androidx-core-splashscreen" }
androidx-emoji2 = { module = "androidx.emoji2:emoji2", version.ref = "androidx-emoji2" } androidx-emoji2 = { module = "androidx.emoji2:emoji2", version.ref = "androidx-emoji2" }
androidx-emoji2-views = { module = "androidx.emoji2:emoji2-views", version.ref = "androidx-emoji2" } androidx-emoji2-views = { module = "androidx.emoji2:emoji2-views", version.ref = "androidx-emoji2" }
androidx-exifinterface = { module = "androidx.exifinterface:exifinterface", version.ref = "androidx-exifinterface" }
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "androidx-navigation" } androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "androidx-navigation" }
androidx-profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version.ref = "androidx-profileinstaller" } androidx-profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version.ref = "androidx-profileinstaller" }
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "androidx-room" } androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "androidx-room" }