Zebra scanner Interleaved 2 of 5 cannot read - android

I have Zebra TC510K and I am developing an app on it in Kotlin. I am using this EMDK com.symbol:emdk:9.1.1. I am trying to scan Interleaved 2of5 barcode but the scanner doesn´t response.
My code is show below. This is only place where I set decodeParams.i2of5.enabled = true. Other types of barcodes works properly. Do you have somebody some idea what should be wrong?
override fun onStatus(statusData: StatusData) {
val state = statusData.state
when (state){
StatusData.ScannerStates.IDLE -> {
statusString = statusData.friendlyName + " je zapnuty a ceka...."
if (!scanner!!.isReadPending()) {
val scannerConfig = scanner!!.config
//Log.d("scanpr","Before${scannerConfig.decoderParams.i2of5.enabled.toString()}")
scannerConfig.decoderParams.i2of5.enabled = true
scannerConfig.decoderParams.code128.enabled = true
scannerConfig.decoderParams.code39.enabled = true
scannerConfig.decoderParams.code93.enabled = true
//Log.d("scanpr","After${scannerConfig.decoderParams.i2of5.enabled.toString()}")
//scanner!!.config(scannerConfig)
try {
scanner!!.read()
} catch (e: ScannerException) {
statusString = e.message.toString()
statusTextView!!.text = statusString
}
}
}
StatusData.ScannerStates.WAITING -> {
}
StatusData.ScannerStates.SCANNING -> {
}
StatusData.ScannerStates.DISABLED -> {
}
StatusData.ScannerStates.ERROR -> {
}
else -> {
}
}
}

I forget to add one line to setDecoder functionality: scanner!!.config = scannerConfig. To set config of scanner.
if (!scanner!!.isReadPending()) {
val scannerConfig = scanner!!.config
scannerConfig.decoderParams.i2of5.enabled = true
scannerConfig.decoderParams.code128.enabled = true
scannerConfig.decoderParams.code39.enabled = true
scannerConfig.decoderParams.code93.enabled = true
scanner!!.config = scannerConfig
try {
scanner!!.read()
} catch (e: ScannerException) {
statusString = e.message.toString()
statusTextView!!.text = statusString
}
}

Related

How to combine two serial flows which input depends on other output?

