Compare commits

...

37 Commits

Author SHA1 Message Date
Mariya
4b059bc953 fixed some issues 2024-03-11 17:33:34 +05:30
Mariya
320ceae26a fixed issues while merging 2024-03-11 17:23:28 +05:30
sanjay
08a781a706 Merge remote-tracking branch 'origin/dev-molbio-result-upload-jithu' into dev-molbio-result-upload-jithu
# Conflicts:
#	app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt
2024-03-11 17:13:15 +05:30
sanjay
8c4fedfe28 code to decrypt and login using locally saved credentials 2024-03-11 17:08:02 +05:30
Mariya
71818e1115 Merge branch 'dev' into dev-molbio-result-upload-jithu
# Conflicts:
#	app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt
2024-03-11 15:14:44 +05:30
Mariya
d7c1508397 changed the condition for fetching device provision details from firebase 2024-03-11 13:01:58 +05:30
chandrashekhar reddy
d701ee4f6d removed the finish for btnNewKit in HomeFragment 2024-03-09 16:20:29 +05:30
chandrashekhar reddy
e4b237bb9a Added new screen ActivitiesFragment to check upload pending list and added version name in DashboardActivity, so it will be easy to know which version currently in use 2024-03-09 16:13:54 +05:30
chandrashekhar reddy
372489330a Added new screen ActivitiesFragment to check upload pending list and added version name in DashboardActivity, so it will be easy to know which version currently in use 2024-03-09 15:20:49 +05:30
chandrashekhar reddy
0c10e5a920 Merge remote-tracking branch 'origin/dev' into dev 2024-03-09 12:27:22 +05:30
chandrashekhar reddy
045bda26ff Rearranging the project structure, so it will east to understand and following proper clean code rules 2024-03-09 12:26:59 +05:30
Mariya
b31e5e6c06 removed getting null values from result upload 2024-03-07 13:30:38 +05:30
sanjay
3913aedefc encryption code integrated 2024-03-07 12:13:12 +05:30
Mariya
53c36d3cf9 added different id and set as primary key for testing twice with same sample Id and uploading the result, offline ,issue fixed, and set ADMIN as user that can only download and export CSV file, for collecting user Data 2024-03-07 12:11:27 +05:30
sanjay
b554f64b51 setting up encryption 2024-03-07 09:55:56 +05:30
jithu
95bb428041 data upload duplication fixed-molbio & firebase 2024-03-05 17:20:18 +05:30
chandrashekhar reddy
f922f585b5 Merge remote-tracking branch 'origin/dev' into dev 2024-03-05 14:46:12 +05:30
chandrashekhar reddy
1742363f1a added deviceUpdateGlobal field in HomeFragment 2024-03-05 14:45:47 +05:30
Mariya
ba9564d867 added new kit button and logout button for offline test 2024-03-05 14:44:06 +05:30
Mariya
1aaf2ba485 sanitize the results values if the result is NaN or infinity 2024-03-04 18:02:07 +05:30
Mariya
85756a7052 commented code for unregistereceiver 2024-03-04 16:47:55 +05:30
Mariya Varghese
0141c2791e Merge branch 'dev-check-apk-update' into 'dev'
app update and other api calls managing for molbio

See merge request sminnovations/hpos!39
2024-03-04 11:12:21 +00:00
Mariya Varghese
a52538e72d Merge branch 'dev' into 'dev-check-apk-update'
# Conflicts:
#   app/build.gradle
#   app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt
#   app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt
#   app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt
#   build.gradle
#   gradle/wrapper/gradle-wrapper.properties
2024-03-04 11:11:13 +00:00
Mariya
c9d0c440e3 added code for sanitize result upload values if if the result is NAN or infinity for molbio integration 2024-03-04 14:48:43 +05:30
Mariya
20f408230e api calls managing, and error resolving for molbio 2024-03-02 19:37:24 +05:30
Mariya
c8d5d41c81 api calls maintaining for molbio 2024-03-02 15:41:17 +05:30
Mariya
210c9fed5d added code for usb permission 2024-03-01 16:21:27 +05:30
Mariya
b68ec45642 reduced number of api calls in home screen 2024-03-01 13:37:16 +05:30
Mariya
1e5afa0a5c reduced number api calls for bigtec 2024-03-01 12:38:19 +05:30
Mariya
80ab69c772 added code for uploading logs only once 2024-02-29 14:18:09 +05:30
Mariya
f7dc879c75 added code related offline bulkupload 2024-02-28 15:17:36 +05:30
Mariya
e8b5d12db5 removed unwanted toast messages 2024-02-28 15:12:21 +05:30
Mariya
626dd380ab Apk update successfully added 2024-02-28 14:46:06 +05:30
Mariya
70b0b93f57 Apk Update Code Added 2024-02-27 20:44:32 +05:30
Mariya
5cdc156f33 Apk Update Code Added 2024-02-27 16:49:25 +05:30
Mariya
71d298cd69 Apk Update Code Added 2024-02-27 14:59:03 +05:30
Mariya
bb6f4ee859 Apk Update Code Added 2024-02-27 12:43:14 +05:30
81 changed files with 1047 additions and 589 deletions

