Illegal StateException Error - android

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.

Related

How to return a List field as an empty list "[]" in Android Studio?

So I have been tackling this issue for a couple of days now. I have a Data class that is used to send information back into the API. In this instance, I have this x amount of fields. In these fields, there are three List fields with different types, as such.
The Data Classes
data class ApiSurveySiteUpdateBody(
#SerializedName("UserId") val userId: Int,
#SerializedName("SStatusId") val sStatusId: Int,
#SerializedName("SSId") val sSId: Int,
#SerializedName("SPONum") val sPoNum: Int,
#SerializedName("WorkPerformanceTypeId") val workPerformTypeId: Int,
#SerializedName("SSAddressId") val sSAddressId: Int,
#SerializedName("WorktoPerformDate") val workToBePerformedDate: String,
#SerializedName("CableRun") val cableRun: String,
#SerializedName("Entrance") val entranceInfo: String,
#SerializedName("DoorLockHardware") val doorLockHardware: String,
#SerializedName("HandicapOperator") val handicapOperator: String,
#SerializedName("DeviceComplete") val completedPrimaryDeviceList: List<Int>,
#SerializedName("TemplateId") val templateId: Int,
#SerializedName("NewDeviceList") val newDeviceList: List<ApiNewDeviceList> = emptyList(),
#SerializedName("UpdateDeviceList") val updateDeviceList: List<ApiUpdateDeviceList> = emptyList(),
#SerializedName("RemoveDeviceList") val removedDeviceList: List<ApiRemovedDeviceList> = emptyList()
)
The Converter function
private fun getSomeRequestBody(
dbInfo: DbFormWithEList,
apiSurveySiteMedias: List<ApiSSMediaInfo>
)
: ApiSSUpdateBody {
val updateRequestApi = ApiSSUpdateBody(
userId = dbInfo.sSDbInfo.userId,
sSId = dbInfo.sSDbInfo.sSId,
sStatusId = dbInfo.sStatusDbInfo.sSId,
sPoNum = dbInfo.sSDbInfo.sPoNumber,
workPerformTypeId = dbInfo.sSDbInfo.workPerformTypeId,
sSAddressId = dbInfo.sSDbInfo.sSAddressId,
workToBePerformedDate = dbInfo.sSDbInfo.workToBePerformedDate,
cableRun = dbInfo.sSDbInfo.cableRun,
entranceInfo = dbInfo.sSDbInfo.entranceInfo,
doorLockHardware = dbInfo.sSDbInfo.doorLockHardware,
handicapOperator = dbInfo.sSDbInfo.handicapOperator,
completedPrimaryDeviceList = dbInfo.sSDbInfo.completedPrimaryDeviceList.toIntList(),
templateId = dbInfo.sSDbInfo.templateId,
newDeviceList = List(dbInfo.equipmentList.size) { i -> // “NewDeviceList”
val dbEquipmentInfo = dbInfo.equipmentList[i].sSEquipmentDbInfo
Log.d(TAG, "NewDeviceListDB $dbEquipmentInfo")
val secondaryDeviceCheckedStatus = dbEquipmentInfo.secondaryDeviceCheckedStatus
val isDuplicateDeviceInUpdatePhase = dbEquipmentInfo.isDeviceUpdateMode
if (sDeviceCheckedS == CHECKED_YES && !isDuplicateDUP){
val newDeviceListRequestBody = ApiNewDeviceList(
secondaryDeviceId = dbEquipmentInfo.secondaryDeviceId,
deviceInstanceId = dbEquipmentInfo.deviceInstanceId.toString(),
mediaNameList = dbEquipmentInfo.mediaNames,
deviceSerialNumber = dbEquipmentInfo.deviceSerialNumber,
devicePartNumber = dbEquipmentInfo.devicePartNumber,
deviceManufacturerName = dbEquipmentInfo.deviceManufacturer,
deviceInstallationDate = DateUtil.dateToStringUTCSS(dbEquipmentInfo.deviceInstallationDate),
deviceLocation = dbEquipmentInfo.locationInfo,
deviceTechnicianNotes = dbEquipmentInfo.deviceTechnicianNotes
)
Log.d(TAG, "newDeviceListRequestBodyAPI $newDeviceListRequestBody")
newDeviceListRequestBody
}
else if (sDeviceCheckedS == CHECKED_NO){
apiDeviceListMapperUpdateSS.sendDeviceNotExistsInNewDeviceList(dbEquipmentInfo)
}
else {
apiDeviceListMapperUpdateSS.sendEmptyNewDeviceList()
}
},
updateDeviceList = (List(dbInfo.equipmentList.size) { i ->
val dbEquipmentInfo = dbInfo.equipmentList[i].sSEquipmentDbInfo
Log.d("UpdatingSiteSurvey", "UpdateDeviceListDB $dbEquipmentInfo")
val secondaryDeviceCheckedStatus = dbEquipmentInfo.secondaryDeviceCheckedStatus
val isDuplicateDeviceInUpdatePhase = dbEquipmentInfo.isDeviceUpdateMode
if (secondaryDeviceCheckedStatus == CHECKED_YES && isDuplicateDeviceInUpdatePhase){
val updateDeviceListRequestBody = ApiUpdateDeviceList(
deviceEquipmentId = dbEquipmentInfo.deviceEquipmentId,
secondaryDeviceId = dbEquipmentInfo.secondaryDeviceId,
deviceInstanceId = dbEquipmentInfo.deviceInstanceId.toString(),
deviceSerialNumber = dbEquipmentInfo.deviceSerialNumber,
devicePartNumber = dbEquipmentInfo.devicePartNumber,
deviceManufacturerName = dbEquipmentInfo.deviceManufacturer,
deviceInstallationDate = DateUtil.dateToStringUTCSiteSurvey(dbEquipmentInfo.deviceInstallationDate),
deviceLocation = dbEquipmentInfo.locationInfo,
deviceTechnicianNotes = dbEquipmentInfo.deviceTechnicianNotes
)
Log.d(TAG, "updateDeviceListRequestBodyAPI $updateDeviceListRequestBody")
updateDeviceListRequestBody
} else Unit.apply { } //<- the issue is here
}) as List<ApiUpdateDeviceList>,
removedDeviceList = List(dbInfo.sSDbInfo.removedDeviceList.size) { i ->
val dbRemovedMediaItem = dbInfo.sSDbInfo.removedDeviceList[i]
Log.d(TAG, "RemovedListDB $dbRemovedMediaItem")
if (dbRemovedMediaItem.removedDeviceEquipmentId == null && dbRemovedMediaItem.removedMediaName.isNullOrEmpty()){
val removeDevice = apiDeviceListMapperUpdateSiteSurvey.removeDevice(dbRemovedMediaItem)
Log.d(TAG, "removeDevice $removeDevice")
removeDevice
}else{
val removeMediaForExistingDevice = apiDeviceListMapperUpdateSS.removeMediaForExistingDevice(dbRemovedMediaItem)
Log.d(TAG, "removeMediaForExistingDevice $removeMediaForExistingDevice")
removeMediaForExistingDevice
}
}
)
Log.d(TAG, "MainUpdateRequestAPI $updateRequestApi")
return updateRequestApi
}
The goal is to have the else statement that is highlighted to return an emptyList "[]" to that updateDeviceList field. I have tried a few ways but never was able to return that exact empty list "[]". Any help will be appreciated. Thank you.
I can't tell if you want (1) the whole list to be invalidated and become empty if any item in the iteration fails the if check, or if you just want (2) to filter out items that fail the if check. But here's how I would approach each of those tasks.
I am breaking out the conversion between DbEquipmentInfo and ApiUpdateDeviceList into a separate extension function (fun DbEquipmentInfo.toApiUpdateDeviceList(): ApiUpdateDeviceList). Not just to avoid code repetition, but also to keep the logic code easy to read, and make the project's code more maintainable in general.
1.
val isValid = dbInfo.equipmentList.all { dbEquipmentInfo ->
val secondaryDeviceCheckedStatus = dbEquipmentInfo.secondaryDeviceCheckedStatus
val isDuplicateDeviceInUpdatePhase = dbEquipmentInfo.isDeviceUpdateMode
secondaryDeviceCheckedStatus == CHECKED_YES && isDuplicateDeviceInUpdatePhase
}
updateDeviceList =
if (isValid) dbInfo.equipmentList.map { it.toApiUpdateDeviceList() }
else emptyList()
updateDeviceList = dbInfo.equipmentList.filter { dbEquipmentInfo ->
val secondaryDeviceCheckedStatus = dbEquipmentInfo.secondaryDeviceCheckedStatus
val isDuplicateDeviceInUpdatePhase = dbEquipmentInfo.isDeviceUpdateMode
secondaryDeviceCheckedStatus == CHECKED_YES && isDuplicateDeviceInUpdatePhase
}.map { it.toApiUpdateDeviceList() }

