removed pre-kitkat code

This commit is contained in:
Thibault Deckers 2023-05-08 00:00:38 +02:00
parent 9d08e88b1a
commit ef2d0eefb0
13 changed files with 58 additions and 99 deletions

View file

@ -142,6 +142,7 @@ open class MainActivity : FlutterFragmentActivity() {
result.success(intentDataMap) result.success(intentDataMap)
intentDataMap.clear() intentDataMap.clear()
} }
"submitPickedItems" -> submitPickedItems(call) "submitPickedItems" -> submitPickedItems(call)
"submitPickedCollectionFilters" -> submitPickedCollectionFilters(call) "submitPickedCollectionFilters" -> submitPickedCollectionFilters(call)
} }
@ -204,8 +205,10 @@ open class MainActivity : FlutterFragmentActivity() {
DOCUMENT_TREE_ACCESS_REQUEST -> onDocumentTreeAccessResult(requestCode, resultCode, data) DOCUMENT_TREE_ACCESS_REQUEST -> onDocumentTreeAccessResult(requestCode, resultCode, data)
DELETE_SINGLE_PERMISSION_REQUEST, DELETE_SINGLE_PERMISSION_REQUEST,
MEDIA_WRITE_BULK_PERMISSION_REQUEST -> onScopedStoragePermissionResult(resultCode) MEDIA_WRITE_BULK_PERMISSION_REQUEST -> onScopedStoragePermissionResult(resultCode)
CREATE_FILE_REQUEST, CREATE_FILE_REQUEST,
OPEN_FILE_REQUEST -> onStorageAccessResult(requestCode, data?.data) OPEN_FILE_REQUEST -> onStorageAccessResult(requestCode, data?.data)
PICK_COLLECTION_FILTERS_REQUEST -> onCollectionFiltersPickResult(resultCode, data) PICK_COLLECTION_FILTERS_REQUEST -> onCollectionFiltersPickResult(resultCode, data)
} }
} }
@ -222,9 +225,8 @@ open class MainActivity : FlutterFragmentActivity() {
return return
} }
@SuppressLint("WrongConstant", "ObsoleteSdkInt")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val canPersist = (intent.flags and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0 val canPersist = (intent.flags and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0
@SuppressLint("WrongConstant")
if (canPersist) { if (canPersist) {
// save access permissions across reboots // save access permissions across reboots
val takeFlags = (intent.flags val takeFlags = (intent.flags
@ -236,7 +238,6 @@ open class MainActivity : FlutterFragmentActivity() {
Log.w(LOG_TAG, "failed to take persistable URI permission for uri=$treeUri", e) Log.w(LOG_TAG, "failed to take persistable URI permission for uri=$treeUri", e)
} }
} }
}
// resume pending action // resume pending action
onStorageAccessResult(requestCode, treeUri) onStorageAccessResult(requestCode, treeUri)
@ -264,6 +265,7 @@ open class MainActivity : FlutterFragmentActivity() {
) )
} }
} }
Intent.ACTION_VIEW, Intent.ACTION_SEND, "com.android.camera.action.REVIEW" -> { Intent.ACTION_VIEW, Intent.ACTION_SEND, "com.android.camera.action.REVIEW" -> {
(intent.data ?: intent.getParcelableExtraCompat<Uri>(Intent.EXTRA_STREAM))?.let { uri -> (intent.data ?: intent.getParcelableExtraCompat<Uri>(Intent.EXTRA_STREAM))?.let { uri ->
// MIME type is optional // MIME type is optional
@ -275,6 +277,7 @@ open class MainActivity : FlutterFragmentActivity() {
) )
} }
} }
Intent.ACTION_GET_CONTENT, Intent.ACTION_PICK -> { Intent.ACTION_GET_CONTENT, Intent.ACTION_PICK -> {
return hashMapOf( return hashMapOf(
INTENT_DATA_KEY_ACTION to INTENT_ACTION_PICK_ITEMS, INTENT_DATA_KEY_ACTION to INTENT_ACTION_PICK_ITEMS,
@ -282,6 +285,7 @@ open class MainActivity : FlutterFragmentActivity() {
INTENT_DATA_KEY_ALLOW_MULTIPLE to (intent.extras?.getBoolean(Intent.EXTRA_ALLOW_MULTIPLE) ?: false), INTENT_DATA_KEY_ALLOW_MULTIPLE to (intent.extras?.getBoolean(Intent.EXTRA_ALLOW_MULTIPLE) ?: false),
) )
} }
Intent.ACTION_SEARCH -> { Intent.ACTION_SEARCH -> {
val viewUri = intent.dataString val viewUri = intent.dataString
return if (viewUri != null) hashMapOf( return if (viewUri != null) hashMapOf(
@ -293,6 +297,7 @@ open class MainActivity : FlutterFragmentActivity() {
INTENT_DATA_KEY_QUERY to intent.getStringExtra(SearchManager.QUERY), INTENT_DATA_KEY_QUERY to intent.getStringExtra(SearchManager.QUERY),
) )
} }
INTENT_ACTION_PICK_COLLECTION_FILTERS -> { INTENT_ACTION_PICK_COLLECTION_FILTERS -> {
val initialFilters = extractFiltersFromIntent(intent) val initialFilters = extractFiltersFromIntent(intent)
return hashMapOf( return hashMapOf(
@ -300,6 +305,7 @@ open class MainActivity : FlutterFragmentActivity() {
INTENT_DATA_KEY_FILTERS to initialFilters, INTENT_DATA_KEY_FILTERS to initialFilters,
) )
} }
INTENT_ACTION_WIDGET_OPEN -> { INTENT_ACTION_WIDGET_OPEN -> {
val widgetId = intent.getIntExtra(EXTRA_KEY_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID) val widgetId = intent.getIntExtra(EXTRA_KEY_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) { if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
@ -309,9 +315,11 @@ open class MainActivity : FlutterFragmentActivity() {
) )
} }
} }
Intent.ACTION_RUN -> { Intent.ACTION_RUN -> {
// flutter run // flutter run
} }
else -> { else -> {
Log.w(LOG_TAG, "unhandled intent action=${intent?.action}") Log.w(LOG_TAG, "unhandled intent action=${intent?.action}")
} }

View file

@ -1,6 +1,5 @@
package deckers.thibault.aves.channel.calls package deckers.thibault.aves.channel.calls
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.ContextWrapper import android.content.ContextWrapper
import android.content.res.Configuration import android.content.res.Configuration
@ -27,14 +26,11 @@ class AccessibilityHandler(private val contextWrapper: ContextWrapper) : MethodC
private fun areAnimationsRemoved(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) { private fun areAnimationsRemoved(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
var removed = false var removed = false
@SuppressLint("ObsoleteSdkInt")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
try { try {
removed = Settings.Global.getFloat(contextWrapper.contentResolver, Settings.Global.TRANSITION_ANIMATION_SCALE) == 0f removed = Settings.Global.getFloat(contextWrapper.contentResolver, Settings.Global.TRANSITION_ANIMATION_SCALE) == 0f
} catch (e: Exception) { } catch (e: Exception) {
Log.w(LOG_TAG, "failed to get settings with error=${e.message}", null) Log.w(LOG_TAG, "failed to get settings with error=${e.message}", null)
} }
}
result.success(removed) result.success(removed)
} }