View File

@@ -19,8 +19,8 @@ android {
applicationId "in.sminnovations.hpostesting.dev"
minSdk 21
targetSdk 34
versionCode 114
versionName "2.1.114"
versionCode 120
versionName "2.1.120"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@@ -25,6 +25,7 @@
<application
android:name="com.example.hpostesting.HPOSTestingApplication"
android:largeHeap="true"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"

View File

@@ -8,7 +8,7 @@ object Constants {
const val DOCUMENT_ID_FOR_UPDATE ="2o71vBKLqdgEKYtFG8Lb"
const val ABHA_APP_PACKAGE = "in.ndhm.phr"
const val MOLBIO_INTEGRATION = false
const val MOLBIO_INTEGRATION = true
const val deviceProvisionEmail = "HPOS_provisioner@bigtec.co.in"
const val deviceProvisionPassword = "f2ab0e7f9d69"
const val DEVICE_ID_API = "deviceIDAPI"

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data
package com.example.hpostesting.data.constant
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.model.patient.HemoCubeTestData

View File

@@ -5,6 +5,7 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
@Dao
@@ -12,6 +13,12 @@ interface HemoCubeDao {
@Query("SELECT * from hemo_cube_test_table")
fun getAll(): LiveData<List<HemoCubeTestData>>
@Query("SELECT * from hemo_cube_test_table WHERE molbioFlag=false")
fun getMolbioPending(): List<HemoCubeTestData>
@Query("SELECT * from hemo_cube_test_table WHERE localFlag=false")
fun getFirebasePending():List<HemoCubeTestData>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(hemoCubeTestData: HemoCubeTestData)
@@ -30,7 +37,7 @@ interface HemoCubeDao {
@Query("UPDATE hemo_cube_test_table SET isCSVCreated = :newValue WHERE _id = :id")
suspend fun updateCSVFieldById(id: String, newValue: Boolean)
@Query("SELECT * from hemo_cube_test_table WHERE molbioFlag = :status")
suspend fun getPendingUser(status: Boolean): List<HemoCubeTestData>
@Query("SELECT * from hemo_cube_test_table WHERE localFlag = 0")
fun getPendingUser(): LiveData<List<HemoCubeTestData>>
}

View File

@@ -10,7 +10,7 @@ import com.example.hpostesting.data.model.patient.UserData
@Database(
entities = [UserData::class, HemoCubeTestData::class, DeviceData::class, BufferCheckData::class],
version = 28,
version = 29,
exportSchema = false
)
@TypeConverters(Converters::class)

View File

@@ -89,8 +89,9 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
)
csvWriter.writeNext(header)
// Write data rows
for (data in dataList) {
// Filter and write data rows where testStatus is true
val filteredDataList = dataList.filter { it.testStatus == true }
for (data in filteredDataList) {
val row = arrayOf(
data._id,
data.name,

View File

@@ -5,7 +5,8 @@ import androidx.room.PrimaryKey
@Entity(tableName = "hemo_cube_test_table")
data class HemoCubeTestData(
@PrimaryKey
@PrimaryKey(autoGenerate = true)
var sampleid: Int = 0,
var _id: String = "",
var name: String = "",
var incubationTime: String = "",

View File

@@ -1,7 +1,7 @@
package com.example.hpostesting.data.repository
import android.net.Uri
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi
import com.example.hpostesting.data.model.PendingUploads
@@ -109,20 +109,7 @@ class DatabaseRepository @Inject constructor(
}
override suspend fun addTestToDatabase(data: UserData?): Response<String> {
return try {
val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true)
}
}
db.collection("testData").add(data).await()
Response.Success(data._id)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
TODO("Not yet implemented")
}
override suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response<String> {
@@ -247,4 +234,22 @@ class DatabaseRepository @Inject constructor(
override fun <UserData> addTestToDatabase(testDetails: UserData): Any {
TODO("Not yet implemented")
}
override suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String> {
return try {
val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true)
}
}
db.collection("testData").add(data).await()
Response.Success(data._id)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
}

View File

@@ -1,6 +1,6 @@
package com.example.hpostesting.data.repository
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse
@@ -25,6 +25,7 @@ import okhttp3.ResponseBody
interface Repository {
suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String>
suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String>
suspend fun addTestToDatabase(data: UserData?): Response<String>

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.domain.di
package com.example.hpostesting.di
import android.app.Application
import android.content.Context
@@ -7,7 +7,7 @@ import android.content.res.AssetManager
import androidx.room.Room
import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi
import com.example.hpostesting.data.api.PropertyProvider
import com.example.hpostesting.util.PropertyProvider
import com.example.hpostesting.data.dao.HemoCubeBufferDao
import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.dao.MyDatabase
@@ -22,8 +22,8 @@ import com.example.hpostesting.domain.LogFileManager
import com.example.hpostesting.domain.LogFileManagerImpl
import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.UsbServiceListenerImpl
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListenerImpl
import com.example.hpostesting.util.PropertyProviderImpl
import dagger.Module
import dagger.Provides
@@ -147,7 +147,7 @@ object AppModule {
@Provides
@Singleton
fun provideRetrofit(
propertyProvider: PropertyProvider,@Named("Auth") client: OkHttpClient
propertyProvider: PropertyProvider, @Named("Auth") client: OkHttpClient
): Retrofit {
return Retrofit.Builder().baseUrl(propertyProvider.getProperty("BASE_URL")).client(client)
.addConverterFactory(GsonConverterFactory.create()).build()

View File

@@ -0,0 +1,42 @@
package com.example.hpostesting.encryption
import android.util.Base64
import javax.crypto.Cipher
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.PBEKeySpec
import javax.crypto.spec.SecretKeySpec
object Encryption {
private const val AES_MODE = "AES/CBC/PKCS5Padding"
private const val KEY_SPEC_ALGORITHM = "PBKDF2WithHmacSHA1"
private const val SALT = "Bigtec"
private const val ITERATION_COUNT = 10000
private const val KEY_LENGTH = 256
private val FIXED_IV = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
fun encrypt(textToEncrypt: String, password: String): String {
val salt = SALT.toByteArray()
val factory = SecretKeyFactory.getInstance(KEY_SPEC_ALGORITHM)
val spec = PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH)
val tmp = factory.generateSecret(spec)
val key = SecretKeySpec(tmp.encoded, "AES")
val cipher = Cipher.getInstance(AES_MODE)
cipher.init(Cipher.ENCRYPT_MODE, key, IvParameterSpec(FIXED_IV))
val encryptedBytes = cipher.doFinal(textToEncrypt.toByteArray(Charsets.UTF_8))
return Base64.encodeToString(encryptedBytes, Base64.NO_WRAP)
}
fun decrypt(encryptedText: String, password: String): String {
val salt = SALT.toByteArray()
val encryptedBytes = Base64.decode(encryptedText, Base64.NO_WRAP)
val factory = SecretKeyFactory.getInstance(KEY_SPEC_ALGORITHM)
val spec = PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH)
val tmp = factory.generateSecret(spec)
val key = SecretKeySpec(tmp.encoded, "AES")
val cipher = Cipher.getInstance(AES_MODE)
cipher.init(Cipher.DECRYPT_MODE, key, IvParameterSpec(FIXED_IV))
val decryptedBytes = cipher.doFinal(encryptedBytes)
return String(decryptedBytes, Charsets.UTF_8)
}
}

View File

@@ -10,7 +10,7 @@ import android.view.View
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.dashboard.DashboardActivity

View File

@@ -17,7 +17,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.patient.UserData

View File

@@ -1,7 +0,0 @@
package com.example.hpostesting.presentation
import androidx.lifecycle.ViewModel
class MainViewModel : ViewModel() {
}

View File

@@ -13,7 +13,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.util.MyUtils

View File

@@ -11,7 +11,7 @@ import androidx.navigation.findNavController
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData

View File

@@ -14,7 +14,7 @@ import androidx.fragment.app.FragmentActivity
import androidx.navigation.findNavController
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.firebase.ui.firestore.FirestoreRecyclerAdapter

View File

@@ -13,9 +13,8 @@ import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Spinner
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.hemocube.HemocubeActivity

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -14,7 +14,7 @@ import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener
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.FragmentAutoDacBinding

View File

@@ -1,4 +0,0 @@
package com.example.hpostesting.presentation.blank
class BlankActivity {
}

View File

@@ -1,4 +0,0 @@
package com.example.hpostesting.presentation.blank
class BlankFragment {
}

View File

@@ -1,4 +0,0 @@
package com.example.hpostesting.presentation.blank
class BlankViewModel {
}

View File

@@ -15,7 +15,7 @@ import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.crashlytics.ktx.crashlytics

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -17,7 +17,7 @@ import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.calibration.CalibrationData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase

View File

@@ -0,0 +1,59 @@
package com.example.hpostesting.presentation.dashboard
import android.content.Context
import android.content.SharedPreferences
import android.os.BatteryManager
import android.os.Bundle
import android.util.Log
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.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.presentation.adapter.OfflineUserListAdapter
import com.example.hpostesting.presentation.adapter.UserListAdapter
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentActivitiesBinding
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
class ActivitiesFragment : Fragment() {
private lateinit var binding: FragmentActivitiesBinding
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var adapter: OfflineUserListAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View {
binding = FragmentActivitiesBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
hemoCubeViewModel.allPendingUserToUpload.observe(viewLifecycleOwner) { userData ->
if (userData.isNotEmpty()) {
binding.rvOrderOffline.visibility = View.VISIBLE
binding.noDataText.visibility = View.GONE
val bm =
requireContext().getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
adapter = OfflineUserListAdapter(binding.root, batLevel)
adapter.differ.submitList(userData)
binding.rvOrderOffline.adapter = adapter
}else{
binding.rvOrderOffline.visibility = View.GONE
binding.noDataText.visibility = View.VISIBLE
Log.d("Activities","Nothing to show")
}
}
}
}

View File

@@ -1,11 +1,10 @@
package com.example.hpostesting.presentation.dashboard
import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
@@ -21,23 +20,21 @@ import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.NatsManager
import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.example.hpostesting.presentation.utils.NatsManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.jig.JigActivity
import com.google.android.material.navigation.NavigationView
import com.google.firebase.appdistribution.FirebaseAppDistribution
import com.google.firebase.appdistribution.FirebaseAppDistributionException
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.BuildConfig
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
import okhttp3.ResponseBody
import java.io.File
interface NatsMessageCallback {
@@ -62,7 +59,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
private var downloadId: Long = 0
// TODO: Remove hemocube viewmodel
private val hemocubeViewModel: HemoCubeViewModel by viewModels()
private lateinit var sharedPreference: SharedPreferences
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
@@ -75,6 +72,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
Log.d(TAG, "Received message on topic $topic: $message")
}
@SuppressLint("SetWorldReadable")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -86,6 +84,9 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
nats.connect()
}
val versionName = getAppVersion(this@DashboardActivity) + " [ " + getAppEnvironment(this@DashboardActivity) + " ]"
binding.appBarDashboard.versionName.text = versionName
val deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "")
@@ -96,15 +97,22 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
when (result) {
is Result.Success -> {
// Handle success
val apkUrl = result.data
// val apkUrl = "https://dl.dropboxusercontent.com/s/fi/1c3nn7t0co431hicl3hrt/app-debug.apk?rlkey=e4uf13ty1dpcked614vy1aaqp&dl=0"
initiateUpdate(apkUrl.toString())
Log.d("ApI", "APK URL: $apkUrl")
// Toast.makeText(
// this,
// "APK UPLOAD ${result.data}",
// Toast.LENGTH_SHORT
// ).show()
val apk = result.data
val file = File(getExternalFilesDir("Updates"), "update.apk")
file.setReadable(true, false) // Ensure the file is readable
apk.byteStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}
Log.d("Responsebodyformat", "Responsebodyformat: ")
installApk(file)
Log.e("ApI", "APK URL: $apk")
Toast.makeText(
this,
"${result.data}",
Toast.LENGTH_SHORT
).show()
}
is Result.Error -> {
@@ -129,7 +137,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_home, R.id.nav_profile, R.id.nav_settings
R.id.nav_home, R.id.nav_profile, R.id.nav_activity,R.id.nav_settings
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
@@ -154,56 +162,15 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
private fun initiateUpdate(url: String) {
val apkUrl = url
if (!isValidHttpUrl(apkUrl)) {
return
}
val request = DownloadManager.Request(Uri.parse(apkUrl))
request.setTitle("App Update")
request.setDescription("Downloading update...")
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalFilesDir(this, "Updates", "update.apk")
val downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
downloadId = downloadManager.enqueue(request)
// Register a BroadcastReceiver to receive the download complete event
val filter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
isRegistered = true
registerReceiver(downloadReceiver, filter, RECEIVER_EXPORTED)
}
}
private fun extractApkUrl(responseBody: ResponseBody): String {
return responseBody.string()
}
private fun isValidHttpUrl(url: String): Boolean {
return url.startsWith("http://") || url.startsWith("https://")
}
private val downloadReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
if (id == downloadId) {
installApk()
}
}
}
private fun installApk() {
val file = File(getExternalFilesDir("Updates"), "update.apk")
file.setReadable(true, false) // Ensure the file is readable
private fun installApk(file: File) {
val pInfo = baseContext.packageManager.getPackageInfo(baseContext.packageName, 0)
val uri: Uri = FileProvider.getUriForFile(
this,
"in.sminnovations.hpostesting.dev.fileprovider",
"${BuildConfig.APPLICATION_ID}.fileprovider",
file
)
// Create an intent to install the APK
val installIntent = Intent(Intent.ACTION_INSTALL_PACKAGE)
installIntent.data = uri
installIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
@@ -221,7 +188,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
override fun onDestroy() {
if(isRegistered) {
try {
unregisterReceiver(downloadReceiver)
// unregisterReceiver(downloadReceiver)
} catch (e: Exception) {
Log.d("HomeFragment", e.toString())
}
@@ -278,6 +245,30 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
override fun setResponse(response: String) {
responses = responses+response+"\n"
println(responses)
Log.d("DashBoardActResponse",response)
// if (response.contains("checkUpdate")) {
// hemocubeViewModel.deviceUpdate(createDeviceUpdateRequestData())
// }
}
private fun createDeviceUpdateRequestData(): DeviceUpdateRequest {
return DeviceUpdateRequest(
serial_no = sharedPreference.getString(Constants.DEVICE_ID, "")
)
}
private fun getAppVersion(context: Context): String {
return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
pInfo.versionName
} catch (e: PackageManager.NameNotFoundException) {
"N/A"
}
}
private fun getAppEnvironment(context: Context): String {
return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
pInfo.packageName.substringAfterLast('.')
} catch (e: PackageManager.NameNotFoundException) {
"N/A"
}
}
}

View File

@@ -21,12 +21,12 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.api.DeviceCommunicationHandler
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.DeviceCommunicationHandler
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber

View File

@@ -12,7 +12,7 @@ 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.utils.UsbServiceListener
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase

View File

@@ -20,12 +20,12 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.api.DeviceCommunicationHandler
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.DeviceCommunicationHandler
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber

View File

@@ -4,6 +4,8 @@ import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.util.Log
import android.view.LayoutInflater
import android.view.View
@@ -12,16 +14,20 @@ import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.encryption.Encryption
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding
import java.io.File
import java.io.FileOutputStream
class DeviceProvisionFragment : Fragment() {
private var resultData: String = ""
@@ -122,6 +128,10 @@ class DeviceProvisionFragment : Fragment() {
deviceUpdateAvailable = false
)
)
encryptAndSaveToFile(
response.data.data?.credentials?.username.toString(),
response.data.data?.credentials?.password.toString()
)
// viewModel.addDeviceId(DeviceData(deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString()))
Log.e("idpass", response.toString())
Log.e("idpass", response.data.data?.credentials?.username.toString())
@@ -221,4 +231,25 @@ class DeviceProvisionFragment : Fragment() {
}
}
}
}
private fun encryptAndSaveToFile(username: String, password: String) {
val messageToEncrypt = "$username\n$password"
val encryptionKey =
Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID)
val encryptedString = Encryption.encrypt(messageToEncrypt, encryptionKey)
Log.d("DEVICE ID/encryptionKey", encryptionKey)
val target = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val file = File(target, "credentials.txt")
if (!file.exists()) {
file.createNewFile()
}
file.writeText(encryptedString)
Log.d("Encrypted Message", encryptedString)
}
}

