added permission support for USB & established a connection using service
This commit is contained in:
@@ -17,34 +17,39 @@
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.RefactoredApp"
|
||||
tools:targetApi="31">
|
||||
|
||||
<service
|
||||
android:name=".UsbService"
|
||||
android:name=".presentation.testRight.UsbService"
|
||||
android:enabled="true"
|
||||
android:exported="true"></service>
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name=".presentation.SplashActivity"
|
||||
android:exported="true">
|
||||
android:exported="true"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
android:noHistory="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".presentation.TestRight.TestRightActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".presentation.MainActivity"
|
||||
android:exported="true">
|
||||
android:name=".presentation.testRight.TestRightActivity"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
||||
android:resource="@xml/device_filter" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".presentation.MainActivity"
|
||||
android:exported="true">
|
||||
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -1,6 +1,10 @@
|
||||
package com.example.refactoredapp
|
||||
|
||||
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
|
||||
|
||||
class MyApplication : Application() {
|
||||
@@ -8,4 +12,5 @@ class MyApplication : Application() {
|
||||
private val sampleDetails = SampleDetails("Change it later");
|
||||
fun getSampleDetails() : SampleDetails = sampleDetails
|
||||
// fun setSampleDetails(sample: SampleDetails) {sampleDetails = sample}
|
||||
|
||||
}
|
||||
@@ -2,4 +2,8 @@ package com.example.refactoredapp.data
|
||||
|
||||
object Constants {
|
||||
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
|
||||
|
||||
}
|
||||
@@ -3,4 +3,6 @@ package com.example.refactoredapp.data
|
||||
object DataHolder {
|
||||
var isStoragePermissionGranted = false
|
||||
var isAppFolderCreated = false
|
||||
|
||||
var isReferenceTaken = false
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -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"),
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -1,40 +1,13 @@
|
||||
package com.example.refactoredapp.presentation
|
||||
|
||||
import android.Manifest
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
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.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 androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
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.presentation.TestRight.TestRightActivity
|
||||
import com.example.refactoredapp.util.MyUtils
|
||||
import com.example.refactoredapp.presentation.testRight.TestRightActivity
|
||||
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()
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.example.refactoredapp.presentation
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.refactoredapp.data.model.DenovixData
|
||||
import com.example.refactoredapp.data.model.DeviceType
|
||||
import com.example.refactoredapp.domain.ParseCSV
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -15,7 +14,7 @@ class MainViewModel(private val parseDenovix: ParseCSV, private val parseTestRig
|
||||
var device = DeviceType.TestRight
|
||||
var isStoragePermission = MutableLiveData<Boolean>(false)
|
||||
|
||||
val resultsLiveData = MutableLiveData<ArrayList<DenovixData>>()
|
||||
// val resultsLiveData = MutableLiveData<ArrayList<DenovixData>>()
|
||||
|
||||
fun parseCSV(file: File){
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package com.example.refactoredapp.presentation
|
||||
|
||||
import com.example.refactoredapp.data.model.DenovixData
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.example.refactoredapp.R
|
||||
import com.example.refactoredapp.data.model.SampleDetails
|
||||
|
||||
class RVAdapter : RecyclerView.Adapter<RVAdapter.ViewHolder>() {
|
||||
|
||||
private val dataset = ArrayList<DenovixData>()
|
||||
private val dataset = ArrayList<SampleDetails>()
|
||||
|
||||
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
@@ -31,7 +30,7 @@ class RVAdapter : RecyclerView.Adapter<RVAdapter.ViewHolder>() {
|
||||
return dataset.size
|
||||
}
|
||||
|
||||
fun updateDataSet(newDataSet: ArrayList<DenovixData>) {
|
||||
fun updateDataSet(newDataSet: ArrayList<SampleDetails>) {
|
||||
dataset.clear()
|
||||
dataset.addAll(newDataSet)
|
||||
notifyDataSetChanged()
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.example.refactoredapp.presentation.TestRight
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
class TestRightViewModel : ViewModel() {
|
||||
|
||||
var isReferenceDone = false
|
||||
}
|
||||
@@ -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.")
|
||||
}
|
||||
}
|
||||
@@ -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?)
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
// }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.refactoredapp.presentation.TestRight
|
||||
package com.example.refactoredapp.presentation.testRight
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
@@ -6,7 +6,6 @@ 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
|
||||
|
||||
class TestRightExpSample : Fragment() {
|
||||
@@ -1,16 +1,14 @@
|
||||
package com.example.refactoredapp.presentation.TestRight
|
||||
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 android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import com.example.refactoredapp.R
|
||||
import com.example.refactoredapp.databinding.FragmentTestRightResultsBinding
|
||||
import com.example.refactoredapp.util.MyUtils
|
||||
|
||||
class TestRightResults : Fragment() {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.example.refactoredapp.presentation.utils
|
||||
|
||||
interface MyDialogListener {
|
||||
fun onClickBtnOne()
|
||||
fun onClickBtnTwo()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,13 +3,10 @@ package com.example.refactoredapp.util
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.example.refactoredapp.data.RepositoryImpl
|
||||
import com.example.refactoredapp.domain.ParseDenovixUseCase
|
||||
import com.example.refactoredapp.domain.ParseTestRightCSVUseCase
|
||||
import com.example.refactoredapp.presentation.MainActivity
|
||||
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 {
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
android:id="@+id/fl_main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".presentation.TestRight.TestRightActivity">
|
||||
tools:context=".presentation.testRight.TestRightActivity">
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".presentation.TestRight.TestRightExpReference">
|
||||
tools:context=".presentation.testRight.TestRightExpReference">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -23,9 +23,21 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/set_reference"
|
||||
android:layout_margin="16dp"
|
||||
android:clickable="false"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_title"
|
||||
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>
|
||||
|
||||
</layout>
|
||||
@@ -1,9 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".presentation.TestRight.TestRightExpSample">
|
||||
tools:context=".presentation.testRight.TestRightExpSample">
|
||||
|
||||
<!-- TODO: Update blank fragment layout -->
|
||||
<TextView
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".presentation.TestRight.TestRightResults">
|
||||
tools:context=".presentation.testRight.TestRightResults">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.RefactoredApp" parent="Theme.MaterialComponents.Light.DarkActionBar">
|
||||
<!-- 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="colorOnPrimary">@color/black</item>
|
||||
<!-- Secondary brand color. -->
|
||||
|
||||
@@ -5,8 +5,17 @@
|
||||
<item>TestRight</item>
|
||||
<item>Denovix</item>
|
||||
</string-array>
|
||||
<!-- TODO: Remove or change this placeholder text -->
|
||||
|
||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||
<string name="select_the_test">Select the Test</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>
|
||||
@@ -1,5 +1,11 @@
|
||||
<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">
|
||||
<item name="android:textSize">20.5sp</item>
|
||||
<item name="android:letterSpacing">-0.01</item>
|
||||
|
||||
Reference in New Issue
Block a user