Multiple fixes
parent
d7b550e85a
commit
4205a65b87
|
@ -1,6 +1,7 @@
|
||||||
package gallery.memories
|
package gallery.memories
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.graphics.Color
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -38,6 +39,11 @@ import gallery.memories.databinding.ActivityMainBinding
|
||||||
|
|
||||||
// Load JavaScript
|
// Load JavaScript
|
||||||
initializeWebView()
|
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() {
|
override fun onDestroy() {
|
||||||
|
@ -99,8 +105,10 @@ import gallery.memories.databinding.ActivityMainBinding
|
||||||
webSettings.userAgentString = "memories-native-android/0.0"
|
webSettings.userAgentString = "memories-native-android/0.0"
|
||||||
binding.webview.clearCache(true)
|
binding.webview.clearCache(true)
|
||||||
binding.webview.addJavascriptInterface(mNativeX, "nativex")
|
binding.webview.addJavascriptInterface(mNativeX, "nativex")
|
||||||
binding.webview.loadUrl("http://10.0.2.2:8035/index.php/apps/memories/")
|
// binding.webview.loadUrl("http://10.0.2.2:8035/index.php/apps/memories/")
|
||||||
binding.webview.setBackgroundColor(0x00000000)
|
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) {
|
fun initializePlayer(uri: Uri, uid: String) {
|
||||||
|
@ -129,15 +137,19 @@ import gallery.memories.databinding.ActivityMainBinding
|
||||||
player = ExoPlayer.Builder(this)
|
player = ExoPlayer.Builder(this)
|
||||||
.build()
|
.build()
|
||||||
.also { exoPlayer ->
|
.also { exoPlayer ->
|
||||||
|
// Bind to player view
|
||||||
binding.videoView.player = exoPlayer
|
binding.videoView.player = exoPlayer
|
||||||
binding.videoView.visibility = View.VISIBLE
|
binding.videoView.visibility = View.VISIBLE
|
||||||
|
|
||||||
val hlsMediaSource = HlsMediaSource.Factory(dataSourceFactory)
|
// Check if HLS source from URI (contains .m3u8 anywhere)
|
||||||
.createMediaSource(mediaItem);
|
if (uri.toString().contains(".m3u8")) {
|
||||||
exoPlayer.addMediaSource(hlsMediaSource)
|
exoPlayer.addMediaSource(HlsMediaSource.Factory(dataSourceFactory)
|
||||||
|
.createMediaSource(mediaItem))
|
||||||
|
} else {
|
||||||
|
exoPlayer.setMediaItems(listOf(mediaItem), mediaItemIndex, playbackPosition)
|
||||||
|
}
|
||||||
|
|
||||||
// val mediaItem = MediaItem.fromUri(uri)
|
// Start the player
|
||||||
// exoPlayer.setMediaItems(listOf(mediaItem), mediaItemIndex, playbackPosition)
|
|
||||||
exoPlayer.playWhenReady = playWhenReady
|
exoPlayer.playWhenReady = playWhenReady
|
||||||
exoPlayer.prepare()
|
exoPlayer.prepare()
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,14 +84,17 @@ import java.net.URLDecoder
|
||||||
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
fun setThemeColor(color: String?, isDark: Boolean) {
|
fun setThemeColor(color: String?, isDark: Boolean) {
|
||||||
|
mActivity.runOnUiThread {
|
||||||
val window = mActivity.window
|
val window = mActivity.window
|
||||||
mActivity.setTheme(if (isDark) R.style.Theme_Black else R.style.Theme_Light)
|
mActivity.setTheme(if (isDark) R.style.Theme_Black else R.style.Theme_Light)
|
||||||
window.navigationBarColor = Color.parseColor(color)
|
window.navigationBarColor = Color.parseColor(color)
|
||||||
window.statusBarColor = Color.parseColor(color)
|
window.statusBarColor = Color.parseColor(color)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
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)
|
val appearance = WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS or WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
|
||||||
|
window.insetsController?.setSystemBarsAppearance(if (isDark) 0 else appearance, appearance)
|
||||||
} else {
|
} else {
|
||||||
window.decorView.systemUiVisibility = if (isDark) 0 else View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
window.decorView.systemUiVisibility = if (isDark) 0 else View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ class SystemImage {
|
||||||
MediaStore.Images.Media.HEIGHT,
|
MediaStore.Images.Media.HEIGHT,
|
||||||
MediaStore.Images.Media.WIDTH,
|
MediaStore.Images.Media.WIDTH,
|
||||||
MediaStore.Images.Media.SIZE,
|
MediaStore.Images.Media.SIZE,
|
||||||
|
MediaStore.Images.Media.ORIENTATION,
|
||||||
MediaStore.Images.Media.DATE_TAKEN,
|
MediaStore.Images.Media.DATE_TAKEN,
|
||||||
MediaStore.Images.Media.DATE_MODIFIED,
|
MediaStore.Images.Media.DATE_MODIFIED,
|
||||||
MediaStore.Images.Media.DATA
|
MediaStore.Images.Media.DATA
|
||||||
|
@ -57,6 +58,18 @@ class SystemImage {
|
||||||
projection.add(MediaStore.Video.Media.DURATION)
|
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
|
// Query content resolver
|
||||||
ctx.contentResolver.query(
|
ctx.contentResolver.query(
|
||||||
collection,
|
collection,
|
||||||
|
@ -69,21 +82,28 @@ class SystemImage {
|
||||||
val image = SystemImage()
|
val image = SystemImage()
|
||||||
|
|
||||||
// Common fields
|
// Common fields
|
||||||
image.fileId = cursor.getLong(0)
|
image.fileId = cursor.getLong(idColumn)
|
||||||
image.baseName = cursor.getString(1)
|
image.baseName = cursor.getString(nameColumn)
|
||||||
image.mimeType = cursor.getString(2)
|
image.mimeType = cursor.getString(mimeColumn)
|
||||||
image.height = cursor.getLong(3)
|
image.height = cursor.getLong(heightColumn)
|
||||||
image.width = cursor.getLong(4)
|
image.width = cursor.getLong(widthColumn)
|
||||||
image.size = cursor.getLong(5)
|
image.size = cursor.getLong(sizeColumn)
|
||||||
image.dateTaken = cursor.getLong(6)
|
image.dateTaken = cursor.getLong(dateTakenColumn)
|
||||||
image.mtime = cursor.getLong(7)
|
image.mtime = cursor.getLong(dateModifiedColumn)
|
||||||
image.dataPath = cursor.getString(8)
|
image.dataPath = cursor.getString(dataColumn)
|
||||||
image.mCollection = collection
|
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
|
// Video specific fields
|
||||||
image.isVideo = collection == VIDEO_URI
|
image.isVideo = collection == VIDEO_URI
|
||||||
if (image.isVideo) {
|
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
|
// Add to main list
|
||||||
|
|
|
@ -3,6 +3,8 @@ package gallery.memories.service
|
||||||
import android.content.ContentUris
|
import android.content.ContentUris
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.ImageDecoder
|
||||||
|
import android.os.Build
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
|
@ -10,11 +12,21 @@ class ImageService(private val mCtx: Context) {
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun getPreview(id: Long): ByteArray {
|
fun getPreview(id: Long): ByteArray {
|
||||||
val bitmap =
|
val bitmap =
|
||||||
|
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(
|
MediaStore.Images.Thumbnails.getThumbnail(
|
||||||
mCtx.contentResolver, id, MediaStore.Images.Thumbnails.FULL_SCREEN_KIND, null)
|
mCtx.contentResolver, id, MediaStore.Images.Thumbnails.FULL_SCREEN_KIND, null
|
||||||
|
)
|
||||||
?: MediaStore.Video.Thumbnails.getThumbnail(
|
?: MediaStore.Video.Thumbnails.getThumbnail(
|
||||||
mCtx.contentResolver, id, MediaStore.Video.Thumbnails.FULL_SCREEN_KIND, null)
|
mCtx.contentResolver, id, MediaStore.Video.Thumbnails.FULL_SCREEN_KIND, null
|
||||||
|
)
|
||||||
?: throw Exception("Thumbnail not found")
|
?: throw Exception("Thumbnail not found")
|
||||||
|
}
|
||||||
|
|
||||||
val stream = ByteArrayOutputStream()
|
val stream = ByteArrayOutputStream()
|
||||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream)
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream)
|
||||||
|
@ -23,11 +35,15 @@ class ImageService(private val mCtx: Context) {
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun getFull(id: Long): ByteArray {
|
fun getFull(id: Long): ByteArray {
|
||||||
val bitmap = MediaStore.Images.Media.getBitmap(
|
val uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)
|
||||||
mCtx.contentResolver, ContentUris.withAppendedId(
|
|
||||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id))
|
|
||||||
?: throw Exception("Image not found")
|
|
||||||
|
|
||||||
|
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()
|
val stream = ByteArrayOutputStream()
|
||||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream)
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream)
|
||||||
return stream.toByteArray()
|
return stream.toByteArray()
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@android:color/black"
|
android:background="@android:color/black"
|
||||||
android:visibility="gone"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<WebView
|
<WebView
|
||||||
|
|
Loading…
Reference in New Issue