View File

@@ -3,7 +3,7 @@ package com.example.hpostesting.presentation.deviceprovision
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -13,15 +13,15 @@ import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.Result.Success
import com.example.hpostesting.util.Result
import com.example.hpostesting.util.Result.Success
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.devicediagnostics.AdditionalDetails
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener
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.FragmentDiagnosticsBinding

View File

@@ -3,7 +3,7 @@ package com.example.hpostesting.presentation.diagnostics
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse
@@ -25,7 +25,7 @@ class DiagnosticsViewModel @Inject constructor(
val deviceData = MutableLiveData<DeviceData?>()
val fireBaseUpload = MutableLiveData<String>()
val deviceDiagnosticsResponse = MutableLiveData<com.example.hpostesting.data.Result<DeviceDiagnosticsResponse>>()
val deviceDiagnosticsResponse = MutableLiveData<Result<DeviceDiagnosticsResponse>>()
// private val batteryStatus: Intent? =
// IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
// context.registerReceiver(null, ifilter)

View File

@@ -10,7 +10,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import `in`.sminnovations.hpostesting.databinding.FragmentDigitalCardBinding
import java.text.SimpleDateFormat

View File

@@ -5,6 +5,7 @@ import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -13,15 +14,15 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.TestStatus
import com.example.hpostesting.data.model.TestState
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils
@@ -149,6 +150,7 @@ class HemoCubeFragment : Fragment() {
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
uploadedToCloud = true
var accessToken = sharedPreferences.getString(Constants.ACCESS_TOKEN, "").toString()
showToast(R.string.test_upload)
if (Constants.MOLBIO_INTEGRATION) {
hemoCubeViewModel.resultUpload.observe(viewLifecycleOwner) {
@@ -161,6 +163,8 @@ class HemoCubeFragment : Fragment() {
)
}
handleReadingFinish()
hemoCubeViewModel.uploadLogs()
hemoCubeViewModel.downloadClientCertificate()
}
is Result.Error -> {
@@ -169,10 +173,11 @@ class HemoCubeFragment : Fragment() {
it.exception.let { message ->
Toast.makeText(
activity,
"An error occurred: $message",
"$message",
Toast.LENGTH_LONG
)
.show()
Log.d("resultuploadfail1", message.toString())
}
handleReadingFinish()
}

View File

@@ -12,10 +12,10 @@ import androidx.lifecycle.viewModelScope
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import com.example.hpostesting.data.CsvWriter
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.CsvWriter
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.HemoCubeBufferDao
import com.example.hpostesting.data.dao.HemoCubeDao
@@ -38,6 +38,7 @@ import com.example.hpostesting.data.repository.Repository
import com.example.hpostesting.domain.CheckUpdateWorker
import com.example.hpostesting.domain.LogFileManager
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
@@ -88,7 +89,8 @@ class HemoCubeViewModel @Inject constructor(
private val _networkStatusLiveData = NetworkStatusLiveData(context)
val allUserData = hemoCubeDao.getAll()
val allPendingUserToUpload = MutableLiveData<List<HemoCubeTestData>>()
val allLocalData = hemoCubeDao.getAll()
val allPendingUserToUpload = hemoCubeDao.getPendingUser()
val allKitTestData = hemoCubeBufferDao.getAll()
val deviceData = MutableLiveData<DeviceData?>()
@@ -143,6 +145,97 @@ class HemoCubeViewModel @Inject constructor(
}
}
fun uploadResultfornew(molbioV2ResultRequest: MolbioV2ResultRequest) = viewModelScope.launch {
resultUpload.postValue(Result.Loading())
repository.uploadResults(molbioV2ResultRequest).let {
resultUpload.postValue(it)
}
}
fun sendDataToMolbio() = viewModelScope.launch(Dispatchers.IO) {
Log.d("molbio","getting in sendMolbio")
val resultList = MolbioV2ResultRequest(mutableListOf())
val pendingData = hemoCubeDao.getMolbioPending()
Log.d("molbio","pending size"+pendingData.size)
pendingData.forEach{
userData ->
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
)
)
}
resultList.results?.forEach { result ->
result.rawData?.let { sanitizeDoubleValues(it) }
}
if (resultList.results?.isNotEmpty() == true) {
uploadMoblioBulkResults(resultList)
}
}
fun uploadMoblioBulkResults(molbioV2ResultRequest: MolbioV2ResultRequest) = viewModelScope.launch {
Log.d("molbio","upload called")
repository.uploadResults(molbioV2ResultRequest).let {
when (it) {
is Result.Success -> {
it.data.data?.forEach { id ->
id.rawData?.let { it1 ->
updateMolbioFlag(
it1._id
)
}
}
}
is Result.Error -> {
Log.d("result","result upload error")
}
else -> {
Log.d("result","result upload else")
}
}
}
}
fun sendDataToFirebase() = viewModelScope.launch ( Dispatchers.IO ) {
val pendingData = hemoCubeDao.getFirebasePending()
pendingData.forEach{
userData ->
if (userData != null) {
if (!userData.localFlag) {
bulkAddResultTestToDb(userData)
}
}
}
}
fun checkUpdate(checkUpdateRequest: CheckUpdateRequest) = viewModelScope.launch {
checkUpdate.postValue(Result.Loading())
repository.checkUpdate(checkUpdateRequest).let {
@@ -187,9 +280,9 @@ class HemoCubeViewModel @Inject constructor(
}
}
}
fun uploadPendingUser() = viewModelScope.launch {
allPendingUserToUpload.postValue(hemoCubeDao.getPendingUser(false))
}
// fun getPendingUser() = viewModelScope.launch {
// allPendingUserToUpload.postValue(hemoCubeDao.getPendingUser(true))
// }
fun uploadHemoCubeResultToDatabaseForBufferCheck(
isOnline: Boolean,
@@ -325,20 +418,24 @@ class HemoCubeViewModel @Inject constructor(
fireBaseUpload.postValue("Success")
testDetails.localFlag = true
if (Constants.MOLBIO_INTEGRATION) {
// Sanitize testDetails before using it in the API call
val sanitizedTestDetails = sanitizeDoubleValues(testDetails)
// Now, use sanitizedTestDetails for the API call
uploadResult(
MolbioV2ResultRequest(
mutableListOf(
MolbioV2Result(
rawData = testDetails,
analysisId = testDetails._id,
analysisDate = testDetails.testTime,
analysisStatus = testDetails.classificationResult,
thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[testDetails.deviceId].toString(),
interpretation = testDetails.classificationResult,
testId = testDetails._id,
testTime = testDetails.testTime,
collectionTime = testDetails.testTime,
expiryTime = testDetails.testTime,
rawData = sanitizedTestDetails,
analysisId = sanitizedTestDetails._id,
analysisDate = sanitizedTestDetails.testTime,
analysisStatus = sanitizedTestDetails.classificationResult,
thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[sanitizedTestDetails.deviceId]?.toString(),
interpretation = sanitizedTestDetails.classificationResult,
testId = sanitizedTestDetails._id,
testTime = sanitizedTestDetails.testTime,
collectionTime = sanitizedTestDetails.testTime,
expiryTime = sanitizedTestDetails.testTime,
)
)
)
@@ -380,6 +477,19 @@ class HemoCubeViewModel @Inject constructor(
}
}
fun sanitizeDoubleValues(hemoCubeTestData: HemoCubeTestData): HemoCubeTestData {
hemoCubeTestData::class.java.declaredFields.forEach { field ->
if (field.type == Double::class.javaObjectType || field.type == Double::class.javaPrimitiveType) {
field.isAccessible = true
val value = field.get(hemoCubeTestData) as Double?
if (value != null && (value.isInfinite() || value.isNaN())) {
field.set(hemoCubeTestData, 0.0) // Replace with a suitable default value
}
}
}
return hemoCubeTestData
}
private fun updateLocalFlag(userId: String) = viewModelScope.launch {
hemoCubeDao.updateFieldById(id = userId, true)
}

View File

@@ -18,10 +18,11 @@ import android.util.Log
import android.view.Menu
import android.widget.Toast
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService
@@ -44,6 +45,7 @@ open class HemocubeActivity : AppCompatActivity() {
private val TAG = "HemoCube"
private val broadcastReceiver = object : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onReceive(context: Context, intent: Intent) {
synchronized(this) {
@@ -83,6 +85,7 @@ open class HemocubeActivity : AppCompatActivity() {
super.attachBaseContext(newBase)
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHemocubeBinding.inflate(layoutInflater)
@@ -107,6 +110,7 @@ open class HemocubeActivity : AppCompatActivity() {
}
}
@RequiresApi(Build.VERSION_CODES.O)
open fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager
@@ -126,6 +130,7 @@ open class HemocubeActivity : AppCompatActivity() {
}
}
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("MutableImplicitPendingIntent")
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent
@@ -151,11 +156,13 @@ open class HemocubeActivity : AppCompatActivity() {
manager.requestPermission(device, mPendingIntent)
}
fun setupService() {
val intent = Intent(this, UsbService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
@RequiresApi(Build.VERSION_CODES.O)
open fun reconnectDevice() {
mService.disconnect()
unbindService(connection)

View File

@@ -21,7 +21,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -19,7 +19,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
@@ -132,7 +132,7 @@ class TestRightActivity : AppCompatActivity() {
this,
0,
Intent(Constants.ACTION_USB_PERMISSION),
PendingIntent.FLAG_MUTABLE
PendingIntent.FLAG_IMMUTABLE
)
} else {
mPendingIntent = PendingIntent.getBroadcast(

View File

@@ -10,11 +10,11 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpostesting.data.model.ErrorMessage
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils
import dagger.hilt.android.AndroidEntryPoint

View File

@@ -10,13 +10,13 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpostesting.data.model.ErrorMessage
import com.example.hpostesting.data.model.test.TestType
import com.example.hpostesting.presentation.MainActivity
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils
import dagger.hilt.android.AndroidEntryPoint

View File

@@ -11,7 +11,7 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.test.TestRightResultType
import com.example.hpostesting.data.model.test.TestType

View File

@@ -5,8 +5,8 @@ import android.net.Uri
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.CalculationVariableForTest

View File

@@ -9,7 +9,7 @@ import android.util.Log
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialPort
import com.hoho.android.usbserial.util.SerialInputOutputManager

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.hemocube.HemoCubeFragment

View File

@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -13,15 +14,15 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.TestStatus
import com.example.hpostesting.data.model.TestState
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import com.example.hpostesting.presentation.utils.MyDialogListener
@@ -1155,6 +1156,8 @@ class TrueHemeFragment : Fragment() {
}
private fun reconnect() {
(activity as HemocubeActivity).reconnectDevice()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
(activity as HemocubeActivity).reconnectDevice()
}
}
}

View File

@@ -12,10 +12,10 @@ import androidx.lifecycle.viewModelScope
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import com.example.hpostesting.data.CsvWriter
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.CsvWriter
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.HemoCubeBufferDao
import com.example.hpostesting.data.dao.HemoCubeDao

View File

@@ -1,12 +1,6 @@
package com.example.hpostesting.data.api
package com.example.hpostesting.presentation.utils
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.presentation.UsbServiceListener
interface PropertyProvider {
fun getProperty(key: String): String
}
interface DeviceCommunicationHandler {
fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener)

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.presentation
package com.example.hpostesting.presentation.utils
import android.content.Context
import android.os.Build

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.presentation
package com.example.hpostesting.presentation.utils
interface UsbServiceListener {
fun onUsbRead(data: ByteArray?)

View File

@@ -1,8 +1,9 @@
package com.example.hpostesting.presentation
package com.example.hpostesting.presentation.utils
import android.content.Context
import android.util.Log
import android.widget.Toast
import com.example.hpostesting.presentation.utils.UsbServiceListener
class UsbServiceListenerImpl(private val context: Context): UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {

View File

@@ -1,11 +0,0 @@
package com.example.hpostesting
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
fun main(){
val dateFormat = SimpleDateFormat("MM:HHddMMyyyy", Locale.getDefault())
val currentDate = Date()
print(dateFormat.format(currentDate))
}

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data
package com.example.hpostesting.util
import android.content.Context
import android.os.Environment

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data
package com.example.hpostesting.util
import android.content.Context

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data
package com.example.hpostesting.util
import android.content.Context
import android.content.SharedPreferences

View File

@@ -0,0 +1,7 @@
package com.example.hpostesting.util
interface PropertyProvider {
fun getProperty(key: String): String
}

View File

@@ -1,7 +1,6 @@
package com.example.hpostesting.util
import android.content.res.AssetManager
import com.example.hpostesting.data.api.PropertyProvider
import java.io.InputStream
import java.util.Properties

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data
package com.example.hpostesting.util
sealed class Result<out T : Any> {
data class Success<out T : Any>(val data: T) : Result<T>()

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM14,17L7,17v-2h7v2zM17,13L7,13v-2h10v2zM17,9L7,9L7,7h10v2z"/>
</vector>

View File

@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.dashboard.DashboardActivity">
>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
@@ -16,7 +16,17 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.HPOS.PopupOverlay" />
app:popupTheme="@style/Theme.HPOS.PopupOverlay" >
<TextView
android:id="@+id/version_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="--"
android:textStyle="bold"
android:layout_gravity="end"
android:textSize="18sp"
android:layout_marginEnd="15dp"/>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/titleText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="Upload Pending List(Local data)"
android:layout_marginTop="5dp"
android:textSize="21sp"
android:textColor="@color/black"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_order_offline"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/titleText"
android:layout_alignParentStart="true"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/offline_user_list_view" />
<TextView
android:id="@+id/noDataText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="All up-to-date"
android:textSize="22sp"
android:textColor="@color/black"
/>
</RelativeLayout>

View File

@@ -38,10 +38,20 @@
android:visibility="gone"
android:padding="24dp">
<ImageView
android:id="@+id/btnLogout1"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="10dp"
android:src="@drawable/baseline_logout_24"
app:layout_constraintTop_toTopOf="@+id/internetNotAvailableCL"
app:layout_constraintEnd_toEndOf="parent"
/>
<TextView
android:id="@+id/tv_title_no_internet"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="24dp"
@@ -125,6 +135,27 @@
<!-- app:layout_constraintBottom_toBottomOf="@+id/rv_order_offline"-->
<!-- app:layout_constraintStart_toStartOf="parent" />-->
<TextView
android:id="@+id/label1"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/new_kit"
app:layout_constraintBottom_toTopOf="@+id/btnNewKitoffline"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnNewKitoffline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:backgroundTint="@color/primary"
android:contentDescription="@string/new_kit"
android:src="@drawable/ic_add"
app:elevation="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout

View File

@@ -12,6 +12,10 @@
android:id="@+id/nav_profile"
android:icon="@drawable/control_panel"
android:title="@string/profile" />
<item
android:id="@+id/nav_activity"
android:icon="@drawable/shows_activity_24"
android:title="@string/action_activity" />
<item
android:id="@+id/nav_settings"
android:icon="@drawable/baseline_settings_24"

View File

@@ -32,6 +32,11 @@
android:name="com.example.hpostesting.presentation.dashboard.SlideshowFragment"
android:label="@string/action_settings"
tools:layout="@layout/fragment_slideshow" />
<fragment
android:id="@+id/nav_activity"
android:name="com.example.hpostesting.presentation.dashboard.ActivitiesFragment"
android:label="@string/action_activity"
tools:layout="@layout/fragment_activities" />
<activity
android:id="@+id/mainActivity"
android:name="com.example.hpostesting.presentation.MainActivity"

View File

@@ -271,4 +271,5 @@
<string name="deviceinfo">डिवाइस जानकारी</string>
<string name="downloadcsv">सीएसवी डाउनलोड करें</string>
<string name="action_activity">Activities</string>
</resources>

View File

@@ -270,6 +270,7 @@
<string name="add_blood_group">ರಕ್ತ ಗುಂಡನ್ನು ಸೇರಿಸಿ</string>
<string name="ok">ಸರಿ</string>
<string name="downloadcsv">CSV ಡೌನ್ಲೋಡ್ ಮಾಡಿ</string>
<string name="action_activity">Activities</string>
<!-- Add translations for other strings -->
</resources>

View File

@@ -273,4 +273,5 @@
<string name="select_language">Select your preferred language</string>
<string name="app_language">App Language</string>
<string name="ok">OK</string>
<string name="action_activity">Activities</string>
</resources>

View File

@@ -3,18 +3,15 @@ package com.example.hpostesting
import android.content.Context
import android.content.SharedPreferences
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.util.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 com.example.hpostesting.presentation.autodac.AutoDacViewModel
import io.mockk.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.setMain

View File

@@ -1,7 +1,7 @@
package com.example.hpostesting
import android.content.Context
import com.example.hpostesting.data.CsvWriter
import com.example.hpostesting.util.CsvWriter
import org.junit.Assert
import org.junit.Before
import org.junit.Test

View File

@@ -1,26 +1,5 @@
package com.example.hpostesting
import android.content.Context
import android.content.SharedPreferences
import androidx.fragment.app.testing.FragmentScenario
import androidx.fragment.app.testing.launchFragmentInContainer
import androidx.lifecycle.MutableLiveData
import androidx.test.core.app.ApplicationProvider
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.presentation.deviceinfo.DeviceActivity
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
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.MockitoAnnotations
class DeviceFragmentTest {
//
// @Mock

View File

@@ -2,7 +2,7 @@ package com.example.hpostesting
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse
import com.example.hpostesting.data.repository.Repository

View File

@@ -3,7 +3,7 @@ package com.example.hpostesting
import android.content.Context
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer
import com.example.hpostesting.data.Result
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.login.LoginResponse
import com.example.hpostesting.data.repository.Repository
import com.example.hpostesting.domain.LogFileManager

View File

@@ -1,22 +1,5 @@
package com.example.hpostesting
import android.content.Context
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import java.math.RoundingMode
import java.text.DecimalFormat
class TestRightViewModelTest {
// private val viewModel = TestRightViewModel()
// private val data = InputData()

View File

@@ -3,9 +3,9 @@ buildscript {
kotlin_version = '1.8.21'
}
dependencies {
classpath 'com.android.tools.build:gradle:8.3.0'
classpath 'com.google.gms:google-services:4.4.0'
classpath 'com.google.firebase:firebase-appdistribution-gradle:4.0.1'
classpath 'com.android.tools.build:gradle:8.2.2'
classpath 'com.google.gms:google-services:4.4.1'
classpath 'com.google.firebase:firebase-appdistribution-gradle:4.1.0'
}
repositories {
mavenCentral()

View File

@@ -1,4 +1,4 @@
#Mon Jun 12 17:07:47 IST 2023
#Mon Mar 04 17:08:24 IST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip