diff --git a/app/build.gradle b/app/build.gradle
index e6cc89a..395566d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -62,6 +62,7 @@ android {
dependencies {
implementation "com.google.dagger:hilt-android:2.46"
+ implementation 'androidx.activity:activity:1.8.0'
kapt "com.google.dagger:hilt-android-compiler:2.46"
implementation 'androidx.core:core-ktx:1.12.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 90d381b..62cdfa0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,17 +1,4 @@
-
-
@@ -19,7 +6,6 @@
-
@@ -38,16 +24,20 @@
+
@@ -73,23 +63,20 @@
-
+ android:theme="@style/Theme.HPOS.NoActionBar" />
-
+ android:theme="@style/Theme.HPOS.NoActionBar" />
-
-
+
+
-
+
+
+
+
+
+
+
-
-
+
+
+
@@ -184,8 +179,7 @@
android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:screenOrientation="portrait"
android:stateNotNeeded="true"
- tools:replace="android:screenOrientation" />
-
+ tools:replace="android:screenOrientation" />
-
\ No newline at end of file
diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/GalleryFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/GalleryFragment.kt
index 09ec534..439fde8 100644
--- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/GalleryFragment.kt
+++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/GalleryFragment.kt
@@ -32,6 +32,7 @@ import com.example.hpostesting.presentation.deviceinfo.DeviceActivity
import com.example.hpostesting.presentation.deviceprovision.DeviceProvisionActivity
import com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
+import com.example.hpostesting.presentation.usb_teminal.UsbTerminalActivity
import `in`.sminnovations.hpostesting.databinding.FragmentGalleryBinding
@@ -77,7 +78,9 @@ class GalleryFragment : Fragment() {
binding.btnDeviceProvision.setOnClickListener {
startActivity(Intent(requireContext(), DeviceProvisionActivity::class.java))
}
-
+ binding.btnUsbTerminal.setOnClickListener {
+ startActivity(Intent(requireContext(), UsbTerminalActivity::class.java))
+ }
binding.btnSubmit.setOnClickListener {
startActivity(Intent(requireContext(), HemocubeBufferCheckActivity::class.java))
}
diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt
index 32372bf..2981020 100644
--- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt
+++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt
@@ -305,7 +305,7 @@ class HomeFragment : Fragment() {
apply()
}
startActivity(Intent(requireContext(), KitScanActivity::class.java))
- requireActivity().finish()
+ // requireActivity().finish()
}
@@ -316,7 +316,7 @@ class HomeFragment : Fragment() {
apply()
}
startActivity(Intent(requireContext(), KitScanActivity::class.java))
- requireActivity().finish()
+ // requireActivity().finish()
}
binding.btnQuickCapture.setOnClickListener {
DataHolder.hemoCubeTestData = HemoCubeTestData()
diff --git a/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalActivity.kt
new file mode 100644
index 0000000..7bcca47
--- /dev/null
+++ b/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalActivity.kt
@@ -0,0 +1,198 @@
+/*
+ * // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
+ * // Notice: All information contained herein is, and remains
+ * // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
+ * // if any. The intellectual and technical concepts contained
+ * // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
+ * // and its suppliers and may be covered by Indian and Foreign Patents,
+ * // patents in process, and are protected by trade secret or copyright law.
+ * // Dissemination of this information or reproduction of this material
+ * // is strictly forbidden unless prior written permission is obtained
+ * // from ShanMukha Innovations Pvt. Ltd.
+ */
+
+package com.example.hpostesting.presentation.usb_teminal
+
+import android.annotation.SuppressLint
+import android.app.PendingIntent
+import android.content.BroadcastReceiver
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.ServiceConnection
+import android.content.SharedPreferences
+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.view.Menu
+import android.widget.Toast
+import androidx.activity.viewModels
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
+import androidx.core.view.get
+import com.example.hpostesting.data.constant.Constants
+import com.example.hpostesting.data.constant.DataHolder
+import com.example.hpostesting.data.constant.HemoCubeCommands
+import com.example.hpostesting.data.constant.LanguageManager
+import com.example.hpostesting.presentation.deviceinfo.DeviceFragment
+import com.example.hpostesting.presentation.utils.DeviceCommunicationHandler
+import com.example.hpostesting.presentation.utils.UsbServiceListener
+import com.example.hpostesting.util.UsbService
+import com.hoho.android.usbserial.driver.UsbSerialDriver
+import com.hoho.android.usbserial.driver.UsbSerialProber
+import dagger.hilt.android.AndroidEntryPoint
+import `in`.sminnovations.hpostesting.R
+import `in`.sminnovations.hpostesting.databinding.ActivityUsbTerminalBinding
+
+@Suppress("MemberVisibilityCanBePrivate")
+@AndroidEntryPoint
+class UsbTerminalActivity : AppCompatActivity() {
+ private lateinit var binding: ActivityUsbTerminalBinding
+ private val usbTerminalViewModel by viewModels()
+ private var myMenu: Menu? = null
+ private lateinit var sharedPreferences: SharedPreferences
+ private lateinit var mDriver: UsbSerialDriver
+ private var mConnection: UsbDeviceConnection? = null
+ lateinit var mService: UsbService
+ private var deviceId = ""
+ private val TAG = "Calibration"
+
+ 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)
+ DataHolder.usbConnected.postValue(true)
+ }
+ } else {
+ onErrorReported("permission denied for device")
+ DataHolder.usbConnected.postValue(true)
+ }
+ }
+
+ }
+ }
+
+
+ private val connection = object : ServiceConnection {
+ override fun onServiceConnected(className: ComponentName, service: IBinder) {
+ val binder = service as UsbService.UsbServiceBinder
+ mService = binder.getService()
+ usbTerminalViewModel.isServiceConnected = true
+ mConnection.let { mService.connect(mDriver, mConnection!!) }
+ moveToNext()
+ }
+
+ override fun onServiceDisconnected(arg0: ComponentName) {
+ usbTerminalViewModel.isServiceConnected = false
+ }
+ }
+
+ override fun attachBaseContext(newBase: Context?) {
+ val languageCode = LanguageManager.getSavedLanguage(newBase!!)
+ LanguageManager.setLocale(newBase, languageCode)
+ super.attachBaseContext(newBase)
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityUsbTerminalBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+// setSupportActionBar(binding.myToolbar)
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ setupListener()
+ connectUsb(false)
+ }
+
+ private fun setupListener() {
+ DataHolder.usbConnected.observe(this) {
+ Log.d("USB OBSERVE", "HemoCube called -> $it")
+ if (it) {
+ myMenu?.get(0)?.icon =
+ ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24)
+ } else {
+ myMenu?.get(0)?.icon =
+ ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
+ Toast.makeText(this, "Device is Disconnected", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
+ open fun connectUsb(permissionGranted: Boolean) {
+ Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
+ val manager = getSystemService(Context.USB_SERVICE) as UsbManager
+ val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager)
+
+ if (availableDrivers.isEmpty()) {
+ onErrorReported("No Device is Connected")
+ } else {
+ mDriver = availableDrivers[0]
+ mConnection = manager.openDevice(mDriver.device)
+ if (mConnection == null) {
+ requestUserPermission(manager, mDriver.device)
+ } else {
+ setupService()
+ }
+ }
+ }
+
+ fun onErrorReported(msg: String) {
+ Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
+ if (!isFinishing) onBackPressed()
+ }
+
+ private fun moveToNext() {
+ if (supportFragmentManager.isDestroyed) return
+
+ supportFragmentManager.beginTransaction().replace(binding.fgDevice.id, UsbTerminalFragment())
+ .commit()
+ }
+
+ @SuppressLint("MutableImplicitPendingIntent")
+ private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
+ val mPendingIntent: PendingIntent
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
+ mPendingIntent = PendingIntent.getBroadcast(
+ this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
+ )
+ } else {
+ mPendingIntent = PendingIntent.getBroadcast(
+ this,
+ 0,
+ Intent(Constants.HEMOCUBE_USB_PERMISSION),
+ PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
+ )
+ }
+
+ val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION)
+ registerReceiver(broadcastReceiver, filter)
+ manager.requestPermission(device, mPendingIntent)
+ }
+
+ fun setupService() {
+ val intent = Intent(this, UsbService::class.java)
+ bindService(intent, connection, Context.BIND_AUTO_CREATE)
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+ menuInflater.inflate(R.menu.my_menu, menu)
+ return true
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ if (usbTerminalViewModel.isServiceConnected) {
+ mService.disconnect()
+ unbindService(connection)
+ usbTerminalViewModel.isServiceConnected = false
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalFragment.kt
new file mode 100644
index 0000000..59f147d
--- /dev/null
+++ b/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalFragment.kt
@@ -0,0 +1,105 @@
+/*
+ * // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
+ * // Notice: All information contained herein is, and remains
+ * // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
+ * // if any. The intellectual and technical concepts contained
+ * // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
+ * // and its suppliers and may be covered by Indian and Foreign Patents,
+ * // patents in process, and are protected by trade secret or copyright law.
+ * // Dissemination of this information or reproduction of this material
+ * // is strictly forbidden unless prior written permission is obtained
+ * // from ShanMukha Innovations Pvt. Ltd.
+ */
+
+package com.example.hpostesting.presentation.usb_teminal
+
+import android.content.Context
+import android.content.SharedPreferences
+import android.os.Bundle
+import android.text.method.ScrollingMovementMethod
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.MutableLiveData
+import com.example.hpostesting.data.constant.HemoCubeCommands
+import com.example.hpostesting.presentation.utils.UsbServiceListener
+import com.google.firebase.crashlytics.ktx.crashlytics
+import com.google.firebase.ktx.Firebase
+import `in`.sminnovations.hpostesting.databinding.FragmentUsbTerminalBinding
+
+
+class UsbTerminalFragment : Fragment() {
+ private lateinit var binding: FragmentUsbTerminalBinding
+ private val usbTerminalViewModel: UsbTerminalViewModel by activityViewModels()
+ private lateinit var sharedPreferences: SharedPreferences
+ private var startListening = MutableLiveData(false)
+ private var resultData: String = ""
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
+ ): View {
+ binding = FragmentUsbTerminalBinding.inflate(inflater, container, false)
+ sharedPreferences =
+ requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ initViews()
+ }
+
+ private fun initViews() {
+ binding.messageCommand.movementMethod = ScrollingMovementMethod()
+ usbTerminalViewModel.messages.observe(viewLifecycleOwner) {
+ binding.messageCommand.text = it
+ }
+ binding.sendCommand.setOnClickListener {
+ callCommand(binding.etCommands.text.trim().toString())
+ }
+ listenToHemoCube()
+ callCommand("I")
+ }
+
+ private fun callCommand(command: String) {
+ usbTerminalViewModel.progressBar.postValue(true)
+ (activity as UsbTerminalActivity).mService.sendAndListenToHemoCubeTxt(
+ command,
+ object : UsbServiceListener {
+ override fun onUsbRead(data: ByteArray?) {
+ }
+
+ override fun onUsbError(e: Exception?) {
+ usbTerminalViewModel.progressBar.postValue(false)
+ }
+ })
+ }
+
+ private fun listenToHemoCube() {
+
+ val fullReadOutput = StringBuilder()
+ startListening.postValue(true)
+
+ try {
+ (activity as UsbTerminalActivity).mService.listenToHemoCube(object : UsbServiceListener {
+ override fun onUsbRead(data: ByteArray?) {
+ data?.let {
+ val stringData = String(it)
+ fullReadOutput.append(stringData)
+ resultData += stringData
+ usbTerminalViewModel.messages.postValue(resultData)
+ }
+ }
+
+ override fun onUsbError(e: Exception?) {
+ usbTerminalViewModel.messages.postValue(e!!.localizedMessage)
+ usbTerminalViewModel.progressBar.postValue(false)
+ }
+ })
+ } catch (e: Exception) {
+ usbTerminalViewModel.messages.postValue(e.localizedMessage)
+ Firebase.crashlytics.recordException(e)
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalViewModel.kt
new file mode 100644
index 0000000..d949d24
--- /dev/null
+++ b/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalViewModel.kt
@@ -0,0 +1,34 @@
+/*
+ * // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
+ * // Notice: All information contained herein is, and remains
+ * // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
+ * // if any. The intellectual and technical concepts contained
+ * // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
+ * // and its suppliers and may be covered by Indian and Foreign Patents,
+ * // patents in process, and are protected by trade secret or copyright law.
+ * // Dissemination of this information or reproduction of this material
+ * // is strictly forbidden unless prior written permission is obtained
+ * // from ShanMukha Innovations Pvt. Ltd.
+ */
+
+package com.example.hpostesting.presentation.usb_teminal
+
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import com.example.hpostesting.data.dao.HemoCubeDao
+import com.example.hpostesting.data.model.patient.DeviceData
+import com.example.hpostesting.data.repository.Repository
+import dagger.hilt.android.lifecycle.HiltViewModel
+import javax.inject.Inject
+
+@HiltViewModel
+class UsbTerminalViewModel @Inject constructor(
+ private val hemoCubeDao: HemoCubeDao,
+ private val repository: Repository,
+) : ViewModel() {
+ var isServiceConnected = false
+ val progressBar = MutableLiveData(false)
+ val messages = MutableLiveData()
+ val deviceData = MutableLiveData()
+ val fireBaseUpload = MutableLiveData()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/hpostesting/util/UsbService.kt b/app/src/main/java/com/example/hpostesting/util/UsbService.kt
index b878d44..60759dc 100644
--- a/app/src/main/java/com/example/hpostesting/util/UsbService.kt
+++ b/app/src/main/java/com/example/hpostesting/util/UsbService.kt
@@ -122,4 +122,12 @@ class UsbService : Service() {
listener.onUsbError(e)
}
}
+ fun sendAndListenToHemoCubeTxt(command: String, listener: UsbServiceListener) {
+ try {
+ this.bus = listener
+ mPort.write(command.toByteArray(), Constants.WRITE_TIMEOUT_MILLIS)
+ } catch (e: IOException) {
+ listener.onUsbError(e)
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_usb_terminal.xml b/app/src/main/res/layout/activity_usb_terminal.xml
new file mode 100644
index 0000000..458cb98
--- /dev/null
+++ b/app/src/main/res/layout/activity_usb_terminal.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_gallery.xml b/app/src/main/res/layout/fragment_gallery.xml
index 35afe1d..e43b758 100644
--- a/app/src/main/res/layout/fragment_gallery.xml
+++ b/app/src/main/res/layout/fragment_gallery.xml
@@ -97,8 +97,21 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_auto_dac" />
-
-
+
+
+ app:layout_constraintTop_toBottomOf="@id/btn_usb_terminal" />
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index 166a18e..df0ce47 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -289,4 +289,7 @@
Cuvette present
Cuvette absent
Retry
+ Firefox
+ Files
+ Usb Terminal
\ No newline at end of file
diff --git a/app/src/main/res/values-kn/strings.xml b/app/src/main/res/values-kn/strings.xml
index fcf453a..5e27538 100644
--- a/app/src/main/res/values-kn/strings.xml
+++ b/app/src/main/res/values-kn/strings.xml
@@ -288,6 +288,9 @@
Cuvette present
Cuvette absent
Retry
+ Firefox
+ Files
+ Usb Terminal
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7a8355a..c647c9c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -291,4 +291,5 @@
Cuvette present , you can start the test
Cuvette is absent , please place the cuvette and retry again
Retry again
+ Usb Terminal
\ No newline at end of file