Se agrego el sdk para el pda de honeywell

This commit is contained in:
Alejandro Lara
2026-06-19 08:57:58 -06:00
parent 50fe9a9d36
commit d6db216d2d
21 changed files with 1038 additions and 77 deletions
+21 -15
View File
@@ -1,13 +1,16 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="com.honeywell.decode.permission.DECODE" />
<application
android:name=".QrScannerApplication"
android:label="qrscanner"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true">
android:usesCleartextTraffic="true"
tools:replace="android:label">
<activity
android:name=".MainActivity"
android:exported="true"
@@ -17,10 +20,6 @@
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
@@ -29,22 +28,29 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="com.example.qrscanner.action.BARCODE_DATA"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<receiver
android:name=".HoneywellScanReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.example.qrscanner.action.BARCODE_DATA"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
</manifest>
@@ -0,0 +1,160 @@
package com.example.qrscanner
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import io.flutter.plugin.common.EventChannel
object HoneywellScanManager {
const val ACTION_BARCODE_DATA = "com.example.qrscanner.action.BARCODE_DATA"
const val EXTRA_SCAN_DATA = "scan_data"
private const val PREFS = "honeywell_scan_bridge"
private const val PENDING_KEY = "pending_scan"
private const val ACTION_CLAIM_SCANNER = "com.honeywell.aidc.action.ACTION_CLAIM_SCANNER"
private const val ACTION_RELEASE_SCANNER = "com.honeywell.aidc.action.ACTION_RELEASE_SCANNER"
private const val EXTRA_SCANNER = "com.honeywell.aidc.extra.EXTRA_SCANNER"
private const val EXTRA_PROPERTIES = "com.honeywell.aidc.extra.EXTRA_PROPERTIES"
private const val SCANNER_PACKAGE = "com.intermec.datacollectionservice"
@Volatile
private var eventSink: EventChannel.EventSink? = null
fun setEventSink(sink: EventChannel.EventSink?) {
eventSink = sink
}
fun isSupported(context: Context): Boolean {
return try {
context.packageManager.getPackageInfo(SCANNER_PACKAGE, 0)
true
} catch (_: PackageManager.NameNotFoundException) {
false
}
}
fun claimScanner(context: Context) {
if (!isSupported(context)) return
val properties = Bundle().apply {
putBoolean("DPR_DATA_INTENT", true)
putString("DPR_DATA_INTENT_ACTION", ACTION_BARCODE_DATA)
putBoolean("DPR_LAUNCH_BROWSER", false)
putBoolean("DEC_QR_ENABLED", true)
putBoolean("DEC_AZTEC_ENABLED", false)
putBoolean("DEC_CODABAR_ENABLED", false)
putBoolean("DEC_CODE39_ENABLED", false)
putBoolean("DEC_CODE93_ENABLED", false)
putBoolean("DEC_CODE128_ENABLED", false)
putBoolean("DEC_DATAMATRIX_ENABLED", false)
putBoolean("DEC_EAN8_ENABLED", false)
putBoolean("DEC_EAN13_ENABLED", false)
putBoolean("DEC_MAXICODE_ENABLED", false)
putBoolean("DEC_PDF417_ENABLED", false)
putBoolean("DEC_RSS_14_ENABLED", false)
putBoolean("DEC_RSS_EXPANDED_ENABLED", false)
putBoolean("DEC_UPCA_ENABLE", false)
putBoolean("DEC_UPCE0_ENABLED", false)
}
sendScannerBroadcast(
context,
Intent(ACTION_CLAIM_SCANNER)
.setPackage(SCANNER_PACKAGE)
.putExtra(EXTRA_SCANNER, "dcs.scanner.imager")
.putExtra(EXTRA_PROPERTIES, properties),
)
}
fun releaseScanner(context: Context) {
if (!isSupported(context)) return
sendScannerBroadcast(context, Intent(ACTION_RELEASE_SCANNER))
}
fun handleBarcodeIntent(context: Context, intent: Intent?) {
val data = extractScanData(intent) ?: return
deliverScan(context, data)
}
fun deliverScan(context: Context, data: String) {
val trimmed = data.trim()
if (trimmed.isEmpty()) return
storePendingScan(context, trimmed)
eventSink?.success(trimmed)
}
fun launchAppWithScan(context: Context, data: String) {
val trimmed = data.trim()
if (trimmed.isEmpty()) return
storePendingScan(context, trimmed)
val launchIntent = Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_SINGLE_TOP or
Intent.FLAG_ACTIVITY_CLEAR_TOP
putExtra(EXTRA_SCAN_DATA, trimmed)
}
context.startActivity(launchIntent)
}
fun consumePendingScan(context: Context): String? {
val prefs = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
val stored = prefs.getString(PENDING_KEY, null)?.trim()
if (!stored.isNullOrEmpty()) {
prefs.edit().remove(PENDING_KEY).apply()
return stored
}
return null
}
private fun storePendingScan(context: Context, data: String) {
context.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.edit()
.putString(PENDING_KEY, data)
.apply()
}
private fun extractScanData(intent: Intent?): String? {
if (intent == null) return null
intent.getStringExtra(EXTRA_SCAN_DATA)?.let { return it }
if (intent.action == ACTION_BARCODE_DATA) {
val version = intent.getIntExtra("version", 0)
if (version >= 1) {
return intent.getStringExtra("data")
}
}
return intent.getStringExtra("data")
}
private fun sendScannerBroadcast(context: Context, intent: Intent) {
if (Build.VERSION.SDK_INT < 26) {
context.sendBroadcast(intent)
return
}
val matches = context.packageManager.queryBroadcastReceivers(intent, PackageManager.MATCH_DEFAULT_ONLY)
if (matches.isEmpty()) {
context.sendBroadcast(intent)
return
}
for (resolveInfo in matches) {
val explicit = Intent(intent).apply {
component = ComponentName(
resolveInfo.activityInfo.applicationInfo.packageName,
resolveInfo.activityInfo.name,
)
}
context.sendBroadcast(explicit)
}
}
}
@@ -0,0 +1,19 @@
package com.example.qrscanner
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
class HoneywellScanReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action != HoneywellScanManager.ACTION_BARCODE_DATA) return
val version = intent.getIntExtra("version", 0)
if (version < 1) return
val data = intent.getStringExtra("data")?.trim().orEmpty()
if (data.isEmpty()) return
HoneywellScanManager.launchAppWithScan(context, data)
}
}
@@ -1,5 +1,59 @@
package com.example.qrscanner
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodChannel
class MainActivity : FlutterActivity()
class MainActivity : FlutterActivity() {
companion object {
private const val METHOD_CHANNEL = "com.example.qrscanner/scan_launch"
private const val EVENT_CHANNEL = "com.example.qrscanner/scan_events"
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, METHOD_CHANNEL)
.setMethodCallHandler { call, result ->
when (call.method) {
"isSupported" -> result.success(HoneywellScanManager.isSupported(this))
"claimScanner" -> {
HoneywellScanManager.claimScanner(this)
result.success(true)
}
"releaseScanner" -> {
HoneywellScanManager.releaseScanner(this)
result.success(true)
}
"consumePendingScan" -> {
result.success(HoneywellScanManager.consumePendingScan(this))
}
else -> result.notImplemented()
}
}
EventChannel(flutterEngine.dartExecutor.binaryMessenger, EVENT_CHANNEL)
.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
HoneywellScanManager.setEventSink(events)
}
override fun onCancel(arguments: Any?) {
HoneywellScanManager.setEventSink(null)
}
})
}
override fun onNewIntent(intent: android.content.Intent) {
super.onNewIntent(intent)
setIntent(intent)
HoneywellScanManager.handleBarcodeIntent(this, intent)
}
override fun onResume() {
super.onResume()
HoneywellScanManager.claimScanner(this)
HoneywellScanManager.handleBarcodeIntent(this, intent)
}
}
@@ -0,0 +1,10 @@
package com.example.qrscanner
import android.app.Application
class QrScannerApplication : Application() {
override fun onCreate() {
super.onCreate()
HoneywellScanManager.claimScanner(this)
}
}