1 Commits

Author SHA1 Message Date
mohamedkaif356
fc9228d3ff Added Adapter and Service 2023-08-07 12:02:35 +05:30
35 changed files with 667 additions and 8 deletions

View File

@@ -9,12 +9,12 @@ plugins {
android {
namespace = "in.sminnovations.homocube"
compileSdk = 33
compileSdk = 34
defaultConfig {
applicationId = "in.sminnovations.homocube"
minSdk = 24
targetSdk = 33
targetSdk = 34
versionCode = 1
versionName = "1.0"
@@ -94,5 +94,8 @@ dependencies {
// Barcode scanner
implementation("com.journeyapps:zxing-android-embedded:4.3.0")
//USB
implementation("com.github.mik3y:usb-serial-for-android:3.5.1")
}

View File

@@ -13,8 +13,12 @@
android:supportsRtl="true"
android:theme="@style/Theme.HomoCube"
tools:targetApi="31">
<service
android:name=".presentation.services.USBService"
android:enabled="true"
android:exported="false" />
<activity
android:name=".ui.MainActivity"
android:name=".presentation.ui.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View File

@@ -0,0 +1,29 @@
package `in`.sminnovations.homocube.data
import androidx.lifecycle.LiveData
import `in`.sminnovations.homocube.data.api.FirebaseAPI
import `in`.sminnovations.homocube.data.dao.TestDao
import `in`.sminnovations.homocube.data.model.Response
import `in`.sminnovations.homocube.data.model.TestData
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class Repository @Inject constructor(
private val testDao: TestDao,
private val firebaseAPI: FirebaseAPI
) {
val testData: LiveData<List<TestData>> = testDao.getTestData()
suspend fun insertTestData(testData: TestData) {
testDao.insertTestData(testData)
}
suspend fun deleteTestDataByID(id: String) {
testDao.deleteTestDataByID(id)
}
suspend fun addTestDetails(testData: TestData): Response<String> {
return firebaseAPI.addTestDetails(testData)
}
}

View File

@@ -0,0 +1,23 @@
package `in`.sminnovations.homocube.data.api
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.homocube.data.model.Response
import `in`.sminnovations.homocube.data.model.TestData
import kotlinx.coroutines.tasks.await
class FirebaseAPI {
private val patientCollection = Firebase.firestore.collection("patientData")
suspend fun addTestDetails(testData: TestData): Response<String> {
return try {
val documentReference = patientCollection.document()
documentReference.set(testData).await()
Response.Success(documentReference.id)
} catch (e: Exception) {
Response.Error(e)
}
}
}

View File

@@ -0,0 +1,6 @@
package `in`.sminnovations.homocube.data.constant
object Constant {
const val WRITE_TIMEOUT_MILLIS = 30000
}

View File

@@ -0,0 +1,8 @@
package `in`.sminnovations.homocube.data.constant
enum class HemoCubeCommands(val command: String) {
startBuffer("B\r"),
getBuffer("Q\r"),
startSample("S\r"),
getSample("R\r"),
}

View File

@@ -0,0 +1,10 @@
package `in`.sminnovations.homocube.data.dao
import androidx.room.Database
import androidx.room.RoomDatabase
import `in`.sminnovations.homocube.data.model.TestData
@Database(entities = [TestData::class], version = 1, exportSchema = false)
abstract class MyDatabase : RoomDatabase() {
abstract fun userDao(): TestDao
}

View File

@@ -0,0 +1,20 @@
package `in`.sminnovations.homocube.data.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import `in`.sminnovations.homocube.data.model.TestData
@Dao
interface TestDao {
@Query("SELECT * from test_table")
fun getTestData(): LiveData<List<TestData>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertTestData(testData: TestData)
@Query("DELETE FROM test_table WHERE _id = :id")
suspend fun deleteTestDataByID(id: String)
}

View File

@@ -0,0 +1,7 @@
package `in`.sminnovations.homocube.data.model
sealed class Response<out R> {
data class Success<out T : Any>(val data: T) : Response<T>()
data class Error(val exception: Exception) : Response<Nothing>()
class Loading<T : Any> : Response<T>()
}

View File

@@ -0,0 +1,10 @@
package `in`.sminnovations.homocube.data.model
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "test_table")
data class TestData(
@PrimaryKey
val _id: String = ""
)

View File

@@ -0,0 +1,5 @@
package `in`.sminnovations.homocube.data.model
data class UserData (
val _id: String = ""
)

View File

@@ -0,0 +1,58 @@
package `in`.sminnovations.homocube.domain
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import androidx.lifecycle.LiveData
class NetworkStatusLiveData(context: Context) : LiveData<Boolean>() {
private val connectivityManager: ConnectivityManager =
context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
postValue(true)
}
override fun onLost(network: Network) {
postValue(false)
}
}
override fun onActive() {
super.onActive()
postValue(isNetworkAvailable())
registerNetworkCallback()
}
override fun onInactive() {
super.onInactive()
unregisterNetworkCallback()
}
private fun registerNetworkCallback() {
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.build()
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
}
private fun unregisterNetworkCallback() {
connectivityManager.unregisterNetworkCallback(networkCallback)
}
private fun isNetworkAvailable(): Boolean {
val network = connectivityManager.activeNetwork
val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
return networkCapabilities != null &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}
}