I have sophisticated scenario where a set of mutually dependent coroutine flows depends on each other and chained:
viewModelScope.launch {
repository.cacheAccount(person)
.flatMapConcat { it->
Log.d(App.TAG, "[2] create account call (server)")
repository.createAccount(person)
}
.flatMapConcat { it ->
if (it is Response.Data) {
repository.cacheAccount(it.data)
.collect { it ->
// no op, just execute the command
Log.d(App.TAG, "account has been cached")
}
}
flow {
emit(it)
}
}
.catch { e ->
Log.d(App.TAG, "[3] get an exception in catch block")
Log.e(App.TAG, "Got an exception during network call", e)
state.update { state ->
val errors = state.errors + getErrorMessage(PersonRepository.Response.Error.Exception(e))
state.copy(errors = errors, isLoading = false)
}
}
.collect { it ->
Log.d(App.TAG, "[4] collect the result")
updateStateProfile(it)
}
}
cache an account on the local disk
create an account on the backend
in positive scenario, cache the newly create account in the local disk
Now I have to add more calls to a new API endpoint and the scenario become even more sophisticated. This endpoint is a ethereum chain.
4a. In the positive scenario, put in the local disk (cache) initiated transaction cacheRepository.createChainTx()
4b. In the negative scenario, just emit further the response from the backend
4a.->5. Register user on the 2nd endpoint repository.registerUser()
The response from 2nd endpoint put in the cache by updating existing row. Even negative case except of exception should be cached to update status of tx.
viewModelScope.launch {
lateinit var newTx: ITransaction
cacheRepository.createChainTxAsFlow(RegisterUserTransaction(userWalletAddress = userWalletAddress))
.map { it ->
newTx= it
repository.registerUserOnSwapMarket(userWalletAddress)
}
.onEach { it -> preProcessResponse(it, newTx) }
.flowOn(backgroundDispatcher)
.collect { it -> processResponse(it) }
}
This a scenario which should be integrated into the 1st Flow chain.
The issue is I do not see how to do it clear in Flow chain. I can rewrite code without chaining, but it also bring variety if else statements.
How would you do this scenario in human readable way?
I'll ended up with this code for transition period:
viewModelScope.launch(backgroundDispatcher) {
try {
var cachedPersonProfile = repository.cacheAccount(person)
var createAccountResponse = repository.createAccount(person)
when(createAccountResponse) {
is Response.Data -> {
repository.cacheAccount(createAccountResponse.data)
val cachedTx = cacheRepository.createChainTx(RegisterUserTransaction(userWalletAddress = person.userWalletAddress))
val chainTx = walletRepository.registerUserOnSwapMarket(userWalletAddress = person.userWalletAddress)
when(chainTx) {
is ru.home.swap.core.network.Response.Data -> {
if (chainTx.data.isStatusOK()) {
cachedTx.status = TxStatus.TX_MINED
} else {
cachedTx.status = TxStatus.TX_REVERTED
}
}
is ru.home.swap.core.network.Response.Error.Message -> {
cachedTx.status = TxStatus.TX_EXCEPTION
}
is ru.home.swap.core.network.Response.Error.Exception -> {
cachedTx.status = TxStatus.TX_EXCEPTION
}
}
cacheRepository.createChainTx(cachedTx)
withContext(Dispatchers.Main) {
state.update { state ->
if (cachedTx.status == TxStatus.TX_MINED) {
state.copy(
isLoading = false,
profile = createAccountResponse.data,
status = StateFlagV2.PROFILE
)
} else {
val txError = "Failed register the profile on chain with status ${TxStatus.TX_MINED}"
state.copy(
isLoading = false,
errors = state.errors + txError
)
}
}
}
}
else -> { updateStateProfile(createAccountResponse) }
}
} catch (ex: Exception) {
withContext(Dispatchers.Main) {
state.update { state ->
val errors = state.errors + getErrorMessage(PersonRepository.Response.Error.Exception(ex))
state.copy(errors = errors, isLoading = false)
}
}
}
}
If you have a better alternative, please share it in the post as an answer.

Coroutine scope cancel

I know that there are a lot of posts "How to cancel Coroutines Scope" but I couldn't find the answer for my case.
I have an Array of objects that I want to send each of them to Server using Coroutines.
What I need is, if one of my requests returns error, canceling others.
Here is my code:
private fun sendDataToServer(function: () -> Unit) {
LiabilitiesWizardSessionManager.getLiabilityAddedDocuments().let { documents ->
if (documents.isEmpty().not()) {
CoroutineScope(Dispatchers.IO).launch {
documents.mapIndexed { index, docDetail ->
async {
val result = uploadFiles(docDetail)
}
}.map {
var result = it.await()
}
}
} else function.invoke()
}
}
Below is my uploadFiles() function:
private suspend fun uploadFiles(docDetail: DocDetail): ArchiveFileResponse? {
LiabilitiesWizardSessionManager.mCreateLiabilityModel.let { model ->
val file = File(docDetail.fullFilePath)
val crmCode = docDetail.docTypeCode
val desc = docDetail.docTypeDesc
val id = model.commitmentMember?.id
val idType = 1
val createArchiveFileModel = CreateArchiveFileModel(108, desc, id, idType).apply {
this.isLiability = true
this.adaSystem = 3
}
val result = mRepositoryControllerKotlin.uploadFile(file, createArchiveFileModel)
return when (result) {
is ResultWrapper.Success -> {
result.value
}
is ResultWrapper.GenericError -> {
null
}
is ResultWrapper.NetworkError -> {
null
}
}
}
}
I know, I'm missing something.

How to return to launch inside of the collect?