View file

@ -1,6 +1,5 @@
package deckers.thibault.aves.channel.calls package deckers.thibault.aves.channel.calls
import android.annotation.SuppressLint
import android.content.* import android.content.*
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.res.Configuration import android.content.res.Configuration
@ -69,13 +68,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler {
// apps tend to use their name in English when creating directories // apps tend to use their name in English when creating directories
// so we get their names in English as well as the current locale // so we get their names in English as well as the current locale
val englishConfig = Configuration().apply { val englishConfig = Configuration().apply {
@SuppressLint("ObsoleteSdkInt")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
setLocale(Locale.ENGLISH) setLocale(Locale.ENGLISH)
} else {
@Suppress("deprecation")
locale = Locale.ENGLISH
}
} }
val pm = context.packageManager val pm = context.packageManager

View file

@ -40,7 +40,6 @@ class DeviceHandler(private val context: Context) : MethodCallHandler {
hashMapOf( hashMapOf(
"canGrantDirectoryAccess" to (sdkInt >= Build.VERSION_CODES.LOLLIPOP), "canGrantDirectoryAccess" to (sdkInt >= Build.VERSION_CODES.LOLLIPOP),
"canPinShortcut" to ShortcutManagerCompat.isRequestPinShortcutSupported(context), "canPinShortcut" to ShortcutManagerCompat.isRequestPinShortcutSupported(context),
"canPrint" to (sdkInt >= Build.VERSION_CODES.KITKAT),
"canRenderFlagEmojis" to (sdkInt >= Build.VERSION_CODES.M), "canRenderFlagEmojis" to (sdkInt >= Build.VERSION_CODES.M),
"canRenderSubdivisionFlagEmojis" to (sdkInt >= Build.VERSION_CODES.O), "canRenderSubdivisionFlagEmojis" to (sdkInt >= Build.VERSION_CODES.O),
"canRequestManageMedia" to (sdkInt >= Build.VERSION_CODES.S), "canRequestManageMedia" to (sdkInt >= Build.VERSION_CODES.S),

View file

@ -1,6 +1,5 @@
package deckers.thibault.aves.channel.calls package deckers.thibault.aves.channel.calls
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
import android.net.Uri import android.net.Uri
@ -28,20 +27,30 @@ import com.drew.metadata.png.PngDirectory
import com.drew.metadata.webp.WebpDirectory import com.drew.metadata.webp.WebpDirectory
import com.drew.metadata.xmp.XmpDirectory import com.drew.metadata.xmp.XmpDirectory
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import deckers.thibault.aves.metadata.* import deckers.thibault.aves.metadata.ExifGeoTiffTags
import deckers.thibault.aves.metadata.ExifInterfaceHelper.describeAll import deckers.thibault.aves.metadata.ExifInterfaceHelper.describeAll
import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeDateMillis import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeDateMillis
import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeDouble import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeDouble
import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeInt import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeInt
import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeRational import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeRational
import deckers.thibault.aves.metadata.ExifTags
import deckers.thibault.aves.metadata.GSpherical
import deckers.thibault.aves.metadata.GeoTiffKeys
import deckers.thibault.aves.metadata.MediaMetadataRetrieverHelper
import deckers.thibault.aves.metadata.MediaMetadataRetrieverHelper.getSafeDateMillis import deckers.thibault.aves.metadata.MediaMetadataRetrieverHelper.getSafeDateMillis
import deckers.thibault.aves.metadata.MediaMetadataRetrieverHelper.getSafeDescription import deckers.thibault.aves.metadata.MediaMetadataRetrieverHelper.getSafeDescription
import deckers.thibault.aves.metadata.MediaMetadataRetrieverHelper.getSafeInt import deckers.thibault.aves.metadata.MediaMetadataRetrieverHelper.getSafeInt
import deckers.thibault.aves.metadata.Metadata
import deckers.thibault.aves.metadata.Metadata.DIR_DNG import deckers.thibault.aves.metadata.Metadata.DIR_DNG
import deckers.thibault.aves.metadata.Metadata.DIR_EXIF_GEOTIFF import deckers.thibault.aves.metadata.Metadata.DIR_EXIF_GEOTIFF
import deckers.thibault.aves.metadata.Metadata.DIR_PNG_TEXTUAL_DATA import deckers.thibault.aves.metadata.Metadata.DIR_PNG_TEXTUAL_DATA
import deckers.thibault.aves.metadata.Metadata.getRotationDegreesForExifCode import deckers.thibault.aves.metadata.Metadata.getRotationDegreesForExifCode
import deckers.thibault.aves.metadata.Metadata.isFlippedForExifCode import deckers.thibault.aves.metadata.Metadata.isFlippedForExifCode
import deckers.thibault.aves.metadata.Mp4ParserHelper
import deckers.thibault.aves.metadata.MultiPage
import deckers.thibault.aves.metadata.PixyMetaHelper
import deckers.thibault.aves.metadata.QuickTimeMetadata
import deckers.thibault.aves.metadata.XMP
import deckers.thibault.aves.metadata.XMP.doesPropExist import deckers.thibault.aves.metadata.XMP.doesPropExist
import deckers.thibault.aves.metadata.XMP.getPropArrayItemValues import deckers.thibault.aves.metadata.XMP.getPropArrayItemValues
import deckers.thibault.aves.metadata.XMP.getSafeDateMillis import deckers.thibault.aves.metadata.XMP.getSafeDateMillis
@ -84,7 +93,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.json.JSONObject import org.json.JSONObject
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.text.DecimalFormat import java.text.DecimalFormat
import java.text.ParseException import java.text.ParseException
@ -305,12 +313,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
val key = kv.key val key = kv.key
// `PNG-iTXt` uses UTF-8, contrary to `PNG-tEXt` and `PNG-zTXt` using Latin-1 / ISO-8859-1 // `PNG-iTXt` uses UTF-8, contrary to `PNG-tEXt` and `PNG-zTXt` using Latin-1 / ISO-8859-1
val charset = if (baseDirName == PNG_ITXT_DIR_NAME) { val charset = if (baseDirName == PNG_ITXT_DIR_NAME) {
@SuppressLint("ObsoleteSdkInt")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
StandardCharsets.UTF_8 StandardCharsets.UTF_8
} else {
Charset.forName("UTF-8")
}
} else { } else {
kv.value.charset kv.value.charset
} }
@ -747,10 +750,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
var flags = (metadataMap[KEY_FLAGS] ?: 0) as Int var flags = (metadataMap[KEY_FLAGS] ?: 0) as Int
try { try {
@SuppressLint("ObsoleteSdkInt")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
retriever.getSafeInt(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) { metadataMap[KEY_ROTATION_DEGREES] = it } retriever.getSafeInt(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) { metadataMap[KEY_ROTATION_DEGREES] = it }
}
if (!metadataMap.containsKey(KEY_DATE_MILLIS)) { if (!metadataMap.containsKey(KEY_DATE_MILLIS)) {
retriever.getSafeDateMillis(MediaMetadataRetriever.METADATA_KEY_DATE) { metadataMap[KEY_DATE_MILLIS] = it } retriever.getSafeDateMillis(MediaMetadataRetriever.METADATA_KEY_DATE) { metadataMap[KEY_DATE_MILLIS] = it }
} }

View file

@ -1,6 +1,5 @@
package deckers.thibault.aves.channel.streams package deckers.thibault.aves.channel.streams
import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
@ -77,7 +76,7 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any
private fun requestMediaFileAccess() { private fun requestMediaFileAccess() {
val uris = (args["uris"] as List<*>?)?.mapNotNull { if (it is String) Uri.parse(it) else null } val uris = (args["uris"] as List<*>?)?.mapNotNull { if (it is String) Uri.parse(it) else null }
val mimeTypes = (args["mimeTypes"] as List<*>?)?.mapNotNull { if (it is String) it else null } val mimeTypes = (args["mimeTypes"] as List<*>?)?.mapNotNull { if (it is String) it else null }
if (uris == null || uris.isEmpty() || mimeTypes == null || mimeTypes.size != uris.size) { if (uris.isNullOrEmpty() || mimeTypes == null || mimeTypes.size != uris.size) {
error("requestMediaFileAccess-args", "missing arguments", null) error("requestMediaFileAccess-args", "missing arguments", null)
return return
} }
@ -112,12 +111,6 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any
} }
private suspend fun createFile() { private suspend fun createFile() {
@SuppressLint("ObsoleteSdkInt")
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
error("createFile-sdk", "unsupported SDK version=${Build.VERSION.SDK_INT}", null)
return
}
val name = args["name"] as String? val name = args["name"] as String?
val mimeType = args["mimeType"] as String? val mimeType = args["mimeType"] as String?
val bytes = args["bytes"] as ByteArray? val bytes = args["bytes"] as ByteArray?
@ -155,12 +148,6 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any
} }
private suspend fun openFile() { private suspend fun openFile() {
@SuppressLint("ObsoleteSdkInt")
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
error("openFile-sdk", "unsupported SDK version=${Build.VERSION.SDK_INT}", null)
return
}
val mimeType = args["mimeType"] as String? // optional val mimeType = args["mimeType"] as String? // optional
fun onGranted(uri: Uri) { fun onGranted(uri: Uri) {

View file

@ -34,14 +34,12 @@ class SettingsChangeStreamHandler(private val context: Context) : EventChannel.S
override fun onChange(selfChange: Boolean, uri: Uri?) { override fun onChange(selfChange: Boolean, uri: Uri?) {
if (update()) { if (update()) {
val settings: FieldMap = hashMapOf( success(
hashMapOf(
Settings.System.ACCELEROMETER_ROTATION to accelerometerRotation, Settings.System.ACCELEROMETER_ROTATION to accelerometerRotation,
Settings.Global.TRANSITION_ANIMATION_SCALE to transitionAnimationScale,
)
) )
@SuppressLint("ObsoleteSdkInt")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
settings[Settings.Global.TRANSITION_ANIMATION_SCALE] = transitionAnimationScale
}
success(settings)
} }
} }
@ -53,14 +51,11 @@ class SettingsChangeStreamHandler(private val context: Context) : EventChannel.S
accelerometerRotation = newAccelerometerRotation accelerometerRotation = newAccelerometerRotation
changed = true changed = true
} }
@SuppressLint("ObsoleteSdkInt")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
val newTransitionAnimationScale = Settings.Global.getFloat(context.contentResolver, Settings.Global.TRANSITION_ANIMATION_SCALE) val newTransitionAnimationScale = Settings.Global.getFloat(context.contentResolver, Settings.Global.TRANSITION_ANIMATION_SCALE)
if (transitionAnimationScale != newTransitionAnimationScale) { if (transitionAnimationScale != newTransitionAnimationScale) {
transitionAnimationScale = newTransitionAnimationScale transitionAnimationScale = newTransitionAnimationScale
changed = true changed = true
} }
}
} catch (e: Exception) { } catch (e: Exception) {
Log.w(LOG_TAG, "failed to get settings with error=${e.message}", null) Log.w(LOG_TAG, "failed to get settings with error=${e.message}", null)
} }

