Before
dependencies {
implementation("com.google.mlkit:barcode-scanning:17.3.0")
}After
dependencies {
implementation("com.google.android.gms:play-services-basement:18.4.0")
implementation("com.google.mlkit:barcode-scanning:17.3.0") {
isTransitive = false
}
}import android.content.Context
import android.graphics.Bitmap
import android.graphics.Point
import android.os.Parcel
import android.os.Parcelable
import com.google.android.gms.common.internal.safeparcel.SafeParcelReader
import com.google.android.gms.dynamic.ObjectWrapper
import com.google.mlkit.vision.barcode.bundled.internal.ThickBarcodeScannerCreator
private typealias BarcodeScannerOptions = com.google.android.gms.internal.mlkit_vision_barcode_bundled.zzba
private typealias ImageMetadata = com.google.android.gms.internal.mlkit_vision_barcode_bundled.zzcc
typealias BarcodeScanner = com.google.android.gms.internal.mlkit_vision_barcode_bundled.zzbn
private typealias Barcode = com.google.android.gms.internal.mlkit_vision_barcode_bundled.zzay
fun createBarcodeScanner(
context: Context,
// https://developers.google.com/android/reference/com/google/mlkit/vision/barcode/common/Barcode#FORMAT_ALL_FORMATS
format: Int, // 0 for all format
): BarcodeScanner {
return ThickBarcodeScannerCreator().newBarcodeScanner(
ObjectWrapper.wrap(context.applicationContext),
BarcodeScannerOptions(format, true)
).also { it.zzd() }
}
// Reminder: don't invoke this after close
private fun BarcodeScanner.recognize0(image: Bitmap): List<Barcode> {
return zzb(
ObjectWrapper.wrap(image),
ImageMetadata(
/** -1 for [Bitmap], 35 for [Image] */
-1,
image.width,
image.height,
/** rotation value */
0,
/** timestamp, 0 is OK */
System.currentTimeMillis()
)
).filterIsInstance<Barcode>()
}
fun BarcodeScanner.close() {
zzf()
}class BarcodeData(
val format: Int,
val rawValue: String?,
val cornerPoints: Array<Point>?,
)
fun BarcodeScanner.recognize(image: Bitmap): List<BarcodeData> {
return recognize0(image).mapNotNull(::readBarcodeResult)
}
// Access private fields without reflection
private fun readBarcodeResult(data: Barcode): BarcodeData? {
val parcel = Parcel.obtain()
data.writeToParcel(parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE)
// read it back
parcel.setDataPosition(0)
var format = 0
var rawValue: String? = null
var cornerPoints: Array<Point>? = null
SafeParcelReader.validateObjectHeader(parcel).let { header ->
while (parcel.dataPosition() < header) {
val h = SafeParcelReader.readHeader(parcel)
when (SafeParcelReader.getFieldId(h)) {
1 -> {
val f = SafeParcelReader.readInt(parcel, h)
// unrecognized format
if (f < 1) {
parcel.recycle()
return null
}
format = f
}
3 -> rawValue = SafeParcelReader.createString(parcel, h)
5 -> cornerPoints = SafeParcelReader.createTypedArray(parcel, h, Point.CREATOR)
else -> SafeParcelReader.skipUnknownField(parcel, h)
}
}
SafeParcelReader.ensureAtEnd(parcel, header)
}
parcel.recycle()
return if (format < 1) null else BarcodeData(
format = format,
rawValue = rawValue,
cornerPoints = cornerPoints,
)
}
Add missing class to java src directory.
ProGuard will remove it.
package com.google.mlkit.vision.common.internal;
public class ImageUtils {
private static final ImageUtils s = new ImageUtils();
public static ImageUtils getInstance() {
return s;
}
public android.graphics.Matrix getUprightRotationMatrix(int width, int height, int rotation) {
// assert rotation is 0
return null;
}
}Add ProGuard rules from com.google.mlkit:common:18.10.0.
# Annotations are implemented as attributes, so we have to explicitly keep them.
# Catch all which encompasses attributes like RuntimeVisibleParameterAnnotations
# and RuntimeVisibleTypeAnnotations
-keepattributes RuntimeVisible*Annotation*
# JNI is an entry point that's hard to keep track of, so there's
# an annotation to mark fields and methods used by native code.
# Keep the annotations that proguard needs to process.
-keep class com.google.android.apps.common.proguard.UsedBy*
# Just because native code accesses members of a class, does not mean that the
# class itself needs to be annotated - only annotate classes that are
# referenced themselves in native code.
-keep @com.google.android.apps.common.proguard.UsedBy* class * {
<init>();
}
-keepclassmembers class * {
@com.google.android.apps.common.proguard.UsedBy* *;
}