react-native-mesmart 3.0.2 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +1 -0
- package/android/consumer-rules.pro +2 -0
- package/android/src/main/assets/gertec-neo/VERSION +1 -0
- package/android/src/main/assets/gertec-neo/arm64-v8a/libgedi.so +0 -0
- package/android/src/main/assets/gertec-neo/armeabi-v7a/libgedi.so +0 -0
- package/android/src/main/assets/gertec-neo/neo-bridge.jar +0 -0
- package/android/src/main/java/com/gertec/GertecImpl.kt +118 -8
- package/android/src/main/java/com/gertec/GertecModule.kt +4 -4
- package/android/src/main/java/com/gertec/NeoSdkLoader.kt +94 -0
- package/android/src/main/java/com/gertec/backend/GertecBackend.java +20 -0
- package/android/src/main/java/com/gertec/backend/GertecCallback.java +7 -0
- package/android/src/main/java/com/gertec/utils/MifareGPOS780.kt +14 -4
- package/android/src/main/java/com/gertec/utils/PrinterGPOS780.kt +39 -16
- package/android/src/main/java/com/mesmart/Utils.kt +11 -1
- package/package.json +2 -2
package/android/build.gradle
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.0.10-b12dc1dd8256
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
package com.gertec
|
|
2
2
|
|
|
3
|
+
import android.util.Log
|
|
3
4
|
import br.com.gertec.gedi.GEDI
|
|
4
5
|
import com.facebook.react.bridge.Promise
|
|
5
6
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import java.util.concurrent.ExecutionException
|
|
8
|
+
import java.util.concurrent.Executors
|
|
9
|
+
import java.util.concurrent.TimeUnit
|
|
10
|
+
import java.util.concurrent.TimeoutException
|
|
11
|
+
import com.gertec.backend.GertecBackend
|
|
12
|
+
import com.gertec.backend.GertecCallback
|
|
6
13
|
import com.gertec.utils.MifareGPOS780
|
|
7
14
|
import com.gertec.utils.PrinterGPOS780
|
|
8
15
|
import com.mesmart.Utils
|
|
@@ -12,42 +19,124 @@ class GertecImpl(
|
|
|
12
19
|
) {
|
|
13
20
|
private val isSupported = Utils.isGPOS780()
|
|
14
21
|
|
|
22
|
+
// GPOS780S usa o SDK Gertec Neo (libgedi 2.x), carregado a parte; os demais GPOS780 seguem na libgedi 1.16.
|
|
23
|
+
private val useNeo = Utils.isGPOS780S()
|
|
24
|
+
|
|
15
25
|
@Volatile private var mifare: MifareGPOS780? = null
|
|
16
26
|
@Volatile private var printer: PrinterGPOS780? = null
|
|
27
|
+
private var neo: GertecBackend? = null
|
|
28
|
+
private var neoError: Throwable? = null
|
|
29
|
+
|
|
30
|
+
// Falha no init da GEDI (ex.: libgedi.so incompativel com o Android do aparelho) nao pode derrubar o modulo:
|
|
31
|
+
// fica guardada e volta como erro legivel em cada chamada.
|
|
32
|
+
private var initError: Throwable? = null
|
|
17
33
|
|
|
18
34
|
init {
|
|
19
|
-
if (isSupported) {
|
|
20
|
-
|
|
35
|
+
if (isSupported && !useNeo) {
|
|
36
|
+
try {
|
|
37
|
+
GEDI.init(reactContext.applicationContext)
|
|
38
|
+
} catch (t: Throwable) {
|
|
39
|
+
initError = t
|
|
40
|
+
Log.e(TAG, "GEDI.init failed: ${t.javaClass.name}: ${t.message} (${Utils.deviceContext()})", t)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private fun checkSupported() {
|
|
46
|
+
if (!isSupported) throw Exception("Unsupported device (Supported models GPOS780, GPOS780S). ${Utils.deviceContext()}")
|
|
47
|
+
initError?.let {
|
|
48
|
+
throw Exception("GEDI init failed: ${it.javaClass.name}: ${it.message} (${Utils.deviceContext()})", it)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// GEDI.init() sobe a instancia numa thread e engole falhas; a lib de RFID le GEDI.getInstance() sem argumento
|
|
53
|
+
// e leva NPE se ainda for null. getInstance(context) cria de forma sincrona e deixa a causa real subir,
|
|
54
|
+
// com timeout p/ nao travar a fila de modulos nativos caso o init fique pendurado (visto na GPOS780S).
|
|
55
|
+
private fun ensureGedi() {
|
|
56
|
+
if (GEDI.getInstance() != null) return
|
|
57
|
+
val executor = Executors.newSingleThreadExecutor()
|
|
58
|
+
try {
|
|
59
|
+
executor.submit<Any?> { GEDI.getInstance(reactContext.applicationContext) }.get(GEDI_INIT_TIMEOUT_S, TimeUnit.SECONDS)
|
|
60
|
+
} catch (e: TimeoutException) {
|
|
61
|
+
throw Exception("GEDI init timeout (${GEDI_INIT_TIMEOUT_S}s) (${Utils.deviceContext()})", e)
|
|
62
|
+
} catch (e: ExecutionException) {
|
|
63
|
+
val cause = e.cause ?: e
|
|
64
|
+
throw Exception("GEDI init failed: ${cause.javaClass.name}: ${cause.message} (${Utils.deviceContext()})", cause)
|
|
65
|
+
} finally {
|
|
66
|
+
executor.shutdownNow()
|
|
67
|
+
}
|
|
68
|
+
if (GEDI.getInstance() == null) {
|
|
69
|
+
throw Exception("GEDI instance is null after init (${Utils.deviceContext()})")
|
|
21
70
|
}
|
|
22
71
|
}
|
|
23
72
|
|
|
24
73
|
@Synchronized
|
|
25
74
|
private fun ensureMifare(): MifareGPOS780 {
|
|
26
|
-
|
|
75
|
+
checkSupported()
|
|
76
|
+
ensureGedi()
|
|
27
77
|
if (mifare == null) mifare = MifareGPOS780()
|
|
28
78
|
return mifare!!
|
|
29
79
|
}
|
|
30
80
|
|
|
31
81
|
@Synchronized
|
|
32
82
|
private fun ensurePrinter(): PrinterGPOS780 {
|
|
33
|
-
|
|
83
|
+
checkSupported()
|
|
34
84
|
if (printer == null) printer = PrinterGPOS780(reactContext)
|
|
35
85
|
return printer!!
|
|
36
86
|
}
|
|
37
87
|
|
|
88
|
+
// Carga preguicosa: so a GPOS780S paga o custo de extrair o dex/.so da Neo, e a falha vira erro legivel por chamada.
|
|
89
|
+
@Synchronized
|
|
90
|
+
private fun ensureNeo(): GertecBackend {
|
|
91
|
+
neo?.let { return it }
|
|
92
|
+
neoError?.let { throw neoLoadException(it) }
|
|
93
|
+
return try {
|
|
94
|
+
NeoSdkLoader.load(reactContext.applicationContext).also { neo = it }
|
|
95
|
+
} catch (t: Throwable) {
|
|
96
|
+
neoError = t
|
|
97
|
+
Log.e(TAG, "Gertec Neo SDK load failed: ${t.javaClass.name}: ${t.message} (${Utils.deviceContext()})", t)
|
|
98
|
+
throw neoLoadException(t)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private fun neoLoadException(t: Throwable) =
|
|
103
|
+
Exception("Gertec Neo SDK load failed: ${t.javaClass.name}: ${t.message} (${Utils.deviceContext()})", t)
|
|
104
|
+
|
|
105
|
+
private fun neoCallback(promise: Promise, transform: (Any?) -> Any? = { it }) = object : GertecCallback {
|
|
106
|
+
override fun resolve(value: Any?) {
|
|
107
|
+
try {
|
|
108
|
+
promise.resolve(transform(value))
|
|
109
|
+
} catch (t: Throwable) {
|
|
110
|
+
promise.reject("GERTEC_RFID_ERROR", t.message, t)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
override fun reject(code: String, message: String?, cause: Throwable?) {
|
|
115
|
+
if (cause != null) promise.reject(code, message, cause) else promise.reject(code, message)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
38
119
|
fun scanRfid(promise: Promise) {
|
|
39
120
|
try {
|
|
121
|
+
if (useNeo) {
|
|
122
|
+
ensureNeo().scanRfid(neoCallback(promise) { Utils.resolveRFID(Utils.byteArrayToHexString(it as ByteArray)) })
|
|
123
|
+
return
|
|
124
|
+
}
|
|
40
125
|
ensureMifare().scanRfid(promise)
|
|
41
126
|
} catch (t: Throwable) {
|
|
42
|
-
promise.reject(t)
|
|
127
|
+
promise.reject("GERTEC_RFID_ERROR", t.message, t)
|
|
43
128
|
}
|
|
44
129
|
}
|
|
45
130
|
|
|
46
131
|
fun cancelScan(promise: Promise) {
|
|
47
132
|
try {
|
|
133
|
+
if (useNeo) {
|
|
134
|
+
ensureNeo().cancelScan(neoCallback(promise))
|
|
135
|
+
return
|
|
136
|
+
}
|
|
48
137
|
ensureMifare().cancelScan(promise)
|
|
49
138
|
} catch (t: Throwable) {
|
|
50
|
-
promise.reject(t)
|
|
139
|
+
promise.reject("GERTEC_RFID_ERROR", t.message, t)
|
|
51
140
|
}
|
|
52
141
|
}
|
|
53
142
|
|
|
@@ -55,13 +144,34 @@ class GertecImpl(
|
|
|
55
144
|
lines: Int,
|
|
56
145
|
promise: Promise
|
|
57
146
|
) {
|
|
58
|
-
|
|
147
|
+
try {
|
|
148
|
+
if (useNeo) {
|
|
149
|
+
ensureNeo().scrollPrinterPaper(lines, neoCallback(promise))
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
ensurePrinter().scrollPaper(lines, promise)
|
|
153
|
+
} catch (t: Throwable) {
|
|
154
|
+
promise.reject("GERTEC_PRINTER_ERROR", t.message, t)
|
|
155
|
+
}
|
|
59
156
|
}
|
|
60
157
|
|
|
61
158
|
fun printHtml(
|
|
62
159
|
html: String,
|
|
63
160
|
promise: Promise
|
|
64
161
|
) {
|
|
65
|
-
|
|
162
|
+
try {
|
|
163
|
+
if (useNeo) {
|
|
164
|
+
ensureNeo().printHtml(html, neoCallback(promise))
|
|
165
|
+
return
|
|
166
|
+
}
|
|
167
|
+
ensurePrinter().printHtml(html, promise)
|
|
168
|
+
} catch (t: Throwable) {
|
|
169
|
+
promise.reject("GERTEC_PRINTER_ERROR", t.message, t)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private companion object {
|
|
174
|
+
const val TAG = "MeSmartGertec"
|
|
175
|
+
const val GEDI_INIT_TIMEOUT_S = 5L
|
|
66
176
|
}
|
|
67
177
|
}
|
|
@@ -18,7 +18,7 @@ class GertecModule(
|
|
|
18
18
|
fun scanRfid(promise: Promise) {
|
|
19
19
|
try {
|
|
20
20
|
gertec.scanRfid(promise)
|
|
21
|
-
} catch (e:
|
|
21
|
+
} catch (e: Throwable) {
|
|
22
22
|
e.printStackTrace()
|
|
23
23
|
promise.reject(e)
|
|
24
24
|
}
|
|
@@ -28,7 +28,7 @@ class GertecModule(
|
|
|
28
28
|
fun cancelScan(promise: Promise) {
|
|
29
29
|
try {
|
|
30
30
|
gertec.cancelScan(promise)
|
|
31
|
-
} catch (e:
|
|
31
|
+
} catch (e: Throwable) {
|
|
32
32
|
e.printStackTrace()
|
|
33
33
|
promise.reject(e)
|
|
34
34
|
}
|
|
@@ -41,7 +41,7 @@ class GertecModule(
|
|
|
41
41
|
) {
|
|
42
42
|
try {
|
|
43
43
|
gertec.scrollPrinterPaper(lines, promise)
|
|
44
|
-
} catch (e:
|
|
44
|
+
} catch (e: Throwable) {
|
|
45
45
|
e.printStackTrace()
|
|
46
46
|
promise.reject(e)
|
|
47
47
|
}
|
|
@@ -54,7 +54,7 @@ class GertecModule(
|
|
|
54
54
|
) {
|
|
55
55
|
try {
|
|
56
56
|
gertec.printHtml(html, promise)
|
|
57
|
-
} catch (e:
|
|
57
|
+
} catch (e: Throwable) {
|
|
58
58
|
e.printStackTrace()
|
|
59
59
|
promise.reject(e)
|
|
60
60
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
package com.gertec
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.Process
|
|
5
|
+
import com.gertec.backend.GertecBackend
|
|
6
|
+
import dalvik.system.BaseDexClassLoader
|
|
7
|
+
import dalvik.system.DexClassLoader
|
|
8
|
+
import java.io.File
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Carrega o SDK Gertec Neo (libgedi 2.x) num classloader proprio, so na GPOS780S.
|
|
12
|
+
*
|
|
13
|
+
* O app usa a libgedi 1.16 nos demais POS e as duas tem as mesmas classes e o mesmo libgedi.so (JNI por nome,
|
|
14
|
+
* entao nao da p/ renomear pacote), por isso a Neo vai num dex a parte (assets/gertec-neo, ver gertec-neo/build.sh)
|
|
15
|
+
* e o libgedi.so dela fica fora de jniLibs, extraido p/ uma pasta que so esse classloader enxerga.
|
|
16
|
+
*/
|
|
17
|
+
internal object NeoSdkLoader {
|
|
18
|
+
private const val ASSET_DIR = "gertec-neo"
|
|
19
|
+
private const val ADAPTER_CLASS = "com.gertec.neo.NeoGertecBackend"
|
|
20
|
+
|
|
21
|
+
@Synchronized
|
|
22
|
+
fun load(context: Context): GertecBackend {
|
|
23
|
+
val abi = if (Process.is64Bit()) "arm64-v8a" else "armeabi-v7a"
|
|
24
|
+
val assets = context.assets
|
|
25
|
+
val version = assets.open("$ASSET_DIR/VERSION").bufferedReader().use { it.readText().trim() }
|
|
26
|
+
|
|
27
|
+
val root = File(context.codeCacheDir, "$ASSET_DIR/$version-$abi")
|
|
28
|
+
val jar = File(root, "neo-bridge.jar")
|
|
29
|
+
val libDir = File(root, "lib")
|
|
30
|
+
val so = File(libDir, "libgedi.so")
|
|
31
|
+
|
|
32
|
+
if (!jar.exists() || !so.exists()) {
|
|
33
|
+
File(context.codeCacheDir, ASSET_DIR).deleteRecursively()
|
|
34
|
+
libDir.mkdirs()
|
|
35
|
+
copyAsset(context, "$ASSET_DIR/neo-bridge.jar", jar)
|
|
36
|
+
copyAsset(context, "$ASSET_DIR/$abi/libgedi.so", so)
|
|
37
|
+
}
|
|
38
|
+
// Android 14+ recusa dex gravavel em DexClassLoader.
|
|
39
|
+
jar.setReadOnly()
|
|
40
|
+
|
|
41
|
+
val parent = GertecBackend::class.java.classLoader
|
|
42
|
+
?: throw IllegalStateException("Sem classloader do app para o SDK Gertec Neo")
|
|
43
|
+
val loader = ChildFirstDexClassLoader(jar.absolutePath, libDir.absolutePath, parent)
|
|
44
|
+
val adapter = loader.loadClass(ADAPTER_CLASS)
|
|
45
|
+
return adapter.getConstructor(Context::class.java).newInstance(context.applicationContext) as GertecBackend
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private fun copyAsset(context: Context, assetPath: String, dest: File) {
|
|
49
|
+
context.assets.open(assetPath).use { input ->
|
|
50
|
+
dest.outputStream().use { output -> input.copyTo(output) }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Classloader "filho primeiro": as classes do dex da Neo (br.com.gertec.*, gedi.*, ...) tem o mesmo nome das da 1.16
|
|
57
|
+
* que estao no app, entao procura no dex antes de perguntar ao pai. Plataforma, Kotlin, React Native e a interface
|
|
58
|
+
* com.gertec.backend continuam vindo do pai, para os tipos trocados entre os dois lados serem os mesmos.
|
|
59
|
+
*/
|
|
60
|
+
internal class ChildFirstDexClassLoader(
|
|
61
|
+
dexPath: String,
|
|
62
|
+
libPath: String,
|
|
63
|
+
parent: ClassLoader
|
|
64
|
+
) : DexClassLoader(dexPath, null, libPath, parent) {
|
|
65
|
+
|
|
66
|
+
override fun loadClass(name: String, resolve: Boolean): Class<*> {
|
|
67
|
+
synchronized(this) {
|
|
68
|
+
findLoadedClass(name)?.let { return it }
|
|
69
|
+
if (!isShared(name)) {
|
|
70
|
+
try {
|
|
71
|
+
val clazz = findClass(name)
|
|
72
|
+
if (resolve) resolveClass(clazz)
|
|
73
|
+
return clazz
|
|
74
|
+
} catch (_: ClassNotFoundException) {
|
|
75
|
+
// nao esta no dex da Neo: cai no pai
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return super.loadClass(name, resolve)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// O libgedi.so da Neo tem que vir daqui (nao da 1.16 do app); o resto (ex.: opencv) pode vir do pai.
|
|
83
|
+
override fun findLibrary(name: String): String? =
|
|
84
|
+
super.findLibrary(name) ?: (parent as? BaseDexClassLoader)?.findLibrary(name)
|
|
85
|
+
|
|
86
|
+
private fun isShared(name: String): Boolean = SHARED_PREFIXES.any { name.startsWith(it) }
|
|
87
|
+
|
|
88
|
+
private companion object {
|
|
89
|
+
val SHARED_PREFIXES = arrayOf(
|
|
90
|
+
"java.", "javax.", "android.", "androidx.", "dalvik.", "libcore.",
|
|
91
|
+
"kotlin.", "kotlinx.", "com.facebook.", "com.gertec.backend."
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package com.gertec.backend;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Contrato entre o modulo e o SDK Gertec "Neo" (libgedi 2.x), que roda num classloader isolado.
|
|
5
|
+
* A interface e o callback sao carregados pelo classloader do app (pai) e so usam tipos da plataforma,
|
|
6
|
+
* assim o adaptador carregado do dex da Neo consegue implementar sem depender de classes do React Native.
|
|
7
|
+
*/
|
|
8
|
+
public interface GertecBackend {
|
|
9
|
+
/** Resolve com o UID do cartao (byte[]). */
|
|
10
|
+
void scanRfid(GertecCallback callback);
|
|
11
|
+
|
|
12
|
+
/** Resolve com Boolean.TRUE. */
|
|
13
|
+
void cancelScan(GertecCallback callback);
|
|
14
|
+
|
|
15
|
+
/** Resolve com Boolean.TRUE. */
|
|
16
|
+
void scrollPrinterPaper(int lines, GertecCallback callback);
|
|
17
|
+
|
|
18
|
+
/** Resolve com Boolean.TRUE. */
|
|
19
|
+
void printHtml(String html, GertecCallback callback);
|
|
20
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.gertec.utils
|
|
2
2
|
|
|
3
|
+
import android.util.Log
|
|
3
4
|
import br.com.gertec.easylayer.contactless.MifareClassic
|
|
4
5
|
import com.facebook.react.bridge.Promise
|
|
5
6
|
import com.mesmart.Utils
|
|
@@ -33,7 +34,10 @@ class MifareGPOS780 {
|
|
|
33
34
|
} catch (e: Exception) {
|
|
34
35
|
val msg = e.message?.lowercase().orEmpty()
|
|
35
36
|
val isTimeoutLike = msg.contains("timeout") || msg.contains("polling")
|
|
36
|
-
if (!isTimeoutLike)
|
|
37
|
+
if (!isTimeoutLike) {
|
|
38
|
+
Log.e(TAG, "RFID connect failed: ${e.javaClass.name}: ${e.message}")
|
|
39
|
+
throw e
|
|
40
|
+
}
|
|
37
41
|
} finally {
|
|
38
42
|
try { mifare.close() } catch (_: Exception) {}
|
|
39
43
|
}
|
|
@@ -46,9 +50,11 @@ class MifareGPOS780 {
|
|
|
46
50
|
)
|
|
47
51
|
else -> promise.reject("Timeout to read RFID card!")
|
|
48
52
|
}
|
|
49
|
-
} catch (
|
|
50
|
-
e.
|
|
51
|
-
|
|
53
|
+
} catch (t: Throwable) {
|
|
54
|
+
// Throwable: falha da lib nativa e Error e, sem isso, a thread morre e a promise nunca resolve.
|
|
55
|
+
val message = "RFID scan threw ${t.javaClass.name}: ${t.message} (${Utils.deviceContext()})"
|
|
56
|
+
Log.e(TAG, message, t)
|
|
57
|
+
promise.reject("GERTEC_RFID_ERROR", message, t)
|
|
52
58
|
} finally {
|
|
53
59
|
try { mifare.close() } catch (_: Exception) {}
|
|
54
60
|
mifare = MifareClassic()
|
|
@@ -70,4 +76,8 @@ class MifareGPOS780 {
|
|
|
70
76
|
promise.reject(e)
|
|
71
77
|
}
|
|
72
78
|
}
|
|
79
|
+
|
|
80
|
+
private companion object {
|
|
81
|
+
const val TAG = "MeSmartGertec"
|
|
82
|
+
}
|
|
73
83
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
package com.gertec.utils
|
|
2
2
|
|
|
3
|
+
import android.util.Log
|
|
3
4
|
import br.com.gertec.easylayer.printer.Printer
|
|
4
5
|
import br.com.gertec.easylayer.printer.PrinterError
|
|
5
6
|
import com.facebook.react.bridge.Promise
|
|
6
7
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
|
+
import com.mesmart.Utils
|
|
7
9
|
|
|
8
10
|
class PrinterGPOS780(
|
|
9
11
|
private val reactContext: ReactApplicationContext
|
|
@@ -12,27 +14,48 @@ class PrinterGPOS780(
|
|
|
12
14
|
lines: Int,
|
|
13
15
|
promise: Promise
|
|
14
16
|
) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
}).scrollPaper(lines)
|
|
17
|
+
try {
|
|
18
|
+
Printer.getInstance(reactContext.applicationContext, listener(promise, "scrollPaper"))
|
|
19
|
+
.scrollPaper(lines)
|
|
20
|
+
} catch (t: Throwable) {
|
|
21
|
+
reject(promise, "scrollPaper", t)
|
|
22
|
+
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
fun printHtml(
|
|
26
26
|
html: String,
|
|
27
27
|
promise: Promise
|
|
28
28
|
) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
try {
|
|
30
|
+
Printer.getInstance(reactContext.applicationContext, listener(promise, "printHtml"))
|
|
31
|
+
.printHtml(reactContext.applicationContext, html)
|
|
32
|
+
} catch (t: Throwable) {
|
|
33
|
+
reject(promise, "printHtml", t)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private fun listener(promise: Promise, operation: String) = object : Printer.Listener {
|
|
38
|
+
override fun onPrinterError(printerError: PrinterError?) {
|
|
39
|
+
val message = "Printer $operation failed. Cause: ${printerError?.cause}, " +
|
|
40
|
+
"error code: ${printerError?.code}, request ID: ${printerError?.requestId} " +
|
|
41
|
+
"(${Utils.deviceContext()})"
|
|
42
|
+
Log.e(TAG, message)
|
|
43
|
+
promise.reject("GERTEC_PRINTER_ERROR", message)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
override fun onPrinterSuccessful(var1: Int) {
|
|
47
|
+
promise.resolve(true)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Throwable (e nao so Exception): falha da lib nativa (UnsatisfiedLinkError, NoClassDefFoundError) e Error.
|
|
52
|
+
private fun reject(promise: Promise, operation: String, t: Throwable) {
|
|
53
|
+
val message = "Printer $operation threw ${t.javaClass.name}: ${t.message} (${Utils.deviceContext()})"
|
|
54
|
+
Log.e(TAG, message, t)
|
|
55
|
+
promise.reject("GERTEC_PRINTER_ERROR", message, t)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private companion object {
|
|
59
|
+
const val TAG = "MeSmartGertec"
|
|
37
60
|
}
|
|
38
61
|
}
|
|
@@ -18,11 +18,21 @@ object Utils {
|
|
|
18
18
|
return Build.MODEL.equals("A910", true)
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
/** Cobre GPOS780 e GPOS780S (mesma familia Gertec
|
|
21
|
+
/** Cobre GPOS780 e GPOS780S (mesma familia Gertec). */
|
|
22
22
|
fun isGPOS780(): Boolean {
|
|
23
23
|
return Build.MODEL.startsWith("GPOS780", true)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/** GPOS780S: nao inicializa o GEDI da libgedi 1.16, usa o SDK Neo (ver com.gertec.NeoSdkLoader). */
|
|
27
|
+
fun isGPOS780S(): Boolean {
|
|
28
|
+
return Build.MODEL.startsWith("GPOS780S", true)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Contexto do aparelho p/ mensagens de erro do Gertec (modelo + Android), p/ debugar em campo. */
|
|
32
|
+
fun deviceContext(): String {
|
|
33
|
+
return "model=${Build.MODEL}, android=${Build.VERSION.RELEASE} (sdk ${Build.VERSION.SDK_INT})"
|
|
34
|
+
}
|
|
35
|
+
|
|
26
36
|
fun isT8(): Boolean {
|
|
27
37
|
return Build.MODEL.equals("T8", true)
|
|
28
38
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-mesmart",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Native methods for integrating with Sunmi P2-B/P2-A11 POS, Pax A910/A920, Pagbank's Plugpag payment SDK, Stone's payment SDK, and Paystore's payment SDK.",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
28
28
|
"clean": "del-cli android/build example/android/build example/android/app/build lib",
|
|
29
29
|
"prepare": "bob build",
|
|
30
|
-
"release": "release
|
|
30
|
+
"release": "bash scripts/release.sh"
|
|
31
31
|
},
|
|
32
32
|
"keywords": [
|
|
33
33
|
"react-native",
|