added permission support for USB & established a connection using service

This commit is contained in:
vsuryakumar
2023-01-23 23:02:39 +05:30
parent 37545a82e1
commit dc52b14335
31 changed files with 541 additions and 156 deletions

View File

@@ -17,34 +17,39 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.RefactoredApp" android:theme="@style/Theme.RefactoredApp"
tools:targetApi="31"> tools:targetApi="31">
<service <service
android:name=".UsbService" android:name=".presentation.testRight.UsbService"
android:enabled="true" android:enabled="true"
android:exported="true"></service> android:exported="false" />
<activity <activity
android:name=".presentation.SplashActivity" android:name=".presentation.SplashActivity"
android:exported="true"> android:exported="true"
android:theme="@style/AppTheme.NoActionBar"
android:noHistory="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".presentation.TestRight.TestRightActivity" android:name=".presentation.testRight.TestRightActivity"
android:exported="false" /> android:exported="false">
<activity
android:name=".presentation.MainActivity"
android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<meta-data <meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" /> android:resource="@xml/device_filter" />
</activity> </activity>
<activity
android:name=".presentation.MainActivity"
android:exported="true">
</activity>
</application> </application>
</manifest> </manifest>

View File

@@ -1,6 +1,10 @@
package com.example.refactoredapp package com.example.refactoredapp
import android.app.Application import android.app.Application
import android.graphics.Color
import android.graphics.PorterDuff
import android.view.View
import android.widget.Button
import com.example.refactoredapp.data.model.SampleDetails import com.example.refactoredapp.data.model.SampleDetails
class MyApplication : Application() { class MyApplication : Application() {
@@ -8,4 +12,5 @@ class MyApplication : Application() {
private val sampleDetails = SampleDetails("Change it later"); private val sampleDetails = SampleDetails("Change it later");
fun getSampleDetails() : SampleDetails = sampleDetails fun getSampleDetails() : SampleDetails = sampleDetails
// fun setSampleDetails(sample: SampleDetails) {sampleDetails = sample} // fun setSampleDetails(sample: SampleDetails) {sampleDetails = sample}
} }

View File

@@ -2,4 +2,8 @@ package com.example.refactoredapp.data
object Constants { object Constants {
const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION" const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION"
const val WRITE_TIMEOUT_MILLIS = 60000 // 1 min
const val READ_TIMEOUT_MILLIS = 60000 // 1 min
} }

View File

@@ -3,4 +3,6 @@ package com.example.refactoredapp.data
object DataHolder { object DataHolder {
var isStoragePermissionGranted = false var isStoragePermissionGranted = false
var isAppFolderCreated = false var isAppFolderCreated = false
var isReferenceTaken = false
} }

View File

@@ -1,8 +0,0 @@
package com.example.refactoredapp.data.model
data class DenovixData(
val serialNumber: Int,
val nameSample: String,
val ratio: Double,
val result: String
)

View File

@@ -0,0 +1,19 @@
package com.example.refactoredapp.data.model
//class TestRightCmdConstants {
//
// companion object {
// const val readCommand = "read\r"
// const val autosetCommand = "autoset\r"
// const val printCommand = "print\r"
// const val runCommand = "run\r"
// }
//
//}
enum class TestRightCommands(val command: String) {
read("read\r"),
autoset("autoset\r"),
print("print 239 2719\r"),
print_all("print\r"),
}

View File

@@ -0,0 +1,8 @@
package com.example.refactoredapp.data.model
data class TestRightDeviceConstants(
val a: String,
val b: String,
val c: String,
val d: String
)

View File

@@ -1,40 +1,13 @@
package com.example.refactoredapp.presentation package com.example.refactoredapp.presentation
import android.Manifest
import android.app.PendingIntent
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.net.Uri
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.util.Log
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.example.refactoredapp.R
import com.example.refactoredapp.data.Constants
import com.example.refactoredapp.databinding.ActivityMainBinding import com.example.refactoredapp.databinding.ActivityMainBinding
import com.example.refactoredapp.presentation.TestRight.TestRightActivity import com.example.refactoredapp.presentation.testRight.TestRightActivity
import com.example.refactoredapp.util.MyUtils
import com.example.refactoredapp.util.MyViewModelFactory import com.example.refactoredapp.util.MyViewModelFactory
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialPort
import com.hoho.android.usbserial.driver.UsbSerialProber
import com.hoho.android.usbserial.util.SerialInputOutputManager
import java.io.File
import java.lang.Exception
import java.nio.charset.StandardCharsets
class MainActivity : AppCompatActivity() class MainActivity : AppCompatActivity()

View File

@@ -3,7 +3,6 @@ package com.example.refactoredapp.presentation
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.refactoredapp.data.model.DenovixData
import com.example.refactoredapp.data.model.DeviceType import com.example.refactoredapp.data.model.DeviceType
import com.example.refactoredapp.domain.ParseCSV import com.example.refactoredapp.domain.ParseCSV
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -15,7 +14,7 @@ class MainViewModel(private val parseDenovix: ParseCSV, private val parseTestRig
var device = DeviceType.TestRight var device = DeviceType.TestRight
var isStoragePermission = MutableLiveData<Boolean>(false) var isStoragePermission = MutableLiveData<Boolean>(false)
val resultsLiveData = MutableLiveData<ArrayList<DenovixData>>() // val resultsLiveData = MutableLiveData<ArrayList<DenovixData>>()
fun parseCSV(file: File){ fun parseCSV(file: File){
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {

View File

@@ -1,16 +1,15 @@
package com.example.refactoredapp.presentation package com.example.refactoredapp.presentation
import com.example.refactoredapp.data.model.DenovixData
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.example.refactoredapp.R import com.example.refactoredapp.R
import com.example.refactoredapp.data.model.SampleDetails
class RVAdapter : RecyclerView.Adapter<RVAdapter.ViewHolder>() { class RVAdapter : RecyclerView.Adapter<RVAdapter.ViewHolder>() {
private val dataset = ArrayList<DenovixData>() private val dataset = ArrayList<SampleDetails>()
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
@@ -31,7 +30,7 @@ class RVAdapter : RecyclerView.Adapter<RVAdapter.ViewHolder>() {
return dataset.size return dataset.size
} }
fun updateDataSet(newDataSet: ArrayList<DenovixData>) { fun updateDataSet(newDataSet: ArrayList<SampleDetails>) {
dataset.clear() dataset.clear()
dataset.addAll(newDataSet) dataset.addAll(newDataSet)
notifyDataSetChanged() notifyDataSetChanged()

View File

@@ -1,28 +0,0 @@
package com.example.refactoredapp.presentation.TestRight
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import com.example.refactoredapp.R
import com.example.refactoredapp.databinding.ActivityMainBinding
import com.example.refactoredapp.databinding.ActivityTestRightBinding
import com.example.refactoredapp.util.MyViewModelFactory
class TestRightActivity : AppCompatActivity() {
private lateinit var binding: ActivityTestRightBinding
private lateinit var viewModel: TestRightViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityTestRightBinding.inflate(layoutInflater)
setContentView(binding.root)
viewModel = ViewModelProvider(this, MyViewModelFactory(this.applicationContext))[TestRightViewModel::class.java]
if (!viewModel.isReferenceDone)
supportFragmentManager.beginTransaction().replace(binding.flMain.id, TestRightExpReference()).commit()
else
supportFragmentManager.beginTransaction().replace(binding.flMain.id, TestRightExpSample()).commit()
}
}

View File

@@ -1,37 +0,0 @@
package com.example.refactoredapp.presentation.TestRight
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import com.example.refactoredapp.R
import com.example.refactoredapp.databinding.FragmentTestRightExpReferenceBinding
import com.example.refactoredapp.databinding.FragmentTestRightResultsBinding
class TestRightExpReference : Fragment() {
private lateinit var binding: FragmentTestRightExpReferenceBinding
private val viewModel: TestRightViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
binding = FragmentTestRightExpReferenceBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupListeners()
}
private fun setupListeners() {
binding.btnSetReference.setOnClickListener {
}
}
}

View File

@@ -1,8 +0,0 @@
package com.example.refactoredapp.presentation.TestRight
import androidx.lifecycle.ViewModel
class TestRightViewModel : ViewModel() {
var isReferenceDone = false
}

View File

@@ -1,12 +0,0 @@
package com.example.refactoredapp.presentation.TestRight
import android.app.Service
import android.content.Intent
import android.os.IBinder
class UsbService : Service() {
override fun onBind(intent: Intent): IBinder {
TODO("Return the communication channel to the service.")
}
}

View File

@@ -0,0 +1,9 @@
package com.example.refactoredapp.presentation
interface UsbServiceListener {
fun onUsbConnect()
fun onUsbConnectError(e: Exception?)
fun onUsbRead(data: ByteArray?)
fun onUsbRead()
fun onUsbIoError(e: Exception?)
}

View File

@@ -0,0 +1,149 @@
package com.example.refactoredapp.presentation.testRight
import android.app.PendingIntent
import android.content.*
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import com.example.refactoredapp.data.Constants
import com.example.refactoredapp.databinding.ActivityTestRightBinding
import com.example.refactoredapp.util.MyViewModelFactory
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
class TestRightActivity : AppCompatActivity() {
private lateinit var binding: ActivityTestRightBinding
private lateinit var viewModel: TestRightViewModel
private lateinit var mDriver: UsbSerialDriver
private var mConnection: UsbDeviceConnection? = null
lateinit var mService: UsbService
private val TAG = "TestRightActivity"
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
synchronized(this) {
val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
device?.apply {
connectUsb(true)
}
} else {
onUsbError("permission denied for device")
}
}
}
}
private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as UsbService.UsbServiceBinder
mService = binder.getService()
viewModel.isServiceConnected = true
mConnection.let { mService.connect(mDriver, mConnection!!) }
moveToNext()
}
override fun onServiceDisconnected(arg0: ComponentName) {
viewModel.isServiceConnected = false
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityTestRightBinding.inflate(layoutInflater)
setContentView(binding.root)
viewModel = ViewModelProvider(this, MyViewModelFactory(this.applicationContext))[TestRightViewModel::class.java]
connectUsb(false);
// if(connectUsb(false)) {
// moveToNext()
// } else {
// onBackPressed()
// }
}
private fun connectUsb(permissionGranted: Boolean) {
val manager = getSystemService(Context.USB_SERVICE) as UsbManager
val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager)
if (availableDrivers.isEmpty()) {
onUsbError("No Device is Connected")
} else {
mDriver = availableDrivers[0]
mConnection = manager.openDevice(mDriver.device)
if (mConnection == null){
requestUserPermission(manager, mDriver.device)
} else {
setupService()
}
}
}
/*
* Request user permission. The response will be received in the BroadcastReceiver
*/
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
Log.d(TAG, String.format("requestUserPermissions", device.vendorId, device.productId))
val mPendingIntent = PendingIntent.getBroadcast(
this,
0,
Intent(Constants.ACTION_USB_PERMISSION),
0
)
val filter = IntentFilter(Constants.ACTION_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter)
manager.requestPermission(device, mPendingIntent)
}
private fun setupService() {
val intent = Intent(this, UsbService::class.java)
// startService(intent)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
private fun moveToNext(){
// setupService()
if (supportFragmentManager.isDestroyed)
return
if (!viewModel.isReferenceDone)
supportFragmentManager.beginTransaction()
.replace(binding.flMain.id, TestRightExpReference()).commit()
else
supportFragmentManager.beginTransaction()
.replace(binding.flMain.id, TestRightExpSample()).commit()
}
override fun onDestroy() {
super.onDestroy()
if (viewModel.isServiceConnected) {
mService.disconnect()
unbindService(connection)
viewModel.isServiceConnected = false
}
}
fun onUsbError(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing)
onBackPressed()
}
}

