diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index abc813f..a91079a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -34,13 +34,16 @@ android:supportsRtl="true" android:theme="@style/Theme.HPOSTesting" tools:targetApi="31"> + + android:theme="@style/Theme.HPOS.NoActionBar" /> () + 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() + deviceViewModel.isServiceConnected = true + mConnection.let { mService.connect(mDriver, mConnection!!) } + moveToNext() + } + + override fun onServiceDisconnected(arg0: ComponentName) { + deviceViewModel.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 = ActivityDeviceBinding.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, DeviceFragment()) + .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.HOMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE + ) + } else { + mPendingIntent = PendingIntent.getBroadcast( + this, + 0, + Intent(Constants.HOMOCUBE_USB_PERMISSION), + PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE + ) + } + + val filter = IntentFilter(Constants.HOMOCUBE_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 (deviceViewModel.isServiceConnected) { + mService.disconnect() + unbindService(connection) + deviceViewModel.isServiceConnected = false + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceFragment.kt new file mode 100644 index 0000000..6ed027e --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceFragment.kt @@ -0,0 +1,109 @@ +package com.example.hpostesting.presentation.deviceinfo + +import android.annotation.SuppressLint +import android.content.Context +import android.content.SharedPreferences +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 androidx.lifecycle.MutableLiveData +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.constant.HemoCubeCommands +import com.example.hpostesting.presentation.UsbServiceListener +import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel +import com.google.firebase.crashlytics.ktx.crashlytics +import com.google.firebase.ktx.Firebase +import `in`.sminnovations.hpostesting.databinding.FragmentDeviceBinding + + + +class DeviceFragment : Fragment() { + private lateinit var binding: FragmentDeviceBinding + private val deviceViewModel: HemoCubeViewModel by activityViewModels() + private lateinit var sharedPreferences: SharedPreferences + private var deviceId = "" + private var startListening = MutableLiveData(false) + private var resultData: String = "" + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, + ): View { + binding = FragmentDeviceBinding.inflate(inflater, container, false) + sharedPreferences = + requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initViews() + + } + + private fun initViews() { + deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString() + listenToHemoCube() + getDeviceId() + } + + private fun getDeviceId() { + deviceViewModel.progressBar.postValue(true) + (activity as DeviceActivity).mService.sendAndListenToHemoCube( + HemoCubeCommands.getDeviceId, + object : UsbServiceListener { + @SuppressLint("SetTextI18n") + override fun onUsbRead(data: ByteArray?) { + data?.let { + val stringData = String(it) + deviceViewModel.messages.postValue(stringData) + binding.tvSubtitle4.text = "Device ID: ${stringData}" + } + } + override fun onUsbError(e: Exception?) { + deviceViewModel.progressBar.postValue(false) + } + }) + } + + + + private fun listenToHemoCube() { + + val fullReadOutput = StringBuilder() + startListening.postValue(true) + + try { + (activity as DeviceActivity).mService.listenToHemoCube(object : UsbServiceListener { + @SuppressLint("SetTextI18n") + override fun onUsbRead(data: ByteArray?) { + data?.let { + val stringData = String(it) + deviceViewModel.messages.postValue(stringData) + fullReadOutput.append(stringData) + resultData += stringData + binding.tvSubtitle4.text = "Device ID : ${resultData}" + if (stringData.contains("SN")) { + val slData = stringData.split(" ") + if (slData.size > 1) { + val hardwareId = slData[1].trim() + with(sharedPreferences.edit()) { + putString(Constants.DEVICE_ID, hardwareId) + apply() + } +// binding.tvSubtitle4.text = hardwareId + } + } + } + } + + override fun onUsbError(e: Exception?) { + deviceViewModel.progressBar.postValue(false) + } + }) + } catch (e: Exception) { + Firebase.crashlytics.recordException(e) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceViewModel.kt new file mode 100644 index 0000000..d577739 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceViewModel.kt @@ -0,0 +1,35 @@ +package com.example.hpostesting.presentation.deviceinfo + +import android.content.Context +import android.content.SharedPreferences +import android.util.Log +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.hpostesting.data.NetworkStatusLiveData +import com.example.hpostesting.data.dao.HemoCubeDao +import com.example.hpostesting.data.model.Response +import com.example.hpostesting.data.model.diagnostics.DiagnosticsData +import com.example.hpostesting.data.model.patient.DeviceData +import com.example.hpostesting.data.repository.Repository +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject +@HiltViewModel +class DeviceViewModel @Inject constructor( + private val hemoCubeDao: HemoCubeDao, + private val repository: Repository, + context: Context +) : ViewModel() { + var isServiceConnected = false + val progressBar = MutableLiveData(false) + val messages = MutableLiveData() + private val _networkStatusLiveData = NetworkStatusLiveData(context) + val allUserData = hemoCubeDao.getAll() + val deviceData = MutableLiveData() + val networkStatusLiveData: LiveData + get() = _networkStatusLiveData + val fireBaseUpload = MutableLiveData() + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt index 17f873e..7a2b7a9 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt @@ -55,6 +55,8 @@ class DiagnosticsViewModel @Inject constructor( Log.e("Testdb", "Error uploading data to Firestore: $response") fireBaseUpload.postValue("Error") } + + else -> {} } } catch (e: Exception) { Log.e("Testdb", "Exception during data upload: ${e.message}") diff --git a/app/src/main/res/layout/activity_device.xml b/app/src/main/res/layout/activity_device.xml new file mode 100644 index 0000000..a0c5d59 --- /dev/null +++ b/app/src/main/res/layout/activity_device.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_device.xml b/app/src/main/res/layout/fragment_device.xml new file mode 100644 index 0000000..84d4928 --- /dev/null +++ b/app/src/main/res/layout/fragment_device.xml @@ -0,0 +1,23 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_gallery.xml b/app/src/main/res/layout/fragment_gallery.xml index 5966bad..e62a6c2 100644 --- a/app/src/main/res/layout/fragment_gallery.xml +++ b/app/src/main/res/layout/fragment_gallery.xml @@ -6,6 +6,22 @@ android:layout_height="match_parent" tools:context="com.example.hpostesting.presentation.dashboard.GalleryFragment"> + + +