How to test ViewModel + Flow

I'm doing a small project to learn flow and the latest Android features, and I'm currently facing the viewModel's testing, which I don't know if I'm performing correctly. can you help me with it?
Currently, I am using a use case to call the repository which calls a remote data source that gets from an API service a list of strings.
I have created a State to control the values in the view model:
data class StringItemsState(
val isLoading: Boolean = false,
val items: List<String> = emptyList(),
val error: String = ""
)
and the flow:
private val stringItemsState = StringtemsState()
private val _stateFlow = MutableStateFlow(stringItemsState)
val stateFlow = _stateFlow.asStateFlow()
and finally the method that performs all the logic in the viewModel:
fun fetchStringItems() {
try {
_stateFlow.value = stringItemsState.copy(isLoading = true)
viewModelScope.launch(Dispatchers.IO) {
val result = getStringItemsUseCase.execute()
if (result.isEmpty()) {
_stateFlow.value = stringItemsState
} else {
_stateFlow.value = stringItemsState.copy(items = result)
}
}
} catch (e: Exception) {
e.localizedMessage?.let {
_stateFlow.value = stringItemsState.copy(error = it)
}
}
}
I am trying to perform the test following the What / Where / Then pattern, but the result is always an empty list and the assert verification always fails:
private val stringItems = listOf<String>("A", "B", "C")
#Test
fun `get string items - not empty`() = runBlocking {
// What
coEvery {
useCase.execute()
} returns stringItems
// Where
viewModel.fetchStringItems()
// Then
assert(viewModel.stateFlow.value.items == stringItems)
coVerify(exactly = 1) { viewModel.fetchStringItems() }
}
Can someone help me and tell me if I am doing it correctly? Thanks.