View File

@@ -0,0 +1,137 @@
package com.example.refactoredapp.presentation.testRight
import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.example.refactoredapp.R
import com.example.refactoredapp.data.DataHolder
import com.example.refactoredapp.data.model.TestRightCommands
import com.example.refactoredapp.databinding.FragmentTestRightExpReferenceBinding
import com.example.refactoredapp.presentation.UsbServiceListener
import com.example.refactoredapp.presentation.utils.MyDialogListener
import com.example.refactoredapp.presentation.utils.UIUtils
class TestRightExpReference : Fragment() {
private lateinit var binding: FragmentTestRightExpReferenceBinding
private val viewModel: TestRightViewModel by activityViewModels()
private val TAG = "TestRightExpReference"
var fullString: String = ""
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
binding = FragmentTestRightExpReferenceBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupListeners()
if (DataHolder.isReferenceTaken)
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightExpSample())
.commit()
}
private fun setupListeners() {
binding.btnSetReference.setOnClickListener {
UIUtils().createAlertDialog(
requireContext(),
getString(R.string.have_you_placed),
getString(R.string.please_place),
getString(R.string.yes),
getString(R.string.no),
object : MyDialogListener {
override fun onClickBtnOne() {
startTakingReference()
}
override fun onClickBtnTwo() {}
})
}
(activity as TestRightActivity).mService.addListener(
object : UsbServiceListener {
override fun onUsbConnect() {
Log.d(TAG, "onUsbConnect() called")
}
override fun onUsbConnectError(e: Exception?) {
}
override fun onUsbRead(data: ByteArray?) {
// Log.d(TAG, "onUsbRead(data) call back called")
data?.let {
val stringData = String(it)
// Log.d(TAG, stringData)
fullString += stringData
if(stringData.contains("OK")){
viewModel.mapValues(fullString)
}
}
// val stringData = String(data!!)
// Log.d(TAG, stringData)
}
override fun onUsbRead() {
Log.d(TAG, "onSerialRead() call back called")
}
override fun onUsbIoError(e: Exception?) {
Log.e(TAG, "onUsbIoError() called -> $e")
}
}
)
binding.btnRead.setOnClickListener {
// Log.d(TAG, "clicked on text")
// val mService = (activity as TestRightActivity).mService
// mService.read()
Log.d(TAG, "FULL STRING IS -> $fullString")
}
}
private fun startTakingReference() {
val mService = (activity as TestRightActivity).mService
mService.eventDrivenWrite(TestRightCommands.print_all)
}
// private fun startTakingReference() {
// val mService = (activity as TestRightActivity).mService
// mService.write(TestRightCommands.print)
//
// val handler = Handler()
// handler.postDelayed(Runnable { // Do something after 5s = 5000ms
// mService.read()
// }, 10000)
//
// }
override fun onDestroy() {
super.onDestroy()
(activity as TestRightActivity).mService.removeListener()
}
// fun Button.disable() {
// background.setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY)
// isClickable = false
// }
//
// fun Button.enable() {
// background.setColorFilter(Color.BLUE, PorterDuff.Mode.MULTIPLY)
// isClickable = true
// }
}