View file

@ -1,11 +1,12 @@
package deckers.thibault.aves.metadata package deckers.thibault.aves.metadata
import android.annotation.SuppressLint
import android.media.MediaFormat import android.media.MediaFormat
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
import android.os.Build import android.os.Build
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.Date
import java.util.Locale
import java.util.TimeZone
object MediaMetadataRetrieverHelper { object MediaMetadataRetrieverHelper {
val allKeys = hashMapOf( val allKeys = hashMapOf(
@ -31,11 +32,8 @@ object MediaMetadataRetrieverHelper {
MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH to "Video Width", MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH to "Video Width",
MediaMetadataRetriever.METADATA_KEY_WRITER to "Writer", MediaMetadataRetriever.METADATA_KEY_WRITER to "Writer",
MediaMetadataRetriever.METADATA_KEY_YEAR to "Year", MediaMetadataRetriever.METADATA_KEY_YEAR to "Year",
MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION to "Video Rotation",
).apply { ).apply {
@SuppressLint("ObsoleteSdkInt")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
put(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION, "Video Rotation")
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
put(MediaMetadataRetriever.METADATA_KEY_CAPTURE_FRAMERATE, "Capture Framerate") put(MediaMetadataRetriever.METADATA_KEY_CAPTURE_FRAMERATE, "Capture Framerate")
} }

View file

@ -1,6 +1,5 @@
package deckers.thibault.aves.metadata package deckers.thibault.aves.metadata
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.media.MediaExtractor import android.media.MediaExtractor
import android.media.MediaFormat import android.media.MediaFormat
@ -63,10 +62,7 @@ object MultiPage {
format.getSafeInt(MediaFormat.KEY_WIDTH) { track[KEY_WIDTH] = it } format.getSafeInt(MediaFormat.KEY_WIDTH) { track[KEY_WIDTH] = it }
format.getSafeInt(MediaFormat.KEY_HEIGHT) { track[KEY_HEIGHT] = it } format.getSafeInt(MediaFormat.KEY_HEIGHT) { track[KEY_HEIGHT] = it }
@SuppressLint("ObsoleteSdkInt")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
format.getSafeInt(MediaFormat.KEY_IS_DEFAULT) { track[KEY_IS_DEFAULT] = it != 0 } format.getSafeInt(MediaFormat.KEY_IS_DEFAULT) { track[KEY_IS_DEFAULT] = it != 0 }
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
format.getSafeInt(MediaFormat.KEY_ROTATION) { track[KEY_ROTATION_DEGREES] = it } format.getSafeInt(MediaFormat.KEY_ROTATION) { track[KEY_ROTATION_DEGREES] = it }
} }

View file

@ -1,12 +1,10 @@
package deckers.thibault.aves.model package deckers.thibault.aves.model
import android.annotation.SuppressLint
import android.content.ContentResolver import android.content.ContentResolver
import android.content.Context import android.content.Context
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
import android.net.Uri import android.net.Uri
import android.os.Build
import androidx.exifinterface.media.ExifInterface import androidx.exifinterface.media.ExifInterface
import com.drew.metadata.avi.AviDirectory import com.drew.metadata.avi.AviDirectory
import com.drew.metadata.exif.ExifIFD0Directory import com.drew.metadata.exif.ExifIFD0Directory
@ -147,10 +145,7 @@ class SourceEntry {
retriever.getSafeLong(MediaMetadataRetriever.METADATA_KEY_DURATION) { durationMillis = it } retriever.getSafeLong(MediaMetadataRetriever.METADATA_KEY_DURATION) { durationMillis = it }
retriever.getSafeDateMillis(MediaMetadataRetriever.METADATA_KEY_DATE) { sourceDateTakenMillis = it } retriever.getSafeDateMillis(MediaMetadataRetriever.METADATA_KEY_DATE) { sourceDateTakenMillis = it }
retriever.getSafeString(MediaMetadataRetriever.METADATA_KEY_TITLE) { title = it } retriever.getSafeString(MediaMetadataRetriever.METADATA_KEY_TITLE) { title = it }
@SuppressLint("ObsoleteSdkInt")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
retriever.getSafeInt(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) { sourceRotationDegrees = it } retriever.getSafeInt(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) { sourceRotationDegrees = it }
}
} catch (e: Exception) { } catch (e: Exception) {
// ignore // ignore
} finally { } finally {

View file

@ -1,6 +1,5 @@
package deckers.thibault.aves.utils package deckers.thibault.aves.utils
import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@ -177,14 +176,10 @@ object PermissionManager {
val accessibleDirs = HashSet(getGrantedDirs(context)) val accessibleDirs = HashSet(getGrantedDirs(context))
accessibleDirs.addAll(context.getExternalFilesDirs(null).filterNotNull().map { it.path }) accessibleDirs.addAll(context.getExternalFilesDirs(null).filterNotNull().map { it.path })
// until API 18 / Android 4.3 / Jelly Bean MR2, removable storage is accessible by default like primary storage
// from API 19 / Android 4.4 / KitKat, removable storage requires access permission, at the file level // from API 19 / Android 4.4 / KitKat, removable storage requires access permission, at the file level
// from API 21 / Android 5.0 / Lollipop, removable storage requires access permission, but directory access grant is possible // from API 21 / Android 5.0 / Lollipop, removable storage requires access permission, but directory access grant is possible
// from API 30 / Android 11 / R, any storage requires access permission // from API 30 / Android 11 / R, any storage requires access permission
@SuppressLint("ObsoleteSdkInt") if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2) {
accessibleDirs.addAll(StorageUtils.getVolumePaths(context))
} else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
accessibleDirs.add(StorageUtils.getPrimaryVolumePath(context)) accessibleDirs.add(StorageUtils.getPrimaryVolumePath(context))
} }
return accessibleDirs return accessibleDirs