Zebra scanner Interleaved 2 of 5 cannot read

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
}
}

Spek Unit Test Failing on Bitrise

I have written a unit test, based on Spek Framework, for one of my use cases. Following is the use case code:
class InsertRemoteWidgetUseCase(
private val remoteConfigProviderImplement: RemoteConfigProviderImplement,
private val feedDataStore: FeedDataStoreImplement
) {
fun invoke(): ArrayList<FeedData> {
if (remoteConfigProviderImplement.getHomeWidgetVisible()) {
val cardData = CardData()
cardData.url = remoteConfigProviderImplement.getHomeWidgetURL()
val feedData = FeedData()
feedData.type = CardType.REMOTE_CONFIG_WIDGET
feedData.listData = arrayListOf(cardData)
feedDataStore.insertRemoteWidgetCard(feedData)
} else {
feedDataStore.removeRemoteWidgetCard()
}
return feedDataStore.getData()
}
}
Here is the test case implementation:
class InsertRemoteWidgetUseCaseTest : Spek({
lateinit var mockRemoteConfigProviderImplement: RemoteConfigProviderImplement
lateinit var mockFeedDataStoreImplement: FeedDataStoreImplement
lateinit var instance: InsertRemoteWidgetUseCase
val feedComponentData1: FeedComponentData = mockk(relaxed = true)
val feedComponentData2: FeedComponentData = mockk(relaxed = true)
var remoteWidgetUrl = ""
var remoteWidgetVisible = false
val feedDataList1 = arrayListOf(
FeedData(listItems = arrayListOf(
CardItem(articleData = ArticleData(title = "A0"))
)
),
FeedData(listItems = arrayListOf(
CardItem(articleData = ArticleData(title = "B0")),
CardItem(articleData = ArticleData(title = "B1")),
CardItem(articleData = ArticleData(title = "B2"))
))
)
val feedDataList2 = arrayListOf(FeedData())
val pagination1 = Pagination(current = 0, next = 1)
val pagination2 = Pagination(current = 1, next = 2)
beforeEachTest {
every{feedComponentData1.pagination} returns pagination1
every{feedComponentData1.feedList} returns feedDataList1
every{feedComponentData2.pagination} returns pagination2
every{feedComponentData2.feedList} returns feedDataList2
mockRemoteConfigProviderImplement = mockk(relaxed = true)
mockFeedDataStoreImplement = spyk(FeedDataStoreImplement())
instance = spyk(InsertRemoteWidgetUseCase(mockRemoteConfigProviderImplement, mockFeedDataStoreImplement))
}
describe("invoke()") {
context("getHomeWidgetVisible is true") {
it("FeedData with CardType.REMOTE_CONFIG_WIDGET is inserted") {
remoteWidgetUrl = "www.google.com"
remoteWidgetVisible = true
every { mockRemoteConfigProviderImplement.getHomeWidgetURL() } returns remoteWidgetUrl
every { mockRemoteConfigProviderImplement.getHomeWidgetVisible() } returns remoteWidgetVisible
mockFeedDataStoreImplement.update(feedComponentData1)
mockFeedDataStoreImplement.update(feedComponentData2)
val feedDataListBefore = mockFeedDataStoreImplement.getData()
val feedDataListAfter = instance.invoke()
assert(feedDataListAfter[0].type == CardType.REMOTE_CONFIG_WIDGET)
assert(feedDataListBefore.size == feedDataListAfter.size + 1)
}
}
context("getHomeWidgetVisible is false") {
it("FeedData with CardType.REMOTE_CONFIG_WIDGET is removed") {
remoteWidgetUrl = "www.google.com"
remoteWidgetVisible = false
every { mockRemoteConfigProviderImplement.getHomeWidgetURL() } returns remoteWidgetUrl
every { mockRemoteConfigProviderImplement.getHomeWidgetVisible() } returns remoteWidgetVisible
mockFeedDataStoreImplement.update(feedComponentData1)
mockFeedDataStoreImplement.update(feedComponentData2)
val feedData = FeedData()
feedData.type = CardType.REMOTE_CONFIG_WIDGET
mockFeedDataStoreImplement.insertRemoteWidgetCard(feedData)
val feedDataListBefore = mockFeedDataStoreImplement.getData()
val feedDataListAfter = instance.invoke()
assert(feedDataListAfter[0].type != CardType.REMOTE_CONFIG_WIDGET)
assert(feedDataListBefore[0].type == CardType.REMOTE_CONFIG_WIDGET)
assert(feedDataListBefore.size == feedDataListAfter.size - 1)
}
}
}
})
The test cases in question runs successfully in local system. But with Bitrise, both of them fails with following:
java.lang.AssertionError: Assertion failed
at sg.com.sph.appbt.views.bnavigation.home.InsertRemoteWidgetUseCaseTest$1$2$1$1.invoke(InsertRemoteWidgetUseCaseTest.kt:74)
at sg.com.sph.appbt.views.bnavigation.home.InsertRemoteWidgetUseCaseTest$1$2$1$1.invoke(InsertRemoteWidgetUseCaseTest.kt:17)
at org.spekframework.spek2.runtime.scope.TestScopeImpl.execute(Scopes.kt:94)
at org.spekframework.spek2.runtime.Executor$execute$$inlined$executeSafely$lambda$1$1.invokeSuspend(Executor.kt:52)
at ???(Coroutine boundary.?(?)
at kotlinx.coroutines.DeferredCoroutine.await$suspendImpl(Builders.common.kt:99)
at org.spekframework.spek2.runtime.ExecutorsKt$doRunBlocking$1.invokeSuspend(executors.kt:8)
Caused by: java.lang.AssertionError: Assertion failed
at sg.com.sph.appbt.views.bnavigation.home.InsertRemoteWidgetUseCaseTest$1$2$1$1.invoke(InsertRemoteWidgetUseCaseTest.kt:74)
at sg.com.sph.appbt.views.bnavigation.home.InsertRemoteWidgetUseCaseTest$1$2$1$1.invoke(InsertRemoteWidgetUseCaseTest.kt:17)
at org.spekframework.spek2.runtime.scope.TestScopeImpl.execute(Scopes.kt:94)
at org.spekframework.spek2.runtime.Executor$execute$$inlined$executeSafely$lambda$1$1.invokeSuspend(Executor.kt:52)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:740)
Problem Statement
This executes well at local system without errors but fails with Bitrise on cloud.
Is there any silver bullet solution for this local vs remote issue.
Could this be due to different environment, if yes then which all components's versions should be checked.

