From 4205a65b87f75c3a122de6a420b278ea679784e7 Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Sun, 14 May 2023 16:25:48 -0700 Subject: [PATCH] Multiple fixes --- .../java/gallery/memories/MainActivity.kt | 26 ++++++++---- app/src/main/java/gallery/memories/NativeX.kt | 19 +++++---- .../gallery/memories/mapper/SystemImage.kt | 40 ++++++++++++++----- .../gallery/memories/service/ImageService.kt | 34 +++++++++++----- app/src/main/res/layout/activity_main.xml | 1 - 5 files changed, 85 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/gallery/memories/MainActivity.kt b/app/src/main/java/gallery/memories/MainActivity.kt index fc2582a7..75f9b3ac 100644 --- a/app/src/main/java/gallery/memories/MainActivity.kt +++ b/app/src/main/java/gallery/memories/MainActivity.kt @@ -1,6 +1,7 @@ package gallery.memories import android.annotation.SuppressLint +import android.graphics.Color import android.net.Uri import android.os.Bundle import android.view.View @@ -38,6 +39,11 @@ import gallery.memories.databinding.ActivityMainBinding // Load JavaScript initializeWebView() + + // Destroy video after 1 seconds (workaround for video not showing on first load) + binding.videoView.postDelayed({ + binding.videoView.visibility = View.GONE + }, 1000) } override fun onDestroy() { @@ -99,8 +105,10 @@ import gallery.memories.databinding.ActivityMainBinding webSettings.userAgentString = "memories-native-android/0.0" binding.webview.clearCache(true) binding.webview.addJavascriptInterface(mNativeX, "nativex") - binding.webview.loadUrl("http://10.0.2.2:8035/index.php/apps/memories/") - binding.webview.setBackgroundColor(0x00000000) +// binding.webview.loadUrl("http://10.0.2.2:8035/index.php/apps/memories/") + binding.webview.loadUrl("https://uncanny-subdue.loca.lt/index.php/apps/memories/") + binding.webview.setBackgroundColor(Color.TRANSPARENT) + WebView.setWebContentsDebuggingEnabled(true); } fun initializePlayer(uri: Uri, uid: String) { @@ -129,15 +137,19 @@ import gallery.memories.databinding.ActivityMainBinding player = ExoPlayer.Builder(this) .build() .also { exoPlayer -> + // Bind to player view binding.videoView.player = exoPlayer binding.videoView.visibility = View.VISIBLE - val hlsMediaSource = HlsMediaSource.Factory(dataSourceFactory) - .createMediaSource(mediaItem); - exoPlayer.addMediaSource(hlsMediaSource) + // Check if HLS source from URI (contains .m3u8 anywhere) + if (uri.toString().contains(".m3u8")) { + exoPlayer.addMediaSource(HlsMediaSource.Factory(dataSourceFactory) + .createMediaSource(mediaItem)) + } else { + exoPlayer.setMediaItems(listOf(mediaItem), mediaItemIndex, playbackPosition) + } -// val mediaItem = MediaItem.fromUri(uri) -// exoPlayer.setMediaItems(listOf(mediaItem), mediaItemIndex, playbackPosition) + // Start the player exoPlayer.playWhenReady = playWhenReady exoPlayer.prepare() } diff --git a/app/src/main/java/gallery/memories/NativeX.kt b/app/src/main/java/gallery/memories/NativeX.kt index c3a01944..430282d5 100644 --- a/app/src/main/java/gallery/memories/NativeX.kt +++ b/app/src/main/java/gallery/memories/NativeX.kt @@ -84,14 +84,17 @@ import java.net.URLDecoder @JavascriptInterface fun setThemeColor(color: String?, isDark: Boolean) { - val window = mActivity.window - mActivity.setTheme(if (isDark) R.style.Theme_Black else R.style.Theme_Light) - window.navigationBarColor = Color.parseColor(color) - window.statusBarColor = Color.parseColor(color) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - window.insetsController?.setSystemBarsAppearance(if (isDark) 0 else WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS) - } else { - window.decorView.systemUiVisibility = if (isDark) 0 else View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR + mActivity.runOnUiThread { + val window = mActivity.window + mActivity.setTheme(if (isDark) R.style.Theme_Black else R.style.Theme_Light) + window.navigationBarColor = Color.parseColor(color) + window.statusBarColor = Color.parseColor(color) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val appearance = WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS or WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS + window.insetsController?.setSystemBarsAppearance(if (isDark) 0 else appearance, appearance) + } else { + window.decorView.systemUiVisibility = if (isDark) 0 else View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR + } } } diff --git a/app/src/main/java/gallery/memories/mapper/SystemImage.kt b/app/src/main/java/gallery/memories/mapper/SystemImage.kt index 78a9f703..616f9922 100644 --- a/app/src/main/java/gallery/memories/mapper/SystemImage.kt +++ b/app/src/main/java/gallery/memories/mapper/SystemImage.kt @@ -47,6 +47,7 @@ class SystemImage { MediaStore.Images.Media.HEIGHT, MediaStore.Images.Media.WIDTH, MediaStore.Images.Media.SIZE, + MediaStore.Images.Media.ORIENTATION, MediaStore.Images.Media.DATE_TAKEN, MediaStore.Images.Media.DATE_MODIFIED, MediaStore.Images.Media.DATA @@ -57,6 +58,18 @@ class SystemImage { projection.add(MediaStore.Video.Media.DURATION) } + // Get column indices + val idColumn = projection.indexOf(MediaStore.Images.Media._ID) + val nameColumn = projection.indexOf(MediaStore.Images.Media.DISPLAY_NAME) + val mimeColumn = projection.indexOf(MediaStore.Images.Media.MIME_TYPE) + val heightColumn = projection.indexOf(MediaStore.Images.Media.HEIGHT) + val widthColumn = projection.indexOf(MediaStore.Images.Media.WIDTH) + val sizeColumn = projection.indexOf(MediaStore.Images.Media.SIZE) + val orientationColumn = projection.indexOf(MediaStore.Images.Media.ORIENTATION) + val dateTakenColumn = projection.indexOf(MediaStore.Images.Media.DATE_TAKEN) + val dateModifiedColumn = projection.indexOf(MediaStore.Images.Media.DATE_MODIFIED) + val dataColumn = projection.indexOf(MediaStore.Images.Media.DATA) + // Query content resolver ctx.contentResolver.query( collection, @@ -69,21 +82,28 @@ class SystemImage { val image = SystemImage() // Common fields - image.fileId = cursor.getLong(0) - image.baseName = cursor.getString(1) - image.mimeType = cursor.getString(2) - image.height = cursor.getLong(3) - image.width = cursor.getLong(4) - image.size = cursor.getLong(5) - image.dateTaken = cursor.getLong(6) - image.mtime = cursor.getLong(7) - image.dataPath = cursor.getString(8) + image.fileId = cursor.getLong(idColumn) + image.baseName = cursor.getString(nameColumn) + image.mimeType = cursor.getString(mimeColumn) + image.height = cursor.getLong(heightColumn) + image.width = cursor.getLong(widthColumn) + image.size = cursor.getLong(sizeColumn) + image.dateTaken = cursor.getLong(dateTakenColumn) + image.mtime = cursor.getLong(dateModifiedColumn) + image.dataPath = cursor.getString(dataColumn) image.mCollection = collection + // Swap width/height if orientation is 90 or 270 + val orientation = cursor.getInt(orientationColumn) + if (orientation == 90 || orientation == 270) { + image.width = image.height.also { image.height = image.width } + } + // Video specific fields image.isVideo = collection == VIDEO_URI if (image.isVideo) { - image.videoDuration = cursor.getLong(9) + val durationColumn = projection.indexOf(MediaStore.Video.Media.DURATION) + image.videoDuration = cursor.getLong(durationColumn) } // Add to main list diff --git a/app/src/main/java/gallery/memories/service/ImageService.kt b/app/src/main/java/gallery/memories/service/ImageService.kt index d0d01a7c..93d9e569 100644 --- a/app/src/main/java/gallery/memories/service/ImageService.kt +++ b/app/src/main/java/gallery/memories/service/ImageService.kt @@ -3,6 +3,8 @@ package gallery.memories.service import android.content.ContentUris import android.content.Context import android.graphics.Bitmap +import android.graphics.ImageDecoder +import android.os.Build import android.provider.MediaStore import java.io.ByteArrayOutputStream @@ -10,11 +12,21 @@ class ImageService(private val mCtx: Context) { @Throws(Exception::class) fun getPreview(id: Long): ByteArray { val bitmap = - MediaStore.Images.Thumbnails.getThumbnail( - mCtx.contentResolver, id, MediaStore.Images.Thumbnails.FULL_SCREEN_KIND, null) - ?: MediaStore.Video.Thumbnails.getThumbnail( - mCtx.contentResolver, id, MediaStore.Video.Thumbnails.FULL_SCREEN_KIND, null) - ?: throw Exception("Thumbnail not found") + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + mCtx.contentResolver.loadThumbnail( + ContentUris.withAppendedId(MediaStore.Files.getContentUri("external"), id), + android.util.Size(2048, 2048), + null + ) + } else { + MediaStore.Images.Thumbnails.getThumbnail( + mCtx.contentResolver, id, MediaStore.Images.Thumbnails.FULL_SCREEN_KIND, null + ) + ?: MediaStore.Video.Thumbnails.getThumbnail( + mCtx.contentResolver, id, MediaStore.Video.Thumbnails.FULL_SCREEN_KIND, null + ) + ?: throw Exception("Thumbnail not found") + } val stream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream) @@ -23,11 +35,15 @@ class ImageService(private val mCtx: Context) { @Throws(Exception::class) fun getFull(id: Long): ByteArray { - val bitmap = MediaStore.Images.Media.getBitmap( - mCtx.contentResolver, ContentUris.withAppendedId( - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)) - ?: throw Exception("Image not found") + val uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id) + val bitmap = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + ImageDecoder.decodeBitmap(ImageDecoder.createSource(mCtx.contentResolver, uri)) + } else { + MediaStore.Images.Media.getBitmap(mCtx.contentResolver, uri) + ?: throw Exception("Image not found") + } val stream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream) return stream.toByteArray() diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 5f2a4f07..4a29b5ec 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -11,7 +11,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/black" - android:visibility="gone" />