View file

@ -9,7 +9,7 @@ final Device device = Device._private();
class Device { class Device {
late final String _userAgent; late final String _userAgent;
late final bool _canAuthenticateUser, _canGrantDirectoryAccess, _canPinShortcut, _canPrint; late final bool _canAuthenticateUser, _canGrantDirectoryAccess, _canPinShortcut;
late final bool _canRenderFlagEmojis, _canRenderSubdivisionFlagEmojis, _canRequestManageMedia, _canSetLockScreenWallpaper, _canUseCrypto; late final bool _canRenderFlagEmojis, _canRenderSubdivisionFlagEmojis, _canRequestManageMedia, _canSetLockScreenWallpaper, _canUseCrypto;
late final bool _hasGeocoder, _isDynamicColorAvailable, _isTelevision, _showPinShortcutFeedback, _supportEdgeToEdgeUIMode, _supportPictureInPicture; late final bool _hasGeocoder, _isDynamicColorAvailable, _isTelevision, _showPinShortcutFeedback, _supportEdgeToEdgeUIMode, _supportPictureInPicture;
@ -21,8 +21,6 @@ class Device {
bool get canPinShortcut => _canPinShortcut; bool get canPinShortcut => _canPinShortcut;
bool get canPrint => _canPrint;
bool get canRenderFlagEmojis => _canRenderFlagEmojis; bool get canRenderFlagEmojis => _canRenderFlagEmojis;
bool get canRenderSubdivisionFlagEmojis => _canRenderSubdivisionFlagEmojis; bool get canRenderSubdivisionFlagEmojis => _canRenderSubdivisionFlagEmojis;
@ -71,7 +69,6 @@ class Device {
final capabilities = await deviceService.getCapabilities(); final capabilities = await deviceService.getCapabilities();
_canGrantDirectoryAccess = capabilities['canGrantDirectoryAccess'] ?? false; _canGrantDirectoryAccess = capabilities['canGrantDirectoryAccess'] ?? false;
_canPinShortcut = capabilities['canPinShortcut'] ?? false; _canPinShortcut = capabilities['canPinShortcut'] ?? false;
_canPrint = capabilities['canPrint'] ?? false;
_canRenderFlagEmojis = capabilities['canRenderFlagEmojis'] ?? false; _canRenderFlagEmojis = capabilities['canRenderFlagEmojis'] ?? false;
_canRenderSubdivisionFlagEmojis = capabilities['canRenderSubdivisionFlagEmojis'] ?? false; _canRenderSubdivisionFlagEmojis = capabilities['canRenderSubdivisionFlagEmojis'] ?? false;
_canRequestManageMedia = capabilities['canRequestManageMedia'] ?? false; _canRequestManageMedia = capabilities['canRequestManageMedia'] ?? false;

View file

@ -82,7 +82,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
case EntryAction.convert: case EntryAction.convert:
return canWrite && !targetEntry.isVideo; return canWrite && !targetEntry.isVideo;
case EntryAction.print: case EntryAction.print:
return device.canPrint && !targetEntry.isVideo; return !targetEntry.isVideo;
case EntryAction.openMap: case EntryAction.openMap:
return !settings.useTvLayout && targetEntry.hasGps; return !settings.useTvLayout && targetEntry.hasGps;
case EntryAction.viewSource: case EntryAction.viewSource: