Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Source/GUI/Android/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ set(BUILD_SHARED_LIBS ON CACHE BOOL "Force shared library build" FORCE)
set(LARGE_FILES OFF CACHE BOOL "Enable large files support" FORCE)
set(BUILD_ZENLIB ON CACHE BOOL "Build bundled ZenLib" FORCE)

find_package(curl REQUIRED CONFIG)

add_subdirectory(../../../../../MediaInfoLib/Project/CMake ${CMAKE_CURRENT_BINARY_DIR}/MediaInfoLib)

target_link_options(mediainfo
Expand Down
27 changes: 14 additions & 13 deletions Source/GUI/Android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ android {
defaultConfig {
applicationId "net.mediaarea.mediainfo"
multiDexEnabled = true
minSdkVersion 21
minSdkVersion 23
versionCode 59
versionName "26.05"
targetSdkVersion 37
Expand All @@ -32,20 +32,18 @@ android {
"-DMEDIAINFO_DUPLICATE=OFF",
"-DMEDIAINFO_DVDIF_ANALYZE=OFF",
"-DMEDIAINFO_EVENTS=OFF",
"-DMEDIAINFO_FILE=OFF",
"-DMEDIAINFO_FILTER=OFF",
"-DMEDIAINFO_FIXITY=OFF",
"-DMEDIAINFO_GRAPH=OFF",
"-DMEDIAINFO_IBI=OFF",
"-DMEDIAINFO_LIBCURL=OFF",
"-DMEDIAINFO_LIBMMS=OFF",
"-DMEDIAINFO_MACROBLOCKS=OFF",
"-DMEDIAINFO_MD5=OFF",
"-DMEDIAINFO_NEXTPACKET=OFF",
"-DMEDIAINFO_READER=OFF",
"-DMEDIAINFO_READTHREAD=OFF",
"-DMEDIAINFO_REFERENCES=OFF",
"-DMEDIAINFO_SHA1=OFF",
"-DMEDIAINFO_SHA2=OFF",
"-DMEDIAINFO_TRACE=OFF",
"-DMEDIAINFO_TRACE_FFV1CONTENT=OFF"
}
Expand Down Expand Up @@ -77,6 +75,9 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
buildFeatures {
prefab = true
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
Expand Down Expand Up @@ -202,9 +203,9 @@ tasks.register('copyLocales', DefaultTask) {
preBuild.dependsOn copyLocales

dependencies {
implementation 'com.google.android.material:material:1.13.0' // can only upgrade when minSdkVersion >= 23
implementation 'com.google.android.material:material:1.14.0'
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation "androidx.core:core-ktx:1.17.0" // can only upgrade when minSdkVersion >= 23
implementation "androidx.core:core-ktx:1.18.0"
implementation 'androidx.documentfile:documentfile:1.1.0'
implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
Expand All @@ -213,19 +214,19 @@ dependencies {
androidTestImplementation 'androidx.test:runner:1.7.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0'
// Android Room
// can only upgrade when minSdkVersion >= 23
implementation 'androidx.room:room-runtime:2.7.2'
implementation 'androidx.room:room-ktx:2.7.2'
ksp 'androidx.room:room-compiler:2.7.2'
implementation 'androidx.room:room-runtime:2.8.4'
implementation 'androidx.room:room-ktx:2.8.4'
ksp 'androidx.room:room-compiler:2.8.4'
// Android Lifecycle
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
ksp "androidx.lifecycle:lifecycle-common-java8:2.10.0"
// Google Billing
// can only upgrade when minSdkVersion >= 23
implementation "com.android.billingclient:billing:8.0.0"
implementation "com.android.billingclient:billing-ktx:8.0.0"
implementation "com.android.billingclient:billing:9.0.0"
implementation "com.android.billingclient:billing-ktx:9.0.0"
// KotlinX Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.11.0"
// Locales manager
implementation 'com.github.YarikSOffice:lingver:1.3.0'
// Curl static build from https://github.com/vvb2060/curl-android
implementation "io.github.vvb2060.ndk:curl:8.18.0"
}
2 changes: 2 additions & 0 deletions Source/GUI/Android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="20" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />

<application
android:name=".MediaInfoApplication"
Expand Down Expand Up @@ -88,6 +89,7 @@
<data android:mimeType="audio/*" />
<data android:mimeType="image/*" />
<data android:mimeType="video/*" />
<data android:mimeType="text/plain" />
<data android:mimeType="application/acad" />
<data android:mimeType="application/dash+xml" />
<data android:mimeType="application/dwg" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

package net.mediaarea.mediainfo

import android.net.Uri

object Core {
data class ReportView(val name: String, val desc: String, val mime: String, val exportable: Boolean) {
override fun toString(): String {
Expand Down Expand Up @@ -47,6 +49,21 @@ object Core {
return report.toByteArray()
}

@Synchronized
fun createReport(networkUri: Uri): ByteArray {
mi.Option("Language", "")
mi.Option("Inform", "MIXML")
mi.Option("Input_Compressed", "")
mi.Option("Inform_Compress", "zlib+base64")
mi.Option("File_FileName") // Reset filename so that MediaInfoLib does not use previous filename

mi.Open(networkUri.toString())
val report: String = mi.Inform()
mi.Close()

return report.toByteArray()
}

@Synchronized
fun convertReport(report: ByteArray, format: String, export: Boolean = false) : String {
mi.Option("Inform", format)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class MediaInfo {
external fun Init(): Long
external fun Destroy(): Int
private external fun OpenFd(fd: Int, name: String): Int
private external fun Open(name:String ): Int
external fun Open(name:String): Int
fun Open(fd: Int, name: String): Int {
return OpenFd(fd, name)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

package net.mediaarea.mediainfo

import kotlin.jvm.*
import kotlin.math.abs
import kotlinx.coroutines.launch

import androidx.activity.result.contract.ActivityResultContracts
Expand All @@ -27,9 +27,11 @@ import androidx.lifecycle.repeatOnLifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.listitem.ListItemViewHolder

import android.os.Build
import android.os.Bundle
Expand All @@ -43,12 +45,16 @@ import android.content.pm.PackageManager
import android.content.res.Configuration
import android.content.res.Resources
import android.provider.Settings
import android.view.*
import android.util.Patterns
import android.view.Menu
import android.view.View
import android.view.ViewConfiguration
import android.view.ViewGroup

import com.yariksoffice.lingver.Lingver
import kotlinx.coroutines.flow.collectLatest
import java.io.BufferedReader
import java.util.*
import java.util.Locale

import net.mediaarea.mediainfo.databinding.ActivityReportListBinding
import net.mediaarea.mediainfo.databinding.ClearButtonBinding
Expand Down Expand Up @@ -169,14 +175,12 @@ class ReportListActivity : AppCompatActivity(), ReportActivityListener {
private fun handleUri(uri: Uri, isMultiple: Boolean = false) {
when (uri.scheme) {
"file" -> {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
pendingFileUris.add(uri)
ActivityCompat.requestPermissions(this@ReportListActivity,
arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE),
READ_EXTERNAL_STORAGE_PERMISSION_REQUEST)
return
}
if (checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
pendingFileUris.add(uri)
ActivityCompat.requestPermissions(this@ReportListActivity,
arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE),
READ_EXTERNAL_STORAGE_PERMISSION_REQUEST)
return
}
}
"content" -> {
Expand Down Expand Up @@ -234,7 +238,15 @@ class ReportListActivity : AppCompatActivity(), ReportActivityListener {
}
Intent.ACTION_SEND -> {
val uri =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (intent.type == "text/plain") {
intent.getStringExtra(Intent.EXTRA_TEXT)?.let { text ->
val matcher = Patterns.WEB_URL.matcher(text)
if (matcher.find())
matcher.group().toUri()
else
null
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
} else {
@Suppress("DEPRECATION")
Expand Down Expand Up @@ -708,6 +720,25 @@ class ReportListActivity : AppCompatActivity(), ReportActivityListener {

private fun setupRecyclerView(recyclerView: RecyclerView) {
recyclerView.adapter = ItemRecyclerViewAdapter()
val layoutManager = recyclerView.layoutManager as? LinearLayoutManager
val extFab = activityReportListBinding.addButton
val scaledTouchSlop = ViewConfiguration.get(recyclerView.context).scaledTouchSlop

recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)

if (abs(dy) <= scaledTouchSlop) {
if (!extFab.isExtended && layoutManager?.findFirstCompletelyVisibleItemPosition() == 0)
extFab.extend()
return
}
if (dy > 0 && extFab.isExtended)
extFab.shrink()
else if (dy < 0 && !extFab.isExtended)
extFab.extend()
}
})
}

sealed class ReportListItem {
Expand Down Expand Up @@ -794,6 +825,7 @@ class ReportListActivity : AppCompatActivity(), ReportActivityListener {
is ReportListItem.ReportData -> {
if (holder is ListViewHolder) {
val report: Report = item.report
holder.bind(position, currentList.size - 1) // Last is button
holder.name.text = report.filename
holder.id = report.id
with(holder.itemView) {
Expand All @@ -805,6 +837,7 @@ class ReportListActivity : AppCompatActivity(), ReportActivityListener {
}
is ReportListItem.ClearButton -> {
if (holder is ButtonViewHolder) {
holder.bind(0, 1)
with(holder.itemView) {
setOnClickListener {
reportModel.deleteAllReports()
Expand All @@ -828,7 +861,7 @@ class ReportListActivity : AppCompatActivity(), ReportActivityListener {
}
}

inner class ListViewHolder(binding: ReportListContentBinding) : RecyclerView.ViewHolder(binding.root) {
inner class ListViewHolder(binding: ReportListContentBinding) : ListItemViewHolder(binding.root) {
val name: TextView = binding.nameText
var id: Int = -1

Expand All @@ -840,7 +873,7 @@ class ReportListActivity : AppCompatActivity(), ReportActivityListener {
}
}

inner class ButtonViewHolder(val binding: ClearButtonBinding) : RecyclerView.ViewHolder(binding.root)
inner class ButtonViewHolder(val binding: ClearButtonBinding) : ListItemViewHolder(binding.root)
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class ReportViewModel(private val dataSource: ReportDao) : ViewModel() {
for (uri in uris) {
var fd: ParcelFileDescriptor? = null
var displayName = ""
var isUrl = false

when (uri.scheme) {
"content" -> {
Expand Down Expand Up @@ -94,17 +95,23 @@ class ReportViewModel(private val dataSource: ReportDao) : ViewModel() {

displayName = uri.lastPathSegment.orEmpty()
}

"http", "https", "ftp", "sftp" -> {
isUrl = true
displayName = uri.lastPathSegment.orEmpty()
}
}

if (fd == null) {
if (fd == null && !isUrl) {
continue
}

fd.use {
val report: ByteArray = Core.createReport(it.detachFd(), displayName)
lastInsertedId =
insertReport(Report(0, displayName, report, Core.version)).toInt()
}
val report: ByteArray =
fd?.use { Core.createReport(it.detachFd(), displayName) }
?: Core.createReport(uri)

lastInsertedId =
insertReport(Report(0, displayName, report, Core.version)).toInt()
}

// Don't go to report view when opening multiple files
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorSecondaryContainer" android:state_activated="true" />
<item android:color="?attr/colorSurfaceBright" />
</selector>
8 changes: 3 additions & 5 deletions Source/GUI/Android/app/src/main/res/layout/activity_about.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".AboutActivity">

<com.google.android.material.appbar.AppBarLayout
android:background="?attr/colorSurfaceContainer"
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
app:liftOnScroll="true">

<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
Expand All @@ -29,7 +27,7 @@

</com.google.android.material.appbar.AppBarLayout>

<ScrollView
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
Expand Down Expand Up @@ -112,6 +110,6 @@

</androidx.constraintlayout.widget.ConstraintLayout>

</ScrollView>
</androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
</com.google.android.material.appbar.AppBarLayout>

<FrameLayout
android:background="?attr/colorSurfaceContainer"
android:id="@+id/frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
Expand All @@ -41,14 +42,15 @@
android:layout_gravity="bottom|start"
app:layout_anchor="@+id/report_list"
app:layout_anchorGravity="bottom|end">
<com.google.android.material.floatingactionbutton.FloatingActionButton
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/button_margin"
android:contentDescription="@string/open_title"
app:srcCompat="@drawable/ic_action_add" />
android:text="@string/open_title"
app:icon="@drawable/ic_action_add" />
</FrameLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
Loading
Loading