Ashampoo / kim

Image metadata manipulation library for Kotlin Multiplatform
https://ashampoo.github.io/kim/
Apache License 2.0
171 stars 8 forks source link

Android version lower than 31 failed to extract metadata #60

Closed Vaxela closed 9 months ago

Vaxela commented 9 months ago

Hi, I'm Lucas, developper on Android - Kotlin, I'm using your plugin to extract metadata for my application and we are working with a lots of devices from 24 to 34 and we have a problem to extract metadata from device under 31.

Your minSdk = 23

Our MinSdk : 24 Our Kim version : v0.9.3

To reproduce I've just create an device emulator in Android Studio using an Pixel 7 on android 29 and I receive an error :

The line use in my kotlin : val metadata = Kim.readMetadata(file.absolutePath) ?: return null

The error : Caused by: java.lang.NoSuchMethodError: No virtual method readNBytes(I)[B in class Ljava/io/InputStream; or its super classes (declaration of 'java.io.InputStream' appears in /apex/com.android.runtime/javalib/core-oj.jar)

Can you help ? Do you have some information ?

Thanks Lucas 😄

Manifest : compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 }

All the log : 2024-01-17 10:33:38.778 5579-5579 System.err com.syslor.easyscan.preprod.debug W com.ashampoo.kim.common.ImageReadException: Failed to read image. 2024-01-17 10:33:38.782 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.ashampoo.kim.Kim.readMetadata(Kim.kt:262) 2024-01-17 10:33:38.782 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.ashampoo.kim.JvmKimExtensionsKt.readMetadata(JvmKimExtensions.kt:26) 2024-01-17 10:33:38.782 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.ashampoo.kim.JvmKimExtensionsKt.readMetadata(JvmKimExtensions.kt:37) 2024-01-17 10:33:38.788 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.ashampoo.kim.JvmKimExtensionsKt.readMetadata(JvmKimExtensions.kt:30) 2024-01-17 10:33:38.788 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.syslor.easyscan.utils.MapUtils.extractOrthomosaicMetadata(MapUtils.kt:117) 2024-01-17 10:33:38.788 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.syslor.easyscan.presentation.viewmodel.MapViewEasyScanViewModel.proceedFeatureToOrthomosaicData(MapViewEasyScanViewModel.kt:282) 2024-01-17 10:33:38.791 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.syslor.easyscan.presentation.viewmodel.MapViewEasyScanViewModel.access$proceedFeatureToOrthomosaicData(MapViewEasyScanViewModel.kt:51) 2024-01-17 10:33:38.791 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.syslor.easyscan.presentation.viewmodel.MapViewEasyScanViewModel$proceedFeatureToOrthomosaicData$1.invokeSuspend(Unknown Source:22) 2024-01-17 10:33:38.791 5579-5579 System.err com.syslor.easyscan.preprod.debug W at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) 2024-01-17 10:33:38.791 5579-5579 System.err com.syslor.easyscan.preprod.debug W at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108) 2024-01-17 10:33:38.797 5579-5579 System.err com.syslor.easyscan.preprod.debug W at android.os.Handler.handleCallback(Handler.java:883) 2024-01-17 10:33:38.797 5579-5579 System.err com.syslor.easyscan.preprod.debug W at android.os.Handler.dispatchMessage(Handler.java:100) 2024-01-17 10:33:38.797 5579-5579 System.err com.syslor.easyscan.preprod.debug W at android.os.Looper.loop(Looper.java:214) 2024-01-17 10:33:38.797 5579-5579 System.err com.syslor.easyscan.preprod.debug W at android.app.ActivityThread.main(ActivityThread.java:7356) 2024-01-17 10:33:38.797 5579-5579 System.err com.syslor.easyscan.preprod.debug W at java.lang.reflect.Method.invoke(Native Method) 2024-01-17 10:33:38.801 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 2024-01-17 10:33:38.801 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 2024-01-17 10:33:38.811 5579-5579 System.err com.syslor.easyscan.preprod.debug W Caused by: java.lang.NoSuchMethodError: No virtual method readNBytes(I)[B in class Ljava/io/InputStream; or its super classes (declaration of 'java.io.InputStream' appears in /apex/com.android.runtime/javalib/core-oj.jar) 2024-01-17 10:33:38.811 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.ashampoo.kim.input.JvmInputStreamByteReader.readBytes(JvmInputStreamByteReader.kt:36) 2024-01-17 10:33:38.811 5579-5579 System.err com.syslor.easyscan.preprod.debug W at com.ashampoo.kim.Kim.readMetadata(Kim.kt:78) 2024-01-17 10:33:38.811 5579-5579 System.err com.syslor.easyscan.preprod.debug W ... 16 more

StefanOltmann commented 9 months ago

Hi Lucas,

thanks for reaching out.

This is the problem you run into: https://github.com/Ashampoo/kim/blob/310bc147d15d0adf347e5e719523c449b6ca2840/src/androidMain/kotlin/com/ashampoo/kim/input/AndroidInputStreamByteReader.kt#L38-L41

I'll look into that how to make String paths work with lower Android APIs.

Please use Kim.readMetadataAndroid() in the mean time. This is API that works on all Android versions and is also used by Ashampoo Photos.

It uses AndroidInputStreamByteReader behind the scenes which avoids usage of newer API.

Kind regards,

Stefan

Vaxela commented 9 months ago

Hi Stefan thanks for the answer ! It work great thank you 😄

StefanOltmann commented 9 months ago

@Vaxela This problem has been fixed now.

You can use String, File and InputStream on Android at it should always use AndroidInputStreamByteReader.

Kim.readMetadataAndroid() has been removed now.