View File

@@ -1,4 +1,4 @@
package com.example.refactoredapp.presentation.TestRight package com.example.refactoredapp.presentation.testRight
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
@@ -6,7 +6,6 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.refactoredapp.R
import com.example.refactoredapp.databinding.FragmentTestRightExpReferenceBinding import com.example.refactoredapp.databinding.FragmentTestRightExpReferenceBinding
class TestRightExpSample : Fragment() { class TestRightExpSample : Fragment() {

View File

@@ -1,16 +1,14 @@
package com.example.refactoredapp.presentation.TestRight package com.example.refactoredapp.presentation.testRight
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.refactoredapp.R import com.example.refactoredapp.R
import com.example.refactoredapp.databinding.FragmentTestRightResultsBinding import com.example.refactoredapp.databinding.FragmentTestRightResultsBinding
import com.example.refactoredapp.util.MyUtils
class TestRightResults : Fragment() { class TestRightResults : Fragment() {

View File

@@ -0,0 +1,16 @@
package com.example.refactoredapp.presentation.testRight
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class TestRightViewModel : ViewModel() {
var isReferenceDone = false
var isServiceConnected = false
val isUsbConnected = MutableLiveData(false)
fun mapValues(fullString: String) {
TODO("Not yet implemented")
}
}

View File

@@ -0,0 +1,105 @@
package com.example.refactoredapp.presentation.testRight
import android.app.Service
import android.content.Intent
import android.hardware.usb.UsbDeviceConnection
import android.os.Binder
import android.os.IBinder
import android.util.Log
import com.example.refactoredapp.data.Constants
import com.example.refactoredapp.data.model.TestRightCommands
import com.example.refactoredapp.presentation.UsbServiceListener
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialPort
import com.hoho.android.usbserial.util.SerialInputOutputManager
import java.io.IOException
class UsbService : Service() {
// Binder to be given to clients
private val binder = UsbServiceBinder()
private lateinit var mPort: UsbSerialPort
private var listener: UsbServiceListener? = null
private var isUsbConnected = false
private val TAG = "UsbService"
inner class UsbServiceBinder : Binder() {
// Return this instance of UsbService so clients can call public methods
fun getService(): UsbService = this@UsbService
}
override fun onBind(intent: Intent): IBinder {
Log.d("surya", "onBind() called")
return binder
}
fun connect(driver: UsbSerialDriver, connection: UsbDeviceConnection) {
mPort = driver.ports[0] // Most devices have just one port (port 0)
mPort.open(connection)
mPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
isUsbConnected = true
Log.d(TAG, "My Usb Connected ${mPort.driver}")
}
fun disconnect() {
if(isUsbConnected){
mPort.close()
isUsbConnected = false;
Log.d(TAG, "My Usb disconnected:: ${mPort.driver}")
}
}
fun addListener(listener: UsbServiceListener){
this.listener = listener
if(isUsbConnected)
listener.onUsbConnect()
}
fun removeListener(){
this.listener = null
}
fun eventDrivenWrite(command: TestRightCommands) {
val usbIoManager = SerialInputOutputManager(mPort,
object : SerialInputOutputManager.Listener{
override fun onNewData(data: ByteArray?) {
listener?.onUsbRead(data)
}
override fun onRunError(e: Exception?) {
Log.e(TAG, "onRunError() called inside eventDrivenWrite()")
}
})
usbIoManager.start();
try {
mPort.write(command.command.toByteArray(), Constants.WRITE_TIMEOUT_MILLIS)
} catch (e: IOException) {
listener?.onUsbIoError(e)
}
}
fun write(command: TestRightCommands){
mPort.write(command.command.toByteArray(), Constants.WRITE_TIMEOUT_MILLIS)
}
fun read(){
val byteArray = ByteArray(3700)
val len = mPort.read(byteArray, Constants.READ_TIMEOUT_MILLIS)
Log.d(TAG, "length is $len")
val byteArrayCropped = ByteArray(len)
System.arraycopy(byteArray, 0, byteArrayCropped, 0, len)
listener?.onUsbRead(byteArrayCropped)
}
}

View File

@@ -0,0 +1,6 @@
package com.example.refactoredapp.presentation.utils
interface MyDialogListener {
fun onClickBtnOne()
fun onClickBtnTwo()
}

View File

@@ -0,0 +1,21 @@
package com.example.refactoredapp.presentation.utils
import android.content.Context
import com.google.android.material.dialog.MaterialAlertDialogBuilder
class UIUtils {
fun createAlertDialog(context: Context, title: String, subtitle: String, btnOneText: String, btnTwoText: String, listener: MyDialogListener){
MaterialAlertDialogBuilder(context)
.setTitle(title)
.setMessage(subtitle)
.setNegativeButton(btnOneText) { _, _ ->
listener.onClickBtnOne()
}
.setPositiveButton(btnTwoText) { _, _ ->
listener.onClickBtnTwo()
}
.show()
}
}

View File

@@ -3,13 +3,10 @@ package com.example.refactoredapp.util
import android.content.Context import android.content.Context
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.example.refactoredapp.data.RepositoryImpl
import com.example.refactoredapp.domain.ParseDenovixUseCase import com.example.refactoredapp.domain.ParseDenovixUseCase
import com.example.refactoredapp.domain.ParseTestRightCSVUseCase import com.example.refactoredapp.domain.ParseTestRightCSVUseCase
import com.example.refactoredapp.presentation.MainActivity
import com.example.refactoredapp.presentation.MainViewModel import com.example.refactoredapp.presentation.MainViewModel
import com.example.refactoredapp.presentation.TestRight.TestRightActivity import com.example.refactoredapp.presentation.testRight.TestRightViewModel
import com.example.refactoredapp.presentation.TestRight.TestRightViewModel
class MyViewModelFactory(private val context: Context) : ViewModelProvider.Factory { class MyViewModelFactory(private val context: Context) : ViewModelProvider.Factory {

View File

@@ -9,7 +9,7 @@
android:id="@+id/fl_main" android:id="@+id/fl_main"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".presentation.TestRight.TestRightActivity"> tools:context=".presentation.testRight.TestRightActivity">
</FrameLayout> </FrameLayout>

View File

@@ -2,7 +2,7 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android" <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:context=".presentation.TestRight.TestRightExpReference"> tools:context=".presentation.testRight.TestRightExpReference">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -23,9 +23,21 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/set_reference" android:text="@string/set_reference"
android:layout_margin="16dp" android:layout_margin="16dp"
android:clickable="false"
app:layout_constraintTop_toBottomOf="@id/tv_title" app:layout_constraintTop_toBottomOf="@id/tv_title"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btn_read"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/read"
android:layout_margin="16dp"
android:clickable="false"
app:layout_constraintTop_toBottomOf="@id/btn_set_reference"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</layout> </layout>

View File

@@ -1,9 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" tools:context=".presentation.testRight.TestRightExpSample">
android:layout_height="match_parent"
tools:context=".presentation.TestRight.TestRightExpSample">
<!-- TODO: Update blank fragment layout --> <!-- TODO: Update blank fragment layout -->
<TextView <TextView

View File

@@ -1,9 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" tools:context=".presentation.testRight.TestRightResults">
android:layout_height="match_parent"
tools:context=".presentation.TestRight.TestRightResults">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -2,7 +2,11 @@
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="Theme.RefactoredApp" parent="Theme.MaterialComponents.Light.DarkActionBar"> <style name="Theme.RefactoredApp" parent="Theme.MaterialComponents.Light.DarkActionBar">
<!-- Primary brand color. --> <!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<!-- <item name="colorPrimary">@color/purple_200</item>-->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item> <item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item> <item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. --> <!-- Secondary brand color. -->

View File

@@ -5,8 +5,17 @@
<item>TestRight</item> <item>TestRight</item>
<item>Denovix</item> <item>Denovix</item>
</string-array> </string-array>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string> <string name="hello_blank_fragment">Hello blank fragment</string>
<string name="select_the_test">Select the Test</string> <string name="select_the_test">Select the Test</string>
<string name="set_reference">Set Reference</string> <string name="set_reference">Set Reference</string>
<!-- Alert Dialog -->
<string name="have_you_placed">Have you placed the cuvette containing reference sample?</string>
<string name="please_place">Please place the cuvette containing sample for reference before moving forward</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="connect">Connect</string>
<string name="connected">Connected</string>
<string name="read">Read</string>
</resources> </resources>

View File

@@ -1,5 +1,11 @@
<resources> <resources>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>
<style name="title1"> <style name="title1">
<item name="android:textSize">20.5sp</item> <item name="android:textSize">20.5sp</item>
<item name="android:letterSpacing">-0.01</item> <item name="android:letterSpacing">-0.01</item>