View File

@@ -0,0 +1,45 @@
package `in`.sminnovations.homocube.presentation.di
import android.app.Application
import android.content.Context
import androidx.room.Room
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import `in`.sminnovations.homocube.data.api.FirebaseAPI
import `in`.sminnovations.homocube.data.dao.MyDatabase
import `in`.sminnovations.homocube.data.dao.TestDao
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideMyDatabase(@ApplicationContext context: Context): MyDatabase {
return Room.databaseBuilder(
context, MyDatabase::class.java, "my_database"
).build()
}
@Provides
@Singleton
fun provideMyDao(myDatabase: MyDatabase): TestDao {
return myDatabase.userDao()
}
@Provides
@Singleton
fun provideFirebaseAPI(): FirebaseAPI {
return FirebaseAPI()
}
@Provides
@Singleton
fun provideContext(application: Application): Context {
return application.applicationContext
}
}

View File

@@ -0,0 +1,75 @@
package `in`.sminnovations.homocube.presentation.services
import android.app.Service
import android.content.Intent
import android.hardware.usb.UsbDeviceConnection
import android.os.Binder
import android.os.IBinder
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialPort
import com.hoho.android.usbserial.util.SerialInputOutputManager
import `in`.sminnovations.homocube.data.constant.Constant
import `in`.sminnovations.homocube.data.constant.HemoCubeCommands
import java.io.IOException
class USBService : Service() {
private val binder = UsbServiceBinder()
private lateinit var mPort: UsbSerialPort
private var isUsbConnected = false
inner class UsbServiceBinder : Binder() {
fun getService(): USBService = this@USBService
}
override fun onBind(intent: Intent): IBinder {
return binder
}
var listener: UsbServiceListener? = null
private var bus: UsbServiceListener? = null
fun connect(driver: UsbSerialDriver, connection: UsbDeviceConnection) {
mPort = driver.ports[0] // Most devices have just one port (port 0)
mPort.open(connection)
mPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
isUsbConnected = true
val usbIoManager = SerialInputOutputManager(mPort,
object : SerialInputOutputManager.Listener {
override fun onNewData(data: ByteArray?) {
listener?.onUsbRead(data)
}
override fun onRunError(e: Exception?) {
listener?.onUsbError(e)
}
})
usbIoManager.start()
}
fun disconnect() {
if (isUsbConnected) {
mPort.close()
isUsbConnected = false
}
}
fun listenToHemoCube(listener: UsbServiceListener) {
this.listener = listener
try {
} catch (e: IOException) {
listener.onUsbError(e)
}
}
fun sendAndListenToHemoCube(command: HemoCubeCommands, listener: UsbServiceListener) {
try {
this.bus = listener
mPort.write(command.command.toByteArray(), Constant.WRITE_TIMEOUT_MILLIS)
} catch (e: IOException) {
listener.onUsbError(e)
}
}
}

View File

@@ -0,0 +1,6 @@
package `in`.sminnovations.homocube.presentation.services
interface UsbServiceListener {
fun onUsbRead(data: ByteArray?)
fun onUsbError(e: Exception?)
}

View File

@@ -1,4 +1,4 @@
package `in`.sminnovations.homocube.ui
package `in`.sminnovations.homocube.presentation.ui
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

View File