I have a method that looks like that:
private lateinit var cards: List<Card>
fun start() = viewModelScope.launch {
if (!::cards.isInitialized) {
getCards().collect { result ->
result
.doIfSuccess {
cards = it.data
Log.d(TAG, "Received cards")
}
.doIfError {
_errorState.setIfNotEqual(it.exception)
Log.e(TAG, "Cards were not received because of ${it.exception}")
return#collect // <--- that's the place
}
}
}
Log.d(TAG, "Message that needs to be shown only if cards were received")
if (сards.isEmpty()) {
Log.e(TAG, "Сards list is empty")
_errorState.setIfNotEqual(NoCardsException)
return#launch
}
val сard = сards[0]
}
I need to completely return from the method, not only from the .collect block, I've tried to use return#launch or some other custom labels, but it doesn't work even though Kotlin compiler suggests me to set it like that:
I think you can use transformWhile to create a new Flow that does an operation on each item you receive until you return false. Then collect that Flow. I didn't test this because I'm not really sure of how you've structured .doIfSuccess and .doIfError.
fun start() = viewModelScope.launch {
if (!::cards.isInitialized) {
getCards().transformWhile { result ->
result
.doIfSuccess {
cards = it.data
Log.d(TAG, "Received cards")
}
.doIfError {
_errorState.setIfNotEqual(it.exception)
Log.e(TAG, "Cards were not received because of ${it.exception}")
return#transformWhile false
}
return#transformWhile true
}.collect()
}
//...
}
EDIT:
If you only want the first value from the Flow, you could do this:
fun start() = viewModelScope.launch {
if (!::cards.isInitialized) {
getCards().first()
.doIfSuccess {
cards = it.data
Log.d(TAG, "Received cards")
}
.doIfError {
_errorState.setIfNotEqual(it.exception)
Log.e(TAG, "Cards were not received because of ${it.exception}")
return#launch
}
}
//...
}

Detect 5G connection on Android phone

I'm trying to identify the type of cellular connection.
I've used different methods, like for example the one suggested here, but I keep getting 4G as a result, on a Samsung with Android 10 and 5G connection.
How is it possible to read the correct network type?
private fun getNetworkType(telephonyManager: TelephonyManager): String {
return when (telephonyManager.networkType) {
TelephonyManager.NETWORK_TYPE_UNKNOWN -> "unknown"
TelephonyManager.NETWORK_TYPE_GPRS,
TelephonyManager.NETWORK_TYPE_EDGE,
TelephonyManager.NETWORK_TYPE_CDMA,
TelephonyManager.NETWORK_TYPE_1xRTT,
TelephonyManager.NETWORK_TYPE_IDEN,
TelephonyManager.NETWORK_TYPE_GSM -> "2G"
TelephonyManager.NETWORK_TYPE_UMTS,
TelephonyManager.NETWORK_TYPE_EVDO_0,
TelephonyManager.NETWORK_TYPE_EVDO_A,
TelephonyManager.NETWORK_TYPE_HSDPA,
TelephonyManager.NETWORK_TYPE_HSUPA,
TelephonyManager.NETWORK_TYPE_HSPA,
TelephonyManager.NETWORK_TYPE_EVDO_B,
TelephonyManager.NETWORK_TYPE_EHRPD,
TelephonyManager.NETWORK_TYPE_HSPAP,
TelephonyManager.NETWORK_TYPE_TD_SCDMA -> "3G"
TelephonyManager.NETWORK_TYPE_LTE,
TelephonyManager.NETWORK_TYPE_IWLAN -> "4G"
TelephonyManager.NETWORK_TYPE_NR -> "5G"
else -> "something else"
}
}
private fun getRadioTechnology(telephonyManager: TelephonyManager): String {
try {
val obj = Class.forName(telephonyManager.javaClass.name)
.getDeclaredMethod("getServiceState", *arrayOfNulls(0)).invoke(telephonyManager, *arrayOfNulls(0))
val methods: Array<Method> = Class.forName(obj.javaClass.name).declaredMethods
for (method in methods) {
if (method.name == "getRadioTechnology" ) {
method.isAccessible = true
val radioTechnology = (method.invoke(obj) as Int).toInt()
return "$radioTechnology"
}
}
} catch (e: Exception) {
Log.e("Test5G", "", e)
}
return ""
}
#SuppressLint("MissingPermission")
fun getActiveSubscriptionInfoList(): String {
val subscriptionInfos = SubscriptionManager.from(this).activeSubscriptionInfoList
var ret: String = ""
for(sub in subscriptionInfos) {
val id = sub.subscriptionId
val telephonyManager = telephonyManager.createForSubscriptionId(id);
ret += getRadioTechnology(telephonyManager)
}
return ret
}
This is how I did it:
telephonyManager.listen(object : PhoneStateListener() {
override fun onServiceStateChanged(serviceState: ServiceState) {
val isNrAvailable = serviceState.toString().isNrAvailable()
// use isNrAvailable
}
}, PhoneStateListener.LISTEN_SERVICE_STATE)
Where
fun String.isNrAvailable() =
contains("nrState=CONNECTED") ||
contains("nsaState=5"))

