Skip to content

Commit

Permalink
Biometrics: basic ui
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandr7035 committed Mar 5, 2023
1 parent 3b7d18c commit 57ca946
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 13 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ dependencies {
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.biometric:biometric-ktx:1.2.0-alpha05'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package by.alexandr7035.affinidi_id.presentation.common.biometrics

import android.content.Context
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG
import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL


class BiometricsHelper {
fun checkIfBiometricsAvailable(context: Context): Int {
val biometricManager = BiometricManager.from(context)
return biometricManager.canAuthenticate(BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.biometric.BiometricManager
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
Expand All @@ -14,12 +17,11 @@ import by.alexandr7035.affinidi_id.BuildConfig
import by.alexandr7035.affinidi_id.R
import by.alexandr7035.affinidi_id.core.extensions.debug
import by.alexandr7035.affinidi_id.core.extensions.navigateSafe
import by.alexandr7035.affinidi_id.core.extensions.showToast
import by.alexandr7035.affinidi_id.core.extensions.svgLoader
import by.alexandr7035.affinidi_id.databinding.FragmentMainMenuBinding
import by.alexandr7035.affinidi_id.presentation.common.biometrics.BiometricsHelper
import by.kirich1409.viewbindingdelegate.viewBinding
import coil.ComponentRegistry
import coil.ImageLoader
import coil.decode.SvgDecoder
import coil.load
import dagger.hilt.android.AndroidEntryPoint
import timber.log.Timber
Expand Down Expand Up @@ -92,5 +94,44 @@ class MainMenuFragment : Fragment() {

true
}

binding.biometricsSwitch.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
requireContext().showToast("Enable biometrics", Toast.LENGTH_SHORT)
// viewModel.checkBiometricAvailability(requireContext())
}
else {
requireContext().showToast("Disable biometrics", Toast.LENGTH_SHORT)
}
}

viewModel.biometricsAvailableStatusLiveData.observe(viewLifecycleOwner) { biometricsStatus ->

fun disableBiometricsSwitch() {
binding.biometricsSwitch.isEnabled = false
binding.biometricsSwitch.isChecked = false
binding.biometricError.isVisible = true
}

when (biometricsStatus ) {
BiometricManager.BIOMETRIC_SUCCESS -> {
requireContext().showToast( "App can authenticate using biometrics.")
}
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> {
disableBiometricsSwitch()
binding.biometricError.text = getString(R.string.biometrics_not_available)
}
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> {
disableBiometricsSwitch()
binding.biometricError.text = getString(R.string.biometrics_not_available)
}
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
disableBiometricsSwitch()
binding.biometricError.text = getString(R.string.biometrics_not_enabled)
}
}
}

viewModel.checkBiometricAvailability(requireContext())
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package by.alexandr7035.affinidi_id.presentation.main_menu

import android.content.Context
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import by.alexandr7035.affinidi_id.domain.model.profile.UserProfile
import by.alexandr7035.affinidi_id.domain.usecase.user.GetProfileUseCase
import by.alexandr7035.affinidi_id.presentation.common.biometrics.BiometricsHelper
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

Expand All @@ -12,7 +14,17 @@ class MainMenuViewModel @Inject constructor(private val getProfileUseCase: GetPr

val userProfileLiveData = MutableLiveData<UserProfile>()

private val _biometricsAvailableStatusLiveData = MutableLiveData<Int>()
val biometricsAvailableStatusLiveData = _biometricsAvailableStatusLiveData

private val biometricsHelper = BiometricsHelper()

fun init() {
userProfileLiveData.value = getProfileUseCase.execute()
}

fun checkBiometricAvailability(context: Context) {
val res = biometricsHelper.checkIfBiometricsAvailable(context)
biometricsAvailableStatusLiveData.value = res
}
}
48 changes: 39 additions & 9 deletions app/src/main/res/layout/fragment_main_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,56 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_fragment_margin"
android:overScrollMode="never"
tools:listitem="@layout/view_primary_menu_item"
android:paddingStart="@dimen/default_fragment_margin"
android:paddingEnd="@dimen/default_fragment_margin"
android:paddingTop="@dimen/default_fragment_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/profileImageView"
tools:itemCount="3"
android:layout_marginTop="@dimen/default_fragment_margin"
android:padding="@dimen/default_fragment_margin"
app:layout_constraintBottom_toTopOf="@id/appVersionView"
tools:listitem="@layout/view_primary_menu_item" />

<androidx.appcompat.widget.SwitchCompat
style="@style/SwitchMenuItem"
android:text="@string/lock_with_biometrics"
android:id="@+id/biometricsSwitch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingStart="@dimen/default_fragment_margin"
android:paddingEnd="@dimen/default_fragment_margin"
app:layout_constraintVertical_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/appVersionView"
app:layout_constraintTop_toBottomOf="@id/recycler"/>

<TextView
android:id="@+id/biometricError"
android:visibility="gone"
tools:visibility="visible"
android:textSize="14sp"
android:textColor="@color/gray_300"
android:layout_marginStart="@dimen/default_fragment_margin"
android:layout_marginEnd="@dimen/default_fragment_margin"
tools:text="No biometric features available on this device"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/profileImageView" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/biometricsSwitch"
android:layout_width="0dp"
android:layout_height="wrap_content"/>

<TextView
android:id="@+id/appVersionView"
style="@style/AppVersionStyle"
tools:text="AffinidiID v0.1-alpha"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/default_fragment_margin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
app:layout_constraintStart_toStartOf="parent"
tools:text="AffinidiID v0.1-alpha" />

</androidx.constraintlayout.widget.ConstraintLayout>
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,7 @@
<string name="claims">Claims</string>
<string name="issued_by">Issued by</string>

<string name="lock_with_biometrics">Lock app with biometrics</string>
<string name="biometrics_not_available">Biometrics is unavailable on your device</string>
<string name="biometrics_not_enabled">Biometrics is not enabled on device. Please, enable biometrics in settings</string>
</resources>
8 changes: 7 additions & 1 deletion app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,19 @@
<item name="android:textColor">@color/gray_500</item>
</style>

<style name="SwitchMenuItem">
<item name="switchPadding">16dp</item>
<item name="android:textSize">18sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/gray_500</item>
</style>

<style name="AppVersionStyle">
<item name="android:textSize">14sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/gray_500</item>
</style>


<style name="ErrorViewTitle">
<item name="android:textSize">@dimen/error_view_tile_text</item>
<item name="android:textStyle">bold</item>
Expand Down

0 comments on commit 57ca946

Please sign in to comment.