How to access a TextView from a non-parent file [Android]

I want to access and change the text of a TextView from a non parent file.
This is the class I would like to make the edits from
class BarcodeProcessor(graphicOverlay: GraphicOverlay, private val workflowModel: WorkflowModel) :
FrameProcessorBase<List<FirebaseVisionBarcode>>() {
In this class there is no onCreat()
Do I need to have AppCompatActivity() in order to gain access to the xml layout files?
Inside this file is where the barcode is processed and I can display the results along with a SQL query to the console, but I want to update the interface to reflect those values. Can I pass them through the companion oject to the parent class?
Is there any way I can make the layout updates from the BarcodeProcessor file?
I've tried including imports
import kotlinx.android.synthetic.main.barcode_field.*
#MainThread
override fun onSuccess(
image: FirebaseVisionImage,
results: List<FirebaseVisionBarcode>,
graphicOverlay: GraphicOverlay
) {
var z = ""
var isSuccess: Boolean? = false
//Variables used in the SQL query
var strData = ""
var strData2 = ""
try {
con = dbConn() // Connect to database
if (con == null) {
z = "Check Your Internet Access!"
} else {
val query = "select [ValueOne], [ValueTwo] from [TableName] where [ValueOne] = '$barcodeValue'"
val stmt = con!!.createStatement()
val cursor = stmt.executeQuery(query)
barcodeValue = results[0].getRawValue()!!
println(barcodeValue)
if (cursor.next()) {
//Selects the values from the columns in the table where the query is taking place
strData = cursor.getString("[ValueOne]")
strData2 = cursor.getString("[ValueTwo]")
var finalDispositionID = strData
var moduleSizeID = strData2
println(finalDispositionID)
println(moduleSizeID)
//barcode_field_value3 is the name of the textview
//barcode_field_value2 is the name of the other textview
//barcode_field_value3.text = strData
z = "Login successful"
isSuccess = true
con!!.close()
} else {
z = "Invalid Credentials!"
isSuccess = false
}
}
} catch (ex: java.lang.Exception) {
isSuccess = false
z = ex.message!!
}
The query happens in the function onSuccess(). I included the entire file for reference though.
LiveBarcodeScanningActivity
private fun setUpWorkflowModel() {
workflowModel = ViewModelProviders.of(this).get(WorkflowModel::class.java)
// Observes the workflow state changes, if happens, update the overlay view indicators and
// camera preview state.
workflowModel!!.workflowState.observe(this, Observer { workflowState ->
if (workflowState == null || Objects.equal(currentWorkflowState, workflowState)) {
return#Observer
}
currentWorkflowState = workflowState
Log.d(TAG, "Current workflow state: ${currentWorkflowState!!.name}")
val wasPromptChipGone = promptChip?.visibility == View.GONE
when (workflowState) {
WorkflowState.DETECTING -> {
promptChip?.visibility = View.VISIBLE
promptChip?.setText(R.string.prompt_point_at_a_barcode)
startCameraPreview()
}
WorkflowState.CONFIRMING -> {
promptChip?.visibility = View.VISIBLE
promptChip?.setText(R.string.prompt_move_camera_closer)
startCameraPreview()
}
WorkflowState.SEARCHING -> {
promptChip?.visibility = View.VISIBLE
promptChip?.setText(R.string.prompt_searching)
stopCameraPreview()
}
WorkflowState.DETECTED, WorkflowState.SEARCHED -> {
promptChip?.visibility = View.GONE
stopCameraPreview()
}
else -> promptChip?.visibility = View.GONE
}
val shouldPlayPromptChipEnteringAnimation = wasPromptChipGone && promptChip?.visibility == View.VISIBLE
promptChipAnimator?.let {
if (shouldPlayPromptChipEnteringAnimation && !it.isRunning) it.start()
}
})
workflowModel?.detectedBarcode?.observe(this, Observer { barcode ->
if (barcode != null) {
val barcodeFieldList = ArrayList<BarcodeField>()
barcodeFieldList.add(BarcodeField("Module Serial Number", barcode.rawValue ?: ""))
BarcodeResultFragment.show(supportFragmentManager, barcodeFieldList)
}
})
}```
You are setting workflowModel.detectedBarcode live data in BarcodeProcessor. So you can find where you are passing this workflowModel to BarcodeProcessor constructor and add such a code to observe this live data in your activtiy:
workflowModel.detectedBarcode.observe(this, Observer {
myTextView.text = it
})
This answer pertains directly to displaying results in the Google ML-Kit Showcase sample project. So if your working on that with barcode scanning this is related.
In order to display the results on successful scan you need to add the fields into the
BarcodeFieldAdapter file
internal class BarcodeFieldViewHolder private constructor(view: View) : RecyclerView.ViewHolder(view) {
private val labelView: TextView = view.findViewById(R.id.barcode_field_label)
private val valueView: TextView = view.findViewById(R.id.barcode_field_value)
private val moduleSize: TextView = view.findViewById(R.id.textViewModuleSize)
private val finalDisposition: TextView = view.findViewById(R.id.textViewFinalDisp)
private val NCRNotes: TextView = view.findViewById(R.id.textViewNCR)
private val OverlapLengthText: TextView = view.findViewById((R.id.textViewOverlapLength))
fun bindBarcodeField(barcodeField: BarcodeField) {
//These are the original values that display in the Barcode_field.xml
labelView.text = barcodeField.label
valueView.text = barcodeField.value
//These are the new values I passed in
moduleSize.text = BarcodeProcessor.data.moduleSize
finalDisposition.text = BarcodeProcessor.data.finalDisposition
NCRNotes.text = BarcodeProcessor.data.NCRNotes
OverlapLengthText.text = BarcodeProcessor.data.OverlapLength
}
Inside
BarcodeProcessor
declare a data object
object data {
var finalDisposition = "init"
var moduleSize = "init"
var barcodeValue: String = ""
var NCRNotes = ""
var OverlapLength = ""
}
These variables will be passed into the BarcodeFieldAdapter file above then displayed in the barcode_field.xml on success.
Inside the query function - That is in the BarcodeProcessor file
//Selects the values from the columns in the table where the query is taking place
strData = cursor.getString("Column Name 1")
strData2 = cursor.getString("Column Name 2")
strData4 = cursor.getString("Column Name 3")
//Assigns the values to the variables inside the object data
data.finalDisposition = strData
data.moduleSize = strData2
data.OverlapLength = strData4
data.NCRNotes = ""
Finally, inside the barcode_field.xml file, create TextViews with the (R.id.TextViewNAMES) that are shown above in the BarcodeFieldAdapter file. Now on successful scanning the new values from the query will be displayed.

Categories

Resources