Illegal StateException Error

I recently migrated from Java to Kotlin and converted my app's code into kotlin code and published the changes.But now some users are reporting that there app is force stopping. But me and the tested devices are not facing the issue. When I checked the crashes page. It is showing this:
And this is the DatabaseHelper Class Code with line 1018
fun getNotes(sqlCommand: String): MutableList<Note> {
val result = ArrayList<Note>()
val db = this.readableDatabase
Log.e(LOG, sqlCommand)
val cursor = db.rawQuery(sqlCommand, null)
try {
if (cursor!!.moveToFirst()) {
do {
val note = Note()
note.id = cursor.getLong(cursor.getColumnIndex(KEY_ID))
note.title = DataEncryption.encryptDecrypt(cursor.getString(cursor.getColumnIndex(KEY_TITLE)))
note.content = DataEncryption.encryptDecrypt(cursor.getString(cursor.getColumnIndex(KEY_CONTENT)))
note.updatedAt = Date(cursor.getLong(cursor.getColumnIndex(KEY_UPDATED_AT)))
note.color = cursor.getInt(cursor.getColumnIndex(KEY_COLOR))
note.favourite = cursor.getInt(cursor.getColumnIndex(KEY_FAVOURITE))
if (cursor.isNull(cursor.getInt(cursor.getColumnIndex(KEY_LOCKSTATUS)))) {
note.lock_status = 0
} else {
note.lock_status = cursor.getInt(cursor.getColumnIndex(KEY_LOCKSTATUS))
}
note.reminderDate = cursor.getString(cursor.getColumnIndex(KEY_REMINDER_DATE))
note.reminderTime = cursor.getString(cursor.getColumnIndex(KEY_REMINDER_TIME))
if (cursor.isNull(cursor.getInt(cursor.getColumnIndex(KEY_REMINDER_STATUS)))) {
note.reminderStatus = 0
} else {
note.reminderStatus = cursor.getInt(cursor.getColumnIndex(KEY_REMINDER_STATUS))
}
note.noteCategoryTitle = cursor.getString(cursor.getColumnIndex(KEY_CATEGORY_NOTE_TITLE))
note.noteCategoryStatus = cursor.getInt(cursor.getColumnIndex(KEY_CATEGORY_NOTE_STATUS))
note.checklist = cursor.getInt(cursor.getColumnIndex(KEY_CHECKLIST))
if (cursor.isNull(cursor.getInt(cursor.getColumnIndex(KEY_ALARM_REPEAT_STATUS)))) {
note.alarmRepeatStatus = 0
} else {
note.alarmRepeatStatus = cursor.getInt(cursor.getColumnIndex(KEY_ALARM_REPEAT_STATUS))
}
result.add(note)
} while (cursor.moveToNext())
}
} finally {
cursor?.close()
}
return result
}
Someone please help me with a solution. Help is high appreciated.

Categories

Resources