@@ -0,0 +1,4 @@
package `in`.sminnovations.homocube.presentation.ui.adapter
class UserListAdapter() {
}

View File

@@ -0,0 +1,23 @@
package `in`.sminnovations.homocube.presentation.ui.fragment
import android.view.View
import android.widget.Button
import androidx.fragment.app.Fragment
open class BaseFragment: Fragment() {
fun hideProgressBar(view: View) {
view.visibility = View.GONE
}
fun showProgressBar(view: View) {
view.visibility = View.VISIBLE
}
fun markButtonDisable(button: Button) {
button.isEnabled = false
}
fun markButtonEnable(button: Button) {
button.isEnabled = true
}
}

View File

@@ -0,0 +1,28 @@
package `in`.sminnovations.homocube.presentation.ui.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import `in`.sminnovations.homocube.databinding.FragmentUserListBinding
class KitInformationFragment : Fragment() {
private var _binding: FragmentUserListBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentUserListBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,31 @@
package `in`.sminnovations.homocube.presentation.ui.fragment
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import `in`.sminnovations.homocube.databinding.FragmentLoginBinding
class LoginFragment : Fragment() {
private var _binding: FragmentLoginBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentLoginBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,31 @@
package `in`.sminnovations.homocube.presentation.ui.fragment
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import `in`.sminnovations.homocube.databinding.FragmentResultBinding
class ResultFragment : Fragment() {
private var _binding: FragmentResultBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentResultBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,27 @@
package `in`.sminnovations.homocube.presentation.ui.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import `in`.sminnovations.homocube.databinding.FragmentSelectTestBinding
class SelectTestFragment : Fragment() {
private var _binding: FragmentSelectTestBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentSelectTestBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,32 @@
package `in`.sminnovations.homocube.presentation.ui.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import `in`.sminnovations.homocube.databinding.FragmentTestBinding
class TestFragment : Fragment() {
private var _binding: FragmentTestBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentTestBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,43 @@
package `in`.sminnovations.homocube.presentation.ui.fragment
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import `in`.sminnovations.homocube.databinding.FragmentUserListBinding
import `in`.sminnovations.homocube.presentation.ui.adapter.UserListAdapter
class UserListFragment : BaseFragment() {
private var _binding: FragmentUserListBinding? = null
private val binding get() = _binding!!
private lateinit var sharedPreference: SharedPreferences
private val adapter = UserListAdapter()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentUserListBinding.inflate(inflater, container, false)
sharedPreference = requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
private fun init() {
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,45 @@
package `in`.sminnovations.homocube.presentation.ui.viewmodels
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import `in`.sminnovations.homocube.data.Repository
import `in`.sminnovations.homocube.data.model.Response
import `in`.sminnovations.homocube.data.model.TestData
import `in`.sminnovations.homocube.domain.NetworkStatusLiveData
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class MainViewModel @Inject constructor(
private val repository: Repository,
context: Context
) : ViewModel(){
val fireBaseUpload = MutableLiveData<Response<String>>()
val allUserData = repository.testData
fun addDataToFirebase(testData: TestData) = viewModelScope.launch {
fireBaseUpload.postValue(Response.Loading())
repository.addTestDetails(testData).let {
fireBaseUpload.postValue(it)
}
}
fun insertTestData(testData: TestData) = viewModelScope.launch {
repository.insertTestData(testData)
}
fun deleteTestDataByID(userId: String) = viewModelScope.launch {
repository.deleteTestDataByID(id = userId)
}
private val _networkStatusLiveData = NetworkStatusLiveData(context)
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
}

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=".ui.MainActivity">
tools:context=".presentation.ui.MainActivity">
<TextView
android:layout_width="wrap_content"

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.ui.fragment.KitInformationFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.ui.fragment.LoginFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.ui.fragment.ResultFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.ui.fragment.SelectTestFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.ui.fragment.TestFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.ui.fragment.UserListFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>

View File

@@ -1,3 +1,5 @@
<resources>
<string name="app_name">HomoCube</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources>

View File

@@ -1,6 +1,6 @@
#Mon Jul 31 21:35:38 IST 2023
#Mon Aug 07 11:32:44 IST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -10,9 +10,9 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven("https://jitpack.io")
}
}
rootProject.name = "HomoCube"
include(":app")