Files
super-app/navi-base/src/main/java/com/navi/base/utils/BaseUtils.kt
2023-08-30 05:31:33 +00:00

521 lines
19 KiB
Kotlin

/*
*
* * Copyright © 2021-2023 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.base.utils
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.Uri
import android.os.Build
import android.provider.Settings
import com.navi.base.sharedpref.CommonPrefConstants
import com.navi.base.sharedpref.CommonPrefConstants.ALFRED_DIALOG_SCREENSHOT
import com.navi.base.sharedpref.CommonPrefConstants.UPDATED_BASE_URL
import com.navi.base.sharedpref.CommonPrefConstants.UPDATED_PULSE_BASE_URL
import com.navi.base.sharedpref.CommonPrefConstants.UPDATED_VERSION_CODE
import com.navi.base.sharedpref.PreferenceManager
import java.util.Locale
object BaseUtils {
fun getDeviceId(applicationContext: Context): String {
return Settings.System.getString(
applicationContext.contentResolver,
Settings.Secure.ANDROID_ID
)
}
fun getDefaultLocale(): String {
try {
return Locale.getDefault().toString()
} catch (_: Exception) {}
return ""
}
fun isUserLoggedIn(): Boolean {
val sessionToken =
PreferenceManager.getSecureString(CommonPrefConstants.SESSION_TOKEN)
?: run { PreferenceManager.getStringPreference(CommonPrefConstants.SESSION_TOKEN) }
return !sessionToken.isNullOrBlank()
}
fun getSessionToken(): String? {
return PreferenceManager.getSecureString(CommonPrefConstants.SESSION_TOKEN)
?: run { PreferenceManager.getStringPreference(CommonPrefConstants.SESSION_TOKEN) }
}
fun saveSessionToken(sessionToken: String) {
PreferenceManager.saveStringSecurely(CommonPrefConstants.SESSION_TOKEN, sessionToken)
}
fun getRefreshToken(): String? {
return PreferenceManager.getSecureString(CommonPrefConstants.REFRESH_TOKEN)
?: run { PreferenceManager.getStringPreference(CommonPrefConstants.REFRESH_TOKEN) }
}
fun saveRefreshToken(refreshToken: String) {
PreferenceManager.saveStringSecurely(CommonPrefConstants.REFRESH_TOKEN, refreshToken)
}
fun getPhoneNumber(): String? {
return PreferenceManager.getSecureString(CommonPrefConstants.PHONE_NUMBER)
?: run { PreferenceManager.getStringPreference(CommonPrefConstants.PHONE_NUMBER) }
}
fun getEmail(): String? {
return PreferenceManager.getSecureString(CommonPrefConstants.EMAIL)
?: run { PreferenceManager.getStringPreference(CommonPrefConstants.EMAIL) }
}
fun savePhoneNumber(phoneNumber: String) {
PreferenceManager.saveStringSecurely(CommonPrefConstants.PHONE_NUMBER, phoneNumber)
}
fun saveEmail(email: String) {
PreferenceManager.saveStringSecurely(CommonPrefConstants.EMAIL, email)
}
fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val network = connectivityManager?.activeNetwork ?: return false
val activeNetwork = connectivityManager.getNetworkCapabilities(network) ?: return false
return when {
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
else -> false
}
} else {
return connectivityManager?.activeNetworkInfo?.isConnected.orFalse()
}
}
fun isFirebaseTokenRefreshed(): Boolean {
return PreferenceManager.getBooleanPreferenceApp(
CommonPrefConstants.IS_FIREBASE_TOKEN_REFRESHED
)
}
fun setFirebaseTokenRefreshed(value: Boolean) {
PreferenceManager.setBooleanPreferenceApp(
CommonPrefConstants.IS_FIREBASE_TOKEN_REFRESHED,
value
)
}
fun getPhoneNumberWithCountryCode(): String? {
var phoneNumber = getPhoneNumber()
if (phoneNumber?.contains("+91").orFalse().not()) {
phoneNumber = "+91 ".plus(phoneNumber)
}
return phoneNumber
}
fun getDigioExceptionReasonForAadhaarOtp(errorCode: Int?): String {
return when (errorCode) {
1001 -> "Invalid Input"
1002 -> "Init not called yet."
1003 -> "User Cancelled"
1004 -> "Internal Error, Try after some time"
1005 -> "Internet not connected"
1006 -> "Server Error, Try after some time"
1007 -> "Error from UIDAI"
1008 -> "Authentication Failed"
else -> "Reason Unknown"
}
}
fun getHyperVergeReasonForSelfieVerification(errorCode: Int?): String {
return when (errorCode) {
2 -> "INTERNAL_SDK_ERROR"
3 -> "OPERATION_CANCELLED_BY_USER_ERROR"
4 -> "PERMISSIONS_NOT_GRANTED_ERROR"
5 -> "HARDWARE_ERROR"
6 -> "INPUT_ERROR"
7 -> "QR_PARSER_ERROR"
8 -> "LOCATION_PERMISSION_NOT_AVAILABLE_ERROR"
11 -> "INITIALIZATION_ERROR"
12 -> "NETWORK_ERROR"
14 -> "INTERNAL_SERVER_ERROR"
15 -> "SSL_CONNECT_ERROR"
16 -> "ACTIVE_SESSION_ERROR"
17 -> "TRANSACTION_ID_EMPTY"
18 -> "SIGNATURE_FAILED_ERROR"
22 -> "FACE_DETECTION_ERROR"
23 -> "BLURRY_FACE_DETECTION_ERROR"
31 -> "INSTRUCTION_ERROR"
32 -> "QR_SCANNER_ERROR"
33 -> "GPS_ACCESS_DENIED"
else -> "REASON_UNKNOWN"
}
}
fun getFinarkeinEventDescription(eventCode: String?): String {
return when (eventCode) {
"OPEN" -> "User has opened Anubhav journey"
"ERROR" -> "Recoverable error occurred in the Anubhav flow"
"UNKNOWN" -> "Event is not handled by Anubhab SDK"
"EXIT" -> "User has exited without completing journey"
"FIP_SELECTED" -> "User selected a FIP in the Anubhav flow"
"AA_SELECTED" -> "When AA is auto-selected based on User/FIU preference"
"AA_OTP_SENT" -> "When AA has triggered the verification OTP to User"
"AA_OTP_FAILED" -> "When AA is unable to send OTP to User"
"AA_OTP_INVALID" -> "Enter OTP is invalid"
"AA_OTP_VERIFIED" -> "When OPT is verified successfully"
"AA_UNREACHABLE" -> "When AA is not reachable"
"FIP_RENDERED" -> "When FIP list is successfully displayed to User"
"ACCOUNT_DISCOVERED" -> "When User account(s) is discovered in the FIP"
"ACCOUNT_NOT_DISCOVERED" -> "When User account(s) is not discovered in the FIP"
"ACCOUNT_LINKED" -> "When User links account successfully"
"MOBILE_CHANGE" -> "When User changed mobile number for Account discovery"
"MOBILE_VERIFIED" -> "When User's new mobile number is verified using OTP"
"CONSENT_GRANTED" -> "When User grants consent successfully"
"CONSENT_REJECTED" ->
"When User rejects consent i.e. does not proceed with FIP selection"
"ALTERNATIVE_CHOSEN" -> "When User selects alternative mechanism instead of AA"
"DATA_REQUESTED" -> "When data is requested from AA"
"DATA_RECEIVED" -> "When data is received from AA"
"DATA_VALID" -> "When received data is valid as per set rules"
"DATA_INVALID" -> "When received data is invalid as per set rules"
"FIP_ERROR" -> "When FIP sends an error"
"AA_ERROR" -> "When AA sends an error"
else -> "Reason Unknown"
}
}
fun hasMultipleDots(originalText: String): Boolean {
var count = 0
for (i in originalText.indices) {
if (originalText[i] == '.') {
count++
}
}
return count > 1
}
fun cleanDecimalString(decimalString: String): String {
if (decimalString.contains('.')) {
var decimalValue = decimalString
decimalValue = stripTrailingCharacters(decimalValue, '0')
decimalValue = stripTrailingCharacters(decimalValue, '.')
return decimalValue
}
return decimalString
}
fun stripTrailingCharacters(str: String, char: Char): String {
val sb: StringBuilder = StringBuilder(str)
while (sb.length > 0 && sb[sb.length - 1] == char) {
sb.setLength(sb.length - 1)
}
return sb.toString()
}
fun isWholeNumber(number: Double): Boolean {
return number.toInt().toDouble() == number
}
fun getDigitsCountAfterDecimal(input: String): Int {
var count = 0
val decimalIndex = input.indexOf(".")
if (decimalIndex >= 0 && decimalIndex < input.length - 1) {
val decimalPart = input.substring(decimalIndex + 1)
count = decimalPart.length
}
return count
}
fun numberToWords(amount: String, isWholeNumber: Boolean): String {
if (isWholeNumber) {
return numberToWords(amount)
} else {
val splitValues = amount.split(".")
if (splitValues.size > 1) {
val result = splitValues[0]
var decimalValue = splitValues[1]
if (decimalValue.length == 1) {
decimalValue += "0"
}
return numberToWords(result)
.plus(" and ")
.plus(numberToWords(decimalValue, "paise", "paise").lowercase())
} else {
return numberToWords(splitValues[0])
}
}
}
fun numberToWords(
amount: String,
unitSingular: String = "rupee",
unitPlural: String = "rupees"
): String {
try {
val number = amount.toDouble().toInt().toString()
if (number == "0") return "Zero $unitPlural"
if (number.length <= 9) {
var numberInStringFormat = number.reversed()
var numberInWords = ""
while (numberInStringFormat.length < 9) {
numberInStringFormat = numberInStringFormat.plus("0")
}
numberInStringFormat = numberInStringFormat.reversed()
while (numberInStringFormat.isNotEmpty()) {
if (numberInStringFormat.length > 7) {
val leftMostTwoDigits = numberInStringFormat.take(2).toInt()
if (leftMostTwoDigits != 0) {
numberInWords =
numberInWords
.plus(twoDigitNumberToWords(leftMostTwoDigits))
.plus(" crore ")
}
} else if (numberInStringFormat.length > 5) {
val leftMostTwoDigits = numberInStringFormat.take(2).toInt()
if (leftMostTwoDigits != 0) {
numberInWords =
numberInWords
.plus(twoDigitNumberToWords(leftMostTwoDigits))
.plus(" lakh ")
}
} else if (numberInStringFormat.length > 3) {
val leftMostTwoDigits = numberInStringFormat.take(2).toInt()
if (leftMostTwoDigits != 0) {
numberInWords =
numberInWords
.plus(twoDigitNumberToWords(leftMostTwoDigits))
.plus(" thousand ")
}
} else if (numberInStringFormat.length > 2) {
val leftMostDigit = numberInStringFormat.take(1).toInt()
if (leftMostDigit != 0) {
numberInWords =
numberInWords
.plus(twoDigitNumberToWords(leftMostDigit))
.plus(" hundred ")
}
} else {
val lastDigits = numberInStringFormat.toInt()
if (lastDigits != 0) {
numberInWords = numberInWords.plus(twoDigitNumberToWords(lastDigits))
}
}
if (numberInStringFormat.length > 3) {
numberInStringFormat = numberInStringFormat.drop(2)
} else if (numberInStringFormat.length > 2) {
numberInStringFormat = numberInStringFormat.drop(1)
} else {
numberInStringFormat = ""
}
}
numberInWords = numberInWords.trim().replaceFirstChar { it.uppercase() }
if (numberInWords == "One") {
numberInWords = numberInWords.plus(" $unitSingular")
} else {
numberInWords = numberInWords.plus(" $unitPlural")
}
return numberInWords
} else {
return EMPTY
}
} catch (_: Exception) {}
return EMPTY
}
private fun twoDigitNumberToWords(num: Int): String {
when (num) {
0 -> return "zero"
1 -> return "one"
2 -> return "two"
3 -> return "three"
4 -> return "four"
5 -> return "five"
6 -> return "six"
7 -> return "seven"
8 -> return "eight"
9 -> return "nine"
10 -> return "ten"
11 -> return "eleven"
12 -> return "twelve"
13 -> return "thirteen"
14 -> return "fourteen"
15 -> return "fifteen"
16 -> return "sixteen"
17 -> return "seventeen"
18 -> return "eighteen"
19 -> return "nineteen"
20 -> return "twenty"
30 -> return "thirty"
40 -> return "forty"
50 -> return "fifty"
60 -> return "sixty"
70 -> return "seventy"
80 -> return "eighty"
90 -> return "ninety"
}
if (num in 21..99) {
val tens = twoDigitNumberToWords((num / 10) * 10)
val ones = twoDigitNumberToWords(num % 10)
return tens.plus(SPACE).plus(ones)
}
return ""
}
fun cacheDirUri(context: Context, fileName: String): String {
return "file://${context.externalCacheDir?.path}/$fileName"
}
fun getUpdatedBaseUrl(): String? =
PreferenceManager.getStringPreferenceApp(key = UPDATED_BASE_URL)
fun getUpdatedPulseBaseUrl(): String? =
PreferenceManager.getStringPreferenceApp(key = UPDATED_PULSE_BASE_URL)
fun getAlfredDialogDisabledStatus(): String? =
PreferenceManager.getStringPreferenceApp(key = ALFRED_DIALOG_SCREENSHOT)
fun saveBaseUrlsAndRestart(
updatedBaseUrl: String?,
updatedPulseBaseUrl: String?,
context: Context?
) {
val updateBaseUrl =
checkDiffAndSaveDataInSharedPreference(
sharedPrefKey = UPDATED_BASE_URL,
updatedValue = updatedBaseUrl
)
val updatePulseBaseUrl =
checkDiffAndSaveDataInSharedPreference(
sharedPrefKey = UPDATED_PULSE_BASE_URL,
updatedValue = updatedPulseBaseUrl
)
if (updateBaseUrl || updatePulseBaseUrl) {
triggerAppRestart(context = context)
}
}
fun checkDiffAndSaveDataInSharedPreference(
sharedPrefKey: String,
updatedValue: String?
): Boolean {
if (updatedValue.isNullOrEmpty()) {
return false
}
val currentValue = PreferenceManager.getStringPreferenceApp(key = sharedPrefKey)
if (updatedValue != currentValue) {
PreferenceManager.saveStringPreferenceAppOnMainThread(
key = sharedPrefKey,
value = updatedValue
)
return true
}
return false
}
fun triggerAppRestart(context: Context?) {
val packageManager: PackageManager? = context?.packageManager
val intent: Intent? = packageManager?.getLaunchIntentForPackage(context.packageName)
val componentName: ComponentName? = intent?.component
val mainIntent = Intent.makeRestartActivityTask(componentName)
context?.startActivity(mainIntent)
try {
Runtime.getRuntime().exit(0)
} catch (e: Exception) {}
}
/**
* This function formats the entered digits in a group of 5 For ex: any phone number will be
* formatted as: 12345 67890
*/
fun phoneFormat(value: String): String {
var tempValue = value
tempValue = tempValue.replace(SPACE, EMPTY)
var result = EMPTY
val partition = 5
val start = 0
val end = 10
for ((digitCount, i) in tempValue.indices.withIndex()) {
if (digitCount == partition && i > start && i < end) {
result = "$result "
}
result += tempValue[i].toString()
}
return result
}
/**
* This function formats the entered amount with commas For ex: 1000000 will be formatted as
* 10,00,000
*/
fun moneyFormat(value: String): String {
var tempValue = value.toDoubleWithSafe().toLong().toString()
var result = EMPTY
tempValue = tempValue.replace(COMMA, EMPTY)
if (tempValue.isEmpty()) return result
val lastDigit = tempValue[tempValue.length - 1]
val len = tempValue.length - 1
var nDigits = 0
for (i in len - 1 downTo 0) {
result = tempValue[i].toString() + result
nDigits++
if (nDigits % 2 == 0 && i > 0) {
result = ",$result"
}
}
return result + lastDigit
}
fun saveUpdatedBaseUrlAndRestart(updatedBaseUrl: String?, context: Context?) {
val updateBaseUrl =
checkDiffAndSaveDataInSharedPreference(
sharedPrefKey = UPDATED_BASE_URL,
updatedValue = updatedBaseUrl
)
if (updateBaseUrl) {
triggerAppRestart(context = context)
}
}
fun saveUpdatedVersionCodeAndRestart(updatedVersionCode: String?, context: Context?) {
val updatedVersionCode =
checkDiffAndSaveDataInSharedPreference(
sharedPrefKey = UPDATED_VERSION_CODE,
updatedValue = updatedVersionCode
)
if (updatedVersionCode) {
triggerAppRestart(context = context)
}
}
fun getDebugVersionCode(): String? =
PreferenceManager.getStringPreferenceApp(key = UPDATED_VERSION_CODE)
fun getVersionSDKInt() = Build.VERSION.SDK_INT
fun isUpiAppAvailable(context: Context?): Boolean {
if (context == null) {
return false
}
val upiIntent = Intent(Intent.ACTION_VIEW, Uri.parse(UPI_APP_INTENT_URL))
val pm = context.packageManager
pm?.let {
val upiActivities = it.queryIntentActivities(upiIntent, 0)
return (upiActivities.isNotEmpty())
}
return false
}
}