Merge branch 'dev-molbio-result-upload-jithu' into dev

This commit is contained in:
Mariya
2024-03-11 17:43:49 +05:30
2 changed files with 310 additions and 254 deletions

View File

@@ -15,6 +15,8 @@ import android.net.Uri
import android.os.BatteryManager import android.os.BatteryManager
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.util.Base64 import android.util.Base64
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
@@ -28,6 +30,7 @@ import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.presentation.utils.DeviceCommunicationHandler
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.login.LoginRequest import com.example.hpostesting.data.model.login.LoginRequest
@@ -39,7 +42,7 @@ import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.updates.CheckUpdateRequest import com.example.hpostesting.data.model.updates.CheckUpdateRequest
import com.example.hpostesting.data.model.updates.DeviceUpdateRequest import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.example.hpostesting.presentation.utils.DeviceCommunicationHandler import com.example.hpostesting.encryption.Encryption
import com.example.hpostesting.presentation.KitScanActivity import com.example.hpostesting.presentation.KitScanActivity
import com.example.hpostesting.presentation.utils.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.adapter.OfflineUserListAdapter import com.example.hpostesting.presentation.adapter.OfflineUserListAdapter
@@ -56,6 +59,7 @@ import com.google.firebase.perf.ktx.performance
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
import kotlinx.coroutines.tasks.await
import okhttp3.ResponseBody import okhttp3.ResponseBody
import org.json.JSONObject import org.json.JSONObject
import java.io.BufferedOutputStream import java.io.BufferedOutputStream
@@ -121,8 +125,6 @@ class HomeFragment : Fragment() {
userData.forEach { userData.forEach {
if (it.testStatus == false) { if (it.testStatus == false) {
userList.add(it) userList.add(it)
}else if(it.testStatus == true){
userList.removeAll(userData)
} }
} }
val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager
@@ -152,65 +154,69 @@ class HomeFragment : Fragment() {
} }
// Now re-subscribe to allUserData // Now re-subscribe to allUserData
/* hemoCubeViewModel.allLocalData.observe(viewLifecycleOwner) { originalUserDataList -> /* hemoCubeViewModel.allLocalData.observe(viewLifecycleOwner) { originalUserDataList ->
Log.d("LOCAL_DB OBSERVE", "OBSERVE CALLED") Log.d("LOCAL_DB OBSERVE", "OBSERVE CALLED")
val resultList = MolbioV2ResultRequest(mutableListOf()) val resultList = MolbioV2ResultRequest(mutableListOf())
originalUserDataList.forEach { userData -> originalUserDataList.forEach { userData ->
Log.d(": USER DATA", originalUserDataList.count().toString() + " : " + userData._id) Log.d(
var accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString() ": USER DATA",
// Upload results after processing all userData to avoid duplicates and ensure all modifications are done originalUserDataList.count().toString() + " : " + userData._id
if(accessToken.isNotEmpty()) { )
var accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString()
// Upload results after processing all userData to avoid duplicates and ensure all modifications are done
if(accessToken.isNotEmpty()) {
if (!userData.molbioFlag && isTokenAvailable && Constants.MOLBIO_INTEGRATION) {
val currentTimeFormatted = SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssZZZZZ",
Locale.getDefault()
).format(Calendar.getInstance().time)
val bufferIntensityThreshold =
Constants.BUFFER_INTENSITY_THRESHOLDS[userData.deviceId]?.toString()
?: "defaultThreshold" // Handle possible nulls safely
resultList.results?.add(
MolbioV2Result(
rawData = userData,
analysisId = userData._id,
analysisDate = currentTimeFormatted,
analysisStatus = userData.classificationResult
?: "defaultStatus", // Handle possible nulls
thresholds = bufferIntensityThreshold,
interpretation = userData.classificationResult
?: "defaultInterpretation", // Handle possible nulls
testId = userData._id,
testTime = currentTimeFormatted,
collectionTime = currentTimeFormatted,
expiryTime = currentTimeFormatted
)
)
}
}
}
Log.d("USER DATA LIST SIZE", resultList.results?.count().toString())
if (!userData.localFlag && userData.testStatus == true) { resultList.results?.forEach { result ->
hemoCubeViewModel.bulkAddResultTestToDb(userData) val userData = result.rawData
} Log.d("UserData", userData.toString())
if (userData != null) {
if (!userData.localFlag) {
hemoCubeViewModel.bulkAddResultTestToDb(userData)
if (!userData.molbioFlag && isTokenAvailable && Constants.MOLBIO_INTEGRATION && userData.testStatus == true) { }
val currentTimeFormatted = SimpleDateFormat( }
"yyyy-MM-dd'T'HH:mm:ssZZZZZ", }
Locale.getDefault() resultList.results?.forEach { result ->
).format(Calendar.getInstance().time) result.rawData?.let { sanitizeDoubleValues(it) }
val bufferIntensityThreshold = }
Constants.BUFFER_INTENSITY_THRESHOLDS[userData.deviceId]?.toString()
?: "defaultThreshold" // Handle possible nulls safely
resultList.results?.add(
MolbioV2Result(
rawData = userData,
analysisId = userData._id,
analysisDate = currentTimeFormatted,
analysisStatus = userData.classificationResult ?: "defaultStatus", // Handle possible nulls
thresholds = bufferIntensityThreshold,
interpretation = userData.classificationResult ?: "defaultInterpretation", // Handle possible nulls
testId = userData._id,
testTime = currentTimeFormatted,
collectionTime = currentTimeFormatted,
expiryTime = currentTimeFormatted
)
)
}
}
}
Log.d("USER DATA LIST SIZE", resultList.results?.count().toString()) // Then, check if there are any results to upload.
if (resultList.results?.isNotEmpty() == true) {
hemoCubeViewModel.uploadResult(resultList)
Log.d("resultcount1", "Uploading sanitized results")
}
resultList.results?.forEach { result -> }*/
val userData = result.rawData
Log.d("UserData", userData.toString())
}
resultList.results?.forEach { result ->
result.rawData?.let { sanitizeDoubleValues(it) }
}
// Then, check if there are any results to upload.
if (resultList.results?.isNotEmpty() == true) {
hemoCubeViewModel.uploadResult(resultList)
Log.d("resultcount1", "Uploading sanitized results")
}
}*/
hemoCubeViewModel.sendDataToMolbio() hemoCubeViewModel.sendDataToMolbio()
hemoCubeViewModel.sendDataToFirebase() hemoCubeViewModel.sendDataToFirebase()
@@ -243,28 +249,27 @@ class HomeFragment : Fragment() {
binding.uploadData.setOnClickListener { binding.uploadData.setOnClickListener {
// showUploadDialog(requireContext()) // showUploadDialog(requireContext())
} }
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData -> // hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData ->
if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") { //
val btnSaveLocalVisibility = // val btnSaveLocalVisibility =
if (userData.any { it.testStatus == true }) View.VISIBLE else View.GONE // if (userData.any { it.testStatus == true }) View.GONE else View.GONE
binding.downloadCSV.visibility = btnSaveLocalVisibility //
binding.downloadCSV.setOnClickListener { // binding.downloadCSV.visibility = btnSaveLocalVisibility
if (btnSaveLocalVisibility == View.VISIBLE) { //
// Execute the action when the button is visible (testStatus is true for at least one user) // binding.downloadCSV.setOnClickListener {
showDownloadDialog(requireContext()) // if (btnSaveLocalVisibility == View.VISIBLE) {
} else { // // Execute the action when the button is visible (testStatus is true for at least one user)
// Handle the case when the button is not visible // showDownloadDialog(requireContext())
Toast.makeText( // } else {
requireContext(), // // Handle the case when the button is not visible
"No test details stored locally", // Toast.makeText(
Toast.LENGTH_SHORT // requireContext(),
).show() // "No test details stored locally",
} // Toast.LENGTH_SHORT
} // ).show()
}else{ // }
binding.downloadCSV.visibility = View.GONE // }
} // }
}
binding.btnNewKit.setOnClickListener { binding.btnNewKit.setOnClickListener {
@@ -274,7 +279,7 @@ class HomeFragment : Fragment() {
apply() apply()
} }
startActivity(Intent(requireContext(), KitScanActivity::class.java)) startActivity(Intent(requireContext(), KitScanActivity::class.java))
// requireActivity().finish() requireActivity().finish()
} }
@@ -285,7 +290,7 @@ class HomeFragment : Fragment() {
apply() apply()
} }
startActivity(Intent(requireContext(), KitScanActivity::class.java)) startActivity(Intent(requireContext(), KitScanActivity::class.java))
// requireActivity().finish() requireActivity().finish()
} }
binding.btnQuickCapture.setOnClickListener { binding.btnQuickCapture.setOnClickListener {
DataHolder.hemoCubeTestData = HemoCubeTestData() DataHolder.hemoCubeTestData = HemoCubeTestData()
@@ -308,26 +313,52 @@ class HomeFragment : Fragment() {
var password = sharedPreference.getString(Constants.DEVICE_PASSWORD_API, "").toString() var password = sharedPreference.getString(Constants.DEVICE_PASSWORD_API, "").toString()
var userID = sharedPreference.getString(Constants.DEVICE_ID_API, "").toString() var userID = sharedPreference.getString(Constants.DEVICE_ID_API, "").toString()
deviceId = sharedPreference.getString(Constants.DEVICE_ID, "").toString() deviceId = sharedPreference.getString(Constants.DEVICE_ID, "").toString()
if(userID.isNotEmpty() && password.isNotEmpty()) {
Log.d("istoken",isTokenAvailable.toString())
if (!isTokenAvailable) {
Log.d("istoken1",isTokenAvailable.toString())
hemoCubeViewModel.login(createLoginRequestData(userID, password))
isTokenAvailable = true
}else if(isTokenAvailable){ val target = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
Log.d("istoken7",isTokenAvailable.toString()) val file = File(target, "credentials.txt") //this file contains userID and password to communicate with API.
isTokenAvailable = true
hemoCubeViewModel.startPeriodicCheckUpdate() if (userID.isNotEmpty() && password.isNotEmpty()) {
hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData()) Log.d("istoken", isTokenAvailable.toString())
}else{ if (!isTokenAvailable) {
if(isTokenExpired(accessToken)) { Log.d("istoken1", isTokenAvailable.toString())
Log.d("istoken8",isTokenAvailable.toString()) hemoCubeViewModel.login(createLoginRequestData(userID, password))
hemoCubeViewModel.login(createLoginRequestData(userID, password)) isTokenAvailable = true
}
} } else if (isTokenAvailable) {
} else if (userID == "" && password == "" && deviceId.isNotEmpty()) { Log.d("istoken7", isTokenAvailable.toString())
isTokenAvailable = true
hemoCubeViewModel.startPeriodicCheckUpdate()
hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData())
} else {
if (isTokenExpired(accessToken)) {
Log.d("istoken8", isTokenAvailable.toString())
hemoCubeViewModel.login(createLoginRequestData(userID, password))
}
}
} else if (userID == "deviceIDAPI" && password == "devicePasswordAPI" && deviceId.isNotEmpty()) {
fetchDeviceCredentials() fetchDeviceCredentials()
} else if (file.exists()) {
val encryptedString = file.readText()
val encryptionKey =
Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID)
val decryptedMessage: String = Encryption.decrypt(encryptedString, encryptionKey)
val credentials = decryptedMessage.split("\n")
userID = credentials[0]
password = credentials[1]
Toast.makeText(context, "DECRYPTED: $credentials", Toast.LENGTH_SHORT).show()
if (!isTokenAvailable) {
hemoCubeViewModel.login(createLoginRequestData(userID, password))
isTokenAvailable = true
} else if (isTokenAvailable) {
isTokenAvailable = true
hemoCubeViewModel.startPeriodicCheckUpdate()
hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData())
} else {
if (isTokenExpired(accessToken)) {
hemoCubeViewModel.login(createLoginRequestData(userID, password))
}
}
} else { } else {
Toast.makeText( Toast.makeText(
requireContext(), requireContext(),
@@ -342,7 +373,7 @@ class HomeFragment : Fragment() {
updateTokens(response) updateTokens(response)
response.data.data?.accessToken response.data.data?.accessToken
isTokenAvailable = true isTokenAvailable = true
Log.d("istoken2",isTokenAvailable.toString()) Log.d("istoken2", isTokenAvailable.toString())
} }
is Result.Error -> { is Result.Error -> {
@@ -368,7 +399,7 @@ class HomeFragment : Fragment() {
when (it) { when (it) {
is Result.Success -> { is Result.Success -> {
Log.d("success,","uploded") Log.d("success,", "uploded")
it.data.data?.forEach { id -> it.data.data?.forEach { id ->
id.rawData?.let { it1 -> id.rawData?.let { it1 ->
hemoCubeViewModel.updateMolbioFlag( hemoCubeViewModel.updateMolbioFlag(
@@ -376,7 +407,11 @@ class HomeFragment : Fragment() {
) )
} }
} }
Toast.makeText(activity, "Molbio Result is successfully uploaded", Toast.LENGTH_LONG) Toast.makeText(
activity,
"Molbio Result is successfully uploaded",
Toast.LENGTH_LONG
)
.show() .show()
} }
@@ -427,25 +462,29 @@ class HomeFragment : Fragment() {
hemoCubeViewModel.checkUpdate.observe(viewLifecycleOwner) { response -> hemoCubeViewModel.checkUpdate.observe(viewLifecycleOwner) { response ->
when (response) { when (response) {
is Result.Success -> { is Result.Success -> {
val updatedversion = response.data.data?.version.toString() val updatedversion = response.data.data?.version.toString()
val currentversion = val currentversion =
context?.let { ctx -> context?.let { ctx ->
val packageInfo = ctx.packageManager.getPackageInfo(ctx.packageName, 0) val packageInfo = ctx.packageManager.getPackageInfo(ctx.packageName, 0)
val versionName = packageInfo.versionName val versionName = packageInfo.versionName
val versionCode: Long = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { val versionCode: Long =
// From Android P (API level 28), versionCode is deprecated and you should use longVersionCode instead. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
packageInfo.longVersionCode // From Android P (API level 28), versionCode is deprecated and you should use longVersionCode instead.
} else { packageInfo.longVersionCode
// For older Android versions, use versionCode (cast it to Long for consistency). } else {
packageInfo.versionCode.toLong() // For older Android versions, use versionCode (cast it to Long for consistency).
} packageInfo.versionCode.toLong()
}
// Use versionName and versionCode as needed // Use versionName and versionCode as needed
Log.d("AppInfo", "Version Name: $versionName, Version Code: $versionCode") Log.d(
"AppInfo",
"Version Name: $versionName, Version Code: $versionCode"
)
} }
Log.d("versionnow",currentversion.toString()) Log.d("versionnow", currentversion.toString())
Log.d("versionnow",updatedversion.toString()) Log.d("versionnow", updatedversion.toString())
if(updatedversion > currentversion.toString()){ if (updatedversion > currentversion.toString()) {
hemoCubeViewModel.deviceUpdate(createDeviceUpdateRequestData()) hemoCubeViewModel.deviceUpdate(createDeviceUpdateRequestData())
Toast.makeText( Toast.makeText(
activity, activity,
@@ -453,7 +492,7 @@ class HomeFragment : Fragment() {
Toast.LENGTH_LONG Toast.LENGTH_LONG
) )
.show() .show()
}else{ } else {
Toast.makeText( Toast.makeText(
activity, activity,
"App is Up to date", "App is Up to date",
@@ -489,14 +528,19 @@ class HomeFragment : Fragment() {
val downloadDirectory = "NATS" val downloadDirectory = "NATS"
val fileName = "nats_certificate.zip" val fileName = "nats_certificate.zip"
val unzipDirectoryPath = requireContext().getExternalFilesDir(null)?.absolutePath + "/$downloadDirectory" val unzipDirectoryPath =
requireContext().getExternalFilesDir(null)?.absolutePath + "/$downloadDirectory"
// Check if the directory with extracted files exists. // Check if the directory with extracted files exists.
val directory = File(unzipDirectoryPath) val directory = File(unzipDirectoryPath)
if (directory.exists() && directory.isDirectory) { if (directory.exists() && directory.isDirectory) {
// Assuming if the directory exists, the certificate has been downloaded and extracted. // Assuming if the directory exists, the certificate has been downloaded and extracted.
// You can add more specific checks here, e.g., checking for specific files within the directory. // You can add more specific checks here, e.g., checking for specific files within the directory.
Toast.makeText(requireContext(), "NATS certificate already downloaded and extracted.", Toast.LENGTH_SHORT).show() Toast.makeText(
requireContext(),
"NATS certificate already downloaded and extracted.",
Toast.LENGTH_SHORT
).show()
return@observe return@observe
} }
val file = downloadFile(url, requireContext(), fileName, downloadDirectory) val file = downloadFile(url, requireContext(), fileName, downloadDirectory)
@@ -528,7 +572,7 @@ class HomeFragment : Fragment() {
private fun isTokenExpired(token: String): Boolean { private fun isTokenExpired(token: String): Boolean {
if(token.isNotEmpty()) { if (token.isNotEmpty()) {
val parts = token.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() val parts = token.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val decodedPayload = String(Base64.decode(parts[1], Base64.DEFAULT)) val decodedPayload = String(Base64.decode(parts[1], Base64.DEFAULT))
val jsonPayload = JSONObject(decodedPayload) val jsonPayload = JSONObject(decodedPayload)
@@ -537,7 +581,7 @@ class HomeFragment : Fragment() {
val currentTimeSeconds = System.currentTimeMillis() / 1000 val currentTimeSeconds = System.currentTimeMillis() / 1000
return exp <= currentTimeSeconds return exp <= currentTimeSeconds
}else{ } else {
return false return false
} }
} }
@@ -552,7 +596,7 @@ class HomeFragment : Fragment() {
apply() apply()
} }
isTokenAvailable = true isTokenAvailable = true
Log.d("istoken3",isTokenAvailable.toString()) Log.d("istoken3", isTokenAvailable.toString())
} }
private fun createLoginRequestData(userID: String, password: String): LoginRequest { private fun createLoginRequestData(userID: String, password: String): LoginRequest {
@@ -695,9 +739,9 @@ class HomeFragment : Fragment() {
putString(Constants.NATS_TOKEN, natsToken) putString(Constants.NATS_TOKEN, natsToken)
apply() apply()
} }
if (!isTokenAvailable ) { if (!isTokenAvailable) {
Log.d("istoken0", isTokenAvailable.toString()) Log.d("istoken0", isTokenAvailable.toString())
hemoCubeViewModel.login(createLoginRequestData(username, password)) hemoCubeViewModel.login(createLoginRequestData(username, password))
} }
} ?: Log.e("fetchDeviceCredentials", "Failed to parse device data.") } ?: Log.e("fetchDeviceCredentials", "Failed to parse device data.")
@@ -881,15 +925,11 @@ class HomeFragment : Fragment() {
} }
private fun checkUnprocessedCSVData() { private fun checkUnprocessedCSVData() {
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> // hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") { // val downloadDataVisibility =
val downloadDataVisibility = // if (userDataList.any { !it.isCSVCreated && it.testStatus == true }) View.GONE else View.GONE
if (userDataList.any { !it.isCSVCreated && it.testStatus == true }) View.VISIBLE else View.GONE // binding.downloadCSV.visibility = downloadDataVisibility
binding.downloadCSV.visibility = downloadDataVisibility // }
}else{
binding.downloadCSV.visibility = View.GONE
}
}
} }
private fun sanitizeDoubleValues(hemoCubeTestData: HemoCubeTestData): HemoCubeTestData { private fun sanitizeDoubleValues(hemoCubeTestData: HemoCubeTestData): HemoCubeTestData {
@@ -906,7 +946,6 @@ class HomeFragment : Fragment() {
} }
private fun showUploadDialog(context: Context) { private fun showUploadDialog(context: Context) {
val builder = AlertDialog.Builder(context) val builder = AlertDialog.Builder(context)
builder.setTitle(R.string.upload_db_registration_title) builder.setTitle(R.string.upload_db_registration_title)
@@ -924,22 +963,22 @@ class HomeFragment : Fragment() {
dialog.show() dialog.show()
} }
private fun showDownloadDialog(context: Context) { // private fun showDownloadDialog(context: Context) {
val builder = AlertDialog.Builder(context) // val builder = AlertDialog.Builder(context)
builder.setTitle(R.string.download_db_registration_title) // builder.setTitle(R.string.download_db_registration_title)
builder.setMessage(R.string.download_db_registration_message) // builder.setMessage(R.string.download_db_registration_message)
//
builder.setPositiveButton(R.string.downloadcsv) { dialog, _ -> // builder.setPositiveButton(R.string.downloadcsv) { dialog, _ ->
downloadLocalDBData(dialog) // downloadLocalDBData(dialog)
} // }
//
builder.setNegativeButton(R.string.cancel) { dialog, _ -> // builder.setNegativeButton(R.string.cancel) { dialog, _ ->
dialog.dismiss() // dialog.dismiss()
} // }
//
val dialog = builder.create() // val dialog = builder.create()
dialog.show() // dialog.show()
} // }
private fun uploadLocalDBData(dialog: DialogInterface) { private fun uploadLocalDBData(dialog: DialogInterface) {
// viewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> // viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
@@ -1001,25 +1040,27 @@ class HomeFragment : Fragment() {
} }
} }
private fun downloadLocalDBData(dialog: DialogInterface) { // private fun downloadLocalDBData(dialog: DialogInterface) {
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> // hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
val downloadList = mutableListOf<HemoCubeTestData>() // val downloadList = mutableListOf<HemoCubeTestData>()
//
userDataList.forEach { userData -> // userDataList.forEach { userData ->
if (!userData.isCSVCreated) { // if (!userData.isCSVCreated) {
downloadList.add(userData) // Add the userData to downloadList // downloadList.add(userData) // Add the userData to downloadList
} // }
} // }
//
if (downloadList.isNotEmpty()) { // if (downloadList.isNotEmpty()) {
// Call ViewModel function to create CSV with filtered data // // Call ViewModel function to create CSV with filtered data
hemoCubeViewModel.createCSV(downloadList, requireContext()) // hemoCubeViewModel.createCSV(downloadList, requireContext())
Toast.makeText(requireContext(), "Done", Toast.LENGTH_SHORT).show() // Toast.makeText(requireContext(), "Done", Toast.LENGTH_SHORT).show()
} // } else {
// Toast.makeText(requireContext(), "Failed", Toast.LENGTH_SHORT).show()
dialog.dismiss() // }
} //
} // dialog.dismiss()
// }
// }
private fun deleteIncompleteRegistrations(userDataList: List<UserData>) { private fun deleteIncompleteRegistrations(userDataList: List<UserData>) {
userDataList.forEach { userData -> userDataList.forEach { userData ->
@@ -1055,22 +1096,22 @@ class HomeFragment : Fragment() {
} }
} }
// private fun showDownloadDialog(context: Context) { private fun showDownloadDialog(context: Context) {
// val builder = AlertDialog.Builder(context) val builder = AlertDialog.Builder(context)
// builder.setTitle(R.string.download_db_registration_title) builder.setTitle(R.string.download_db_registration_title)
// builder.setMessage(R.string.download_db_registration_message) builder.setMessage(R.string.download_db_registration_message)
//
// builder.setPositiveButton(R.string.downloadcsv) { dialog, _ -> builder.setPositiveButton(R.string.downloadcsv) { dialog, _ ->
// downloadLocalDBData(dialog) // downloadLocalDBData(dialog)
// } }
//
// builder.setNegativeButton(R.string.cancel) { dialog, _ -> builder.setNegativeButton(R.string.cancel) { dialog, _ ->
// dialog.dismiss() dialog.dismiss()
// } }
//
// val dialog = builder.create() val dialog = builder.create()
// dialog.show() dialog.show()
// } }
// private fun downloadLocalDBData(dialog: DialogInterface) { // private fun downloadLocalDBData(dialog: DialogInterface) {
// var csvDownloaded = false // var csvDownloaded = false
@@ -1117,7 +1158,7 @@ class HomeFragment : Fragment() {
// } // }
private fun getDeviceId() { private fun getDeviceId() {
Log.d("HomeFragmentUSb","getDeviceId") Log.d("HomeFragmentUSb", "getDeviceId")
val handler = activity as? DeviceCommunicationHandler val handler = activity as? DeviceCommunicationHandler
handler?.sendAndListenToDevice( handler?.sendAndListenToDevice(
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
@@ -1125,9 +1166,10 @@ class HomeFragment : Fragment() {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { data?.let {
val receivedData = String(it, Charset.forName("UTF-8")) val receivedData = String(it, Charset.forName("UTF-8"))
Log.d("HomeFragment","USB data"+receivedData) Log.d("HomeFragment", "USB data" + receivedData)
// Assuming the device ID is the full content of the received data. Adjust if needed. // Assuming the device ID is the full content of the received data. Adjust if needed.
deviceId = extractDeviceId(receivedData) // Implement this method based on your data format. deviceId =
extractDeviceId(receivedData) // Implement this method based on your data format.
if (deviceId.isNotEmpty()) { if (deviceId.isNotEmpty()) {
// Store the deviceId in SharedPreferences // Store the deviceId in SharedPreferences
with(sharedPreference.edit()) { with(sharedPreference.edit()) {
@@ -1144,7 +1186,7 @@ class HomeFragment : Fragment() {
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
// Handle USB communication error // Handle USB communication error
Log.d("HomeFragment","USB read error"+e.toString()) Log.d("HomeFragment", "USB read error" + e.toString())
} }
}) })
@@ -1156,94 +1198,103 @@ class HomeFragment : Fragment() {
val matchResult = regex.find(receivedData) val matchResult = regex.find(receivedData)
return matchResult?.groups?.get(1)?.value ?: "" return matchResult?.groups?.get(1)?.value ?: ""
} }
@SuppressLint("SuspiciousIndentation") @SuppressLint("SuspiciousIndentation")
private fun checkForUpdate() { private fun checkForUpdate() {
try { try {
val db = Firebase.firestore val db = Firebase.firestore
//val deviceId = deviceId //val deviceId = deviceId
val deviceRef = db.collection("deviceUpdate").document(Constants.DOCUMENT_ID_FOR_UPDATE) val deviceRef = db.collection("deviceUpdate").document(Constants.DOCUMENT_ID_FOR_UPDATE)
deviceRef.get().addOnSuccessListener { documentSnapshot -> deviceRef.get().addOnSuccessListener { documentSnapshot ->
if (documentSnapshot.exists()) { if (documentSnapshot.exists()) {
val deviceData = val deviceData =
documentSnapshot.toObject(DeviceData::class.java) documentSnapshot.toObject(DeviceData::class.java)
// deviceData?.let { data -> // deviceData?.let { data ->
val deviceVersion = deviceData!!.deviceVersion val deviceVersion = deviceData!!.deviceVersion
val deviceUpdateAvailableGlobal= deviceData.deviceUpdateAvailable val deviceUpdateAvailableGlobal = deviceData.deviceUpdateAvailable
val updatePathGlobal= deviceData.updatePath val updatePathGlobal = deviceData.updatePath
db.collection("devices").whereEqualTo("deviceId", deviceId).get().addOnSuccessListener { documentSnapshotNew -> db.collection("devices").whereEqualTo("deviceId", deviceId).get()
if (documentSnapshotNew.documents.isNotEmpty()) { .addOnSuccessListener { documentSnapshotNew ->
documentSnapshotNew.documents.forEach{ if (documentSnapshotNew.documents.isNotEmpty()) {
val documentIn = it.toObject(DeviceData::class.java) documentSnapshotNew.documents.forEach {
val documentIn = it.toObject(DeviceData::class.java)
val globalUpdateIgnore = documentIn!!.globalUpdateIgnore val globalUpdateIgnore = documentIn!!.globalUpdateIgnore
val deviceUpdateAvailable = documentIn.deviceUpdateAvailable val deviceUpdateAvailable = documentIn.deviceUpdateAvailable
val globalUpdateDone = documentIn.globalUpdateDone val globalUpdateDone = documentIn.globalUpdateDone
val updatePath = documentIn.updatePath val updatePath = documentIn.updatePath
if(globalUpdateIgnore){ if (globalUpdateIgnore) {
if(deviceUpdateAvailable){ if (deviceUpdateAvailable) {
val update = db.collection("devices").document(it.id).update("deviceUpdateAvailable",false) val update = db.collection("devices").document(it.id)
update.addOnSuccessListener { .update("deviceUpdateAvailable", false)
Log.d("HomeFragmentUpdate","Device local update done") update.addOnSuccessListener {
Log.d(
"HomeFragmentUpdate",
"Device local update done"
)
initiateUpdate(updatePath) initiateUpdate(updatePath)
}.addOnFailureListener{ }.addOnFailureListener {
Log.e("fetchDeviceUpdate", "update fail.") Log.e("fetchDeviceUpdate", "update fail.")
} }
}else{ } else {
Log.d("HomeFragmentUpdate","Device update not available") Log.d(
} "HomeFragmentUpdate",
}else{ "Device update not available"
if(deviceUpdateAvailableGlobal) { )
if (!globalUpdateDone) { }
val update = } else {
db.collection("devices").document(it.id) if (deviceUpdateAvailableGlobal) {
.update("globalUpdateDone", true) if (!globalUpdateDone) {
update.addOnSuccessListener { val update =
Log.d( db.collection("devices").document(it.id)
"HomeFragmentUpdate", .update("globalUpdateDone", true)
"Device global update done" update.addOnSuccessListener {
) Log.d(
"HomeFragmentUpdate",
"Device global update done"
)
initiateUpdate(updatePathGlobal) initiateUpdate(updatePathGlobal)
}.addOnFailureListener { }.addOnFailureListener {
Log.e( Log.e(
"fetchDeviceUpdate", "fetchDeviceUpdate",
"update fail." "update fail."
) )
}
}
} }
} }
} }
} else {
Log.e("fetchDeviceUpdate", "Document does not exist.")
} }
}.addOnFailureListener { exception ->
Log.e("fetchDeviceUpdate", "Error fetching device data", exception)
} }
} else {
// Toast.makeText(requireActivity()," true -version."+deviceVersion+"updatePath.."+updatePath,Toast.LENGTH_LONG).show() Log.e("fetchDeviceUpdate", "Document does not exist.")
}
}.addOnFailureListener { exception ->
Log.e("fetchDeviceUpdate", "Error fetching device data", exception)
}
// Log for debugging // Toast.makeText(requireActivity()," true -version."+deviceVersion+"updatePath.."+updatePath,Toast.LENGTH_LONG).show()
Log.d(
"fetchDeviceCredentials",
"deviceVersion: $deviceVersion, Password: $deviceUpdateAvailableGlobal, updatePath: $updatePathGlobal" // Log for debugging
) Log.d(
"fetchDeviceCredentials",
"deviceVersion: $deviceVersion, Password: $deviceUpdateAvailableGlobal, updatePath: $updatePathGlobal"
)
// ?: Log.e("fetchDeviceUpdate", "Failed to parse device data.") // ?: Log.e("fetchDeviceUpdate", "Failed to parse device data.")
} else { } else {
Log.e("fetchDeviceUpdate", "Document does not exist.") Log.e("fetchDeviceUpdate", "Document does not exist.")
}
} }
}
.addOnFailureListener { exception -> .addOnFailureListener { exception ->
Log.e("fetchDeviceUpdate", "Error fetching device data", exception) Log.e("fetchDeviceUpdate", "Error fetching device data", exception)
} }
@@ -1265,7 +1316,8 @@ class HomeFragment : Fragment() {
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalFilesDir(requireActivity(), "Updates", "update.apk") request.setDestinationInExternalFilesDir(requireActivity(), "Updates", "update.apk")
val downloadManager = requireActivity().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager val downloadManager =
requireActivity().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
downloadId = downloadManager.enqueue(request) downloadId = downloadManager.enqueue(request)
// Register a BroadcastReceiver to receive the download complete event // Register a BroadcastReceiver to receive the download complete event
@@ -1275,12 +1327,15 @@ class HomeFragment : Fragment() {
requireActivity().registerReceiver(downloadReceiver, filter, RECEIVER_EXPORTED) requireActivity().registerReceiver(downloadReceiver, filter, RECEIVER_EXPORTED)
} }
} }
private fun extractApkUrl(responseBody: ResponseBody): String { private fun extractApkUrl(responseBody: ResponseBody): String {
return responseBody.string() return responseBody.string()
} }
private fun isValidHttpUrl(url: String): Boolean { private fun isValidHttpUrl(url: String): Boolean {
return url.startsWith("http://") || url.startsWith("https://") return url.startsWith("http://") || url.startsWith("https://")
} }
private val downloadReceiver = object : BroadcastReceiver() { private val downloadReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) { override fun onReceive(context: Context?, intent: Intent?) {
val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
@@ -1294,8 +1349,11 @@ class HomeFragment : Fragment() {
val file = File(requireActivity().getExternalFilesDir("Updates"), "update.apk") val file = File(requireActivity().getExternalFilesDir("Updates"), "update.apk")
file.setReadable(true, false) // Ensure the file is readable file.setReadable(true, false) // Ensure the file is readable
val pInfo = requireActivity().baseContext.packageManager.getPackageInfo(requireActivity().baseContext.packageName, 0) val pInfo = requireActivity().baseContext.packageManager.getPackageInfo(
Log.d("HomeFragmentShowInfo",pInfo.packageName.toString()) requireActivity().baseContext.packageName,
0
)
Log.d("HomeFragmentShowInfo", pInfo.packageName.toString())
val uri: Uri = FileProvider.getUriForFile( val uri: Uri = FileProvider.getUriForFile(
requireActivity(), requireActivity(),
"${pInfo.packageName}.fileprovider", "${pInfo.packageName}.fileprovider",
@@ -1318,7 +1376,7 @@ class HomeFragment : Fragment() {
} }
override fun onDestroy() { override fun onDestroy() {
if(isRegistered) { if (isRegistered) {
try { try {
requireActivity().unregisterReceiver(downloadReceiver) requireActivity().unregisterReceiver(downloadReceiver)
} catch (e: Exception) { } catch (e: Exception) {

View File

@@ -233,7 +233,7 @@ class DeviceProvisionFragment : Fragment() {
} }
private fun encryptAndSaveToFile(username: String, password: String) { private fun encryptAndSaveToFile(username: String, password: String) {
val messageToEncrypt = "deviceID\n$username\n$password" val messageToEncrypt = "$username\n$password"
val encryptionKey = val encryptionKey =
Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID) Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID)
val encryptedString = Encryption.encrypt(messageToEncrypt, encryptionKey) val encryptedString = Encryption.encrypt(messageToEncrypt, encryptionKey)
@@ -245,12 +245,10 @@ class DeviceProvisionFragment : Fragment() {
file.createNewFile() file.createNewFile()
} }
val fos = FileOutputStream(file)
file.writeText(encryptedString) file.writeText(encryptedString)
Log.d("Encrypted Message", encryptedString) Log.d("Encrypted Message", encryptedString)
fos.close()
} }
} }