mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-04-14 19:56:32 +00:00
update minSdk to 26
This commit is contained in:
parent
2638001513
commit
6d062aa7b6
39 changed files with 136 additions and 345 deletions
|
|
@ -156,12 +156,8 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
|
|||
val resources = resources
|
||||
val configuration: Configuration = resources.configuration
|
||||
val languageHelper = LanguageHelper(sharedPrefs.getString("language", "en"))
|
||||
if (if (SDK_INT >= Build.VERSION_CODES.N) {
|
||||
if (
|
||||
configuration.locales.isEmpty || configuration.locales[0] != languageHelper.locale
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
configuration.locale != languageHelper.locale
|
||||
}
|
||||
) {
|
||||
configuration.setLocale(languageHelper.locale)
|
||||
resources.updateConfiguration(configuration, null)
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
package com.habitrpg.android.habitica.extensions
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.os.Build
|
||||
|
||||
fun withImmutableFlag(flags: Int): Int {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
flags + PendingIntent.FLAG_IMMUTABLE
|
||||
} else {
|
||||
flags
|
||||
}
|
||||
}
|
||||
|
||||
fun withMutableFlag(flags: Int): Int {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
flags + PendingIntent.FLAG_MUTABLE
|
||||
} else {
|
||||
flags
|
||||
}
|
||||
}
|
||||
|
|
@ -15,9 +15,7 @@ fun Resources.forceLocale(
|
|||
Locale.setDefault(locale)
|
||||
val configuration = Configuration()
|
||||
configuration.setLocale(locale)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
activity.createConfigurationContext(configuration)
|
||||
}
|
||||
activity.createConfigurationContext(configuration)
|
||||
updateConfiguration(configuration, displayMetrics)
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -13,12 +13,8 @@ fun Window.updateStatusBarColor(
|
|||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
return
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
statusBarColor = color
|
||||
@Suppress("DEPRECATION")
|
||||
decorView.systemUiVisibility =
|
||||
if (isLight) View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR else View.SYSTEM_UI_FLAG_VISIBLE
|
||||
} else {
|
||||
statusBarColor = context.getThemeColor(R.attr.colorPrimaryDark)
|
||||
}
|
||||
statusBarColor = color
|
||||
@Suppress("DEPRECATION")
|
||||
decorView.systemUiVisibility =
|
||||
if (isLight) View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR else View.SYSTEM_UI_FLAG_VISIBLE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import android.content.Intent
|
|||
import android.os.Build
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.extensions.withImmutableFlag
|
||||
import com.habitrpg.android.habitica.models.tasks.RemindersItem
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.android.habitica.modules.AuthenticationHandler
|
||||
|
|
@ -166,7 +165,7 @@ class TaskAlarmManager(
|
|||
context,
|
||||
intentId,
|
||||
intent,
|
||||
withImmutableFlag(PendingIntent.FLAG_NO_CREATE)
|
||||
PendingIntent.FLAG_NO_CREATE + PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
if (previousSender != null) {
|
||||
previousSender.cancel()
|
||||
|
|
@ -178,7 +177,7 @@ class TaskAlarmManager(
|
|||
context,
|
||||
intentId,
|
||||
intent,
|
||||
withImmutableFlag(PendingIntent.FLAG_CANCEL_CURRENT)
|
||||
PendingIntent.FLAG_CANCEL_CURRENT + PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
|
|
@ -209,7 +208,7 @@ class TaskAlarmManager(
|
|||
context,
|
||||
intentId,
|
||||
intent,
|
||||
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABE
|
||||
)
|
||||
val am = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
|
||||
sender.cancel()
|
||||
|
|
@ -250,7 +249,7 @@ class TaskAlarmManager(
|
|||
context,
|
||||
0,
|
||||
notificationIntent,
|
||||
withImmutableFlag(PendingIntent.FLAG_NO_CREATE)
|
||||
PendingIntent.FLAG_NO_CREATE + PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
if (previousSender != null) {
|
||||
previousSender.cancel()
|
||||
|
|
@ -262,7 +261,7 @@ class TaskAlarmManager(
|
|||
context,
|
||||
0,
|
||||
notificationIntent,
|
||||
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABE
|
||||
)
|
||||
|
||||
setAlarm(context, triggerTime, pendingIntent)
|
||||
|
|
@ -273,7 +272,7 @@ class TaskAlarmManager(
|
|||
val notificationIntent = Intent(context, NotificationPublisher::class.java)
|
||||
val alarmManager = context?.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
|
||||
val displayIntent =
|
||||
PendingIntent.getBroadcast(context, 0, notificationIntent, withImmutableFlag(0))
|
||||
PendingIntent.getBroadcast(context, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||
alarmManager?.cancel(displayIntent)
|
||||
}
|
||||
|
||||
|
|
@ -289,45 +288,41 @@ class TaskAlarmManager(
|
|||
}
|
||||
|
||||
val notificationType = AlarmManager.RTC_WAKEUP
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
try {
|
||||
var canScheduleExact = true
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
canScheduleExact = alarmManager.canScheduleExactAlarms()
|
||||
}
|
||||
if (canScheduleExact) {
|
||||
alarmManager.setExactAndAllowWhileIdle(notificationType, time, pendingIntent)
|
||||
HLogger.log(
|
||||
LogLevel.DEBUG,
|
||||
"TaskAlarmManager",
|
||||
"setAlarm: Scheduling for $time using setExact ${Date().time}"
|
||||
)
|
||||
} else {
|
||||
alarmManager.setAndAllowWhileIdle(notificationType, time, pendingIntent)
|
||||
HLogger.log(
|
||||
LogLevel.DEBUG,
|
||||
"TaskAlarmManager",
|
||||
"setAlarm: Scheduling for $time using setAndAllowWhileIdle"
|
||||
try {
|
||||
var canScheduleExact = true
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
canScheduleExact = alarmManager.canScheduleExactAlarms()
|
||||
}
|
||||
if (canScheduleExact) {
|
||||
alarmManager.setExactAndAllowWhileIdle(notificationType, time, pendingIntent)
|
||||
HLogger.log(
|
||||
LogLevel.DEBUG,
|
||||
"TaskAlarmManager",
|
||||
"setAlarm: Scheduling for $time using setExact ${Date().time}"
|
||||
)
|
||||
} else {
|
||||
alarmManager.setAndAllowWhileIdle(notificationType, time, pendingIntent)
|
||||
HLogger.log(
|
||||
LogLevel.DEBUG,
|
||||
"TaskAlarmManager",
|
||||
"setAlarm: Scheduling for $time using setAndAllowWhileIdle"
|
||||
)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
when (ex) {
|
||||
is IllegalStateException, is SecurityException -> {
|
||||
alarmManager.setWindow(
|
||||
notificationType,
|
||||
time,
|
||||
600000,
|
||||
pendingIntent
|
||||
)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
when (ex) {
|
||||
is IllegalStateException, is SecurityException -> {
|
||||
alarmManager.setWindow(
|
||||
notificationType,
|
||||
time,
|
||||
600000,
|
||||
pendingIntent
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
throw ex
|
||||
}
|
||||
else -> {
|
||||
throw ex
|
||||
}
|
||||
}
|
||||
} else {
|
||||
alarmManager.set(notificationType, time, pendingIntent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,12 +130,8 @@ class TaskDescriptionBuilder(private val context: Context) {
|
|||
}
|
||||
|
||||
private fun withOrdinal(day: Int): String {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val formatter = MessageFormat("{0,ordinal}", LanguageHelper.systemLocale)
|
||||
formatter.format(arrayOf(day))
|
||||
} else {
|
||||
day.toString()
|
||||
}
|
||||
val formatter = MessageFormat("{0,ordinal}", LanguageHelper.systemLocale)
|
||||
return formatter.format(arrayOf(day))
|
||||
}
|
||||
|
||||
private fun describeRepeatInterval(
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import androidx.core.app.Person
|
|||
import androidx.core.app.RemoteInput
|
||||
import androidx.core.os.bundleOf
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.withMutableFlag
|
||||
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver
|
||||
import com.habitrpg.common.habitica.helpers.EmojiParser
|
||||
import java.text.SimpleDateFormat
|
||||
|
|
@ -35,11 +34,7 @@ class GroupActivityNotification(context: Context, identifier: String?) :
|
|||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager
|
||||
val existingNotifications =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
notificationManager?.activeNotifications?.filter { it.id == getNotificationID(data) }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
notificationManager?.activeNotifications?.filter { it.id == getNotificationID(data) }
|
||||
val oldMessages =
|
||||
existingNotifications?.firstOrNull()?.notification?.extras?.getBundle("messages")
|
||||
?.get("messages") as? ArrayList<Map<String, String>> ?: arrayListOf()
|
||||
|
|
@ -89,7 +84,7 @@ class GroupActivityNotification(context: Context, identifier: String?) :
|
|||
context,
|
||||
groupID.hashCode(),
|
||||
intent,
|
||||
withMutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_MUTABLE
|
||||
)
|
||||
|
||||
val action: NotificationCompat.Action =
|
||||
|
|
|
|||
|
|
@ -4,12 +4,8 @@ import android.app.PendingIntent
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.withImmutableFlag
|
||||
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver
|
||||
|
||||
/**
|
||||
* Created by keithholliday on 7/1/16.
|
||||
*/
|
||||
class GuildInviteLocalNotification(context: Context, identifier: String?) :
|
||||
HabiticaLocalNotification(context, identifier) {
|
||||
override fun configureMainIntent(intent: Intent) {
|
||||
|
|
@ -34,7 +30,7 @@ class GuildInviteLocalNotification(context: Context, identifier: String?) :
|
|||
context,
|
||||
groupID.hashCode(),
|
||||
acceptInviteIntent,
|
||||
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
notificationBuilder.addAction(0, "Accept", pendingIntentAccept)
|
||||
|
||||
|
|
@ -47,7 +43,7 @@ class GuildInviteLocalNotification(context: Context, identifier: String?) :
|
|||
context,
|
||||
groupID.hashCode() + 1,
|
||||
rejectInviteIntent,
|
||||
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
notificationBuilder.addAction(0, "Reject", pendingIntentReject)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import androidx.core.app.NotificationCompat
|
|||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.withImmutableFlag
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import java.util.Date
|
||||
|
||||
|
|
@ -81,7 +80,7 @@ abstract class HabiticaLocalNotification(
|
|||
context,
|
||||
3000,
|
||||
intent,
|
||||
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABE
|
||||
)
|
||||
notificationBuilder.setContentIntent(pendingIntent)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,8 @@ import android.app.PendingIntent
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.withImmutableFlag
|
||||
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver
|
||||
|
||||
/**
|
||||
* Created by keithholliday on 6/28/16.
|
||||
*/
|
||||
class PartyInviteLocalNotification(context: Context, identifier: String?) :
|
||||
HabiticaLocalNotification(context, identifier) {
|
||||
override fun setNotificationActions(
|
||||
|
|
@ -29,7 +25,7 @@ class PartyInviteLocalNotification(context: Context, identifier: String?) :
|
|||
context,
|
||||
groupID.hashCode(),
|
||||
acceptInviteIntent,
|
||||
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
notificationBuilder.addAction(0, context.getString(R.string.accept), pendingIntentAccept)
|
||||
|
||||
|
|
@ -42,7 +38,7 @@ class PartyInviteLocalNotification(context: Context, identifier: String?) :
|
|||
context,
|
||||
groupID.hashCode() + 1,
|
||||
rejectInviteIntent,
|
||||
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
notificationBuilder.addAction(0, context.getString(R.string.reject), pendingIntentReject)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,5 @@ package com.habitrpg.android.habitica.helpers.notifications
|
|||
|
||||
import android.content.Context
|
||||
|
||||
/**
|
||||
* Created by keithholliday on 7/1/16.
|
||||
*/
|
||||
class QuestBegunLocalNotification(context: Context, identifier: String?) :
|
||||
HabiticaLocalNotification(context, identifier)
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@ import android.os.Build
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver
|
||||
|
||||
/**
|
||||
* Created by keithholliday on 7/1/16.
|
||||
*/
|
||||
class QuestInviteLocalNotification(context: Context, identifier: String?) :
|
||||
HabiticaLocalNotification(context, identifier) {
|
||||
override fun getNotificationID(data: MutableMap<String, String>): Int {
|
||||
|
|
@ -27,11 +24,7 @@ class QuestInviteLocalNotification(context: Context, identifier: String?) :
|
|||
acceptInviteIntent.action = res.getString(R.string.accept_quest_invite)
|
||||
acceptInviteIntent.putExtra("NOTIFICATION_ID", notificationId)
|
||||
val flags =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABLE
|
||||
} else {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
}
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABLE
|
||||
val pendingIntentAccept =
|
||||
PendingIntent.getBroadcast(
|
||||
context,
|
||||
|
|
|
|||
|
|
@ -2,8 +2,5 @@ package com.habitrpg.android.habitica.helpers.notifications
|
|||
|
||||
import android.content.Context
|
||||
|
||||
/**
|
||||
* Created by keithholliday on 7/1/16.
|
||||
*/
|
||||
class ReceivedGemsGiftLocalNotification(context: Context, identifier: String?) :
|
||||
HabiticaLocalNotification(context, identifier)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import androidx.core.app.NotificationCompat
|
|||
import androidx.core.app.RemoteInput
|
||||
import androidx.core.os.bundleOf
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.withMutableFlag
|
||||
import com.habitrpg.android.habitica.receivers.LocalNotificationActionReceiver
|
||||
import com.habitrpg.common.habitica.helpers.EmojiParser
|
||||
|
||||
|
|
@ -20,11 +19,7 @@ class ReceivedPrivateMessageLocalNotification(context: Context, identifier: Stri
|
|||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager
|
||||
val existingNotifications =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
notificationManager?.activeNotifications?.filter { it.id == getNotificationID(data) }
|
||||
} else {
|
||||
null
|
||||
}
|
||||
notificationManager?.activeNotifications?.filter { it.id == getNotificationID(data) }
|
||||
val messageText = EmojiParser.parseEmojis(data["message"]?.trim { it <= ' ' })
|
||||
val oldMessages =
|
||||
existingNotifications?.firstOrNull()?.notification?.extras?.getStringArrayList("messages")
|
||||
|
|
@ -100,7 +95,7 @@ class ReceivedPrivateMessageLocalNotification(context: Context, identifier: Stri
|
|||
context,
|
||||
senderID.hashCode(),
|
||||
intent,
|
||||
withMutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_MUTABLE
|
||||
)
|
||||
|
||||
val action: NotificationCompat.Action =
|
||||
|
|
|
|||
|
|
@ -2,8 +2,5 @@ package com.habitrpg.android.habitica.helpers.notifications
|
|||
|
||||
import android.content.Context
|
||||
|
||||
/**
|
||||
* Created by keithholliday on 7/1/16.
|
||||
*/
|
||||
class ReceivedSubscriptionGiftLocalNotification(context: Context, identifier: String?) :
|
||||
HabiticaLocalNotification(context, identifier)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import androidx.core.content.edit
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.extensions.withImmutableFlag
|
||||
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.common.habitica.helpers.launchCatching
|
||||
|
|
@ -142,7 +141,7 @@ class NotificationPublisher : BroadcastReceiver() {
|
|||
thisContext,
|
||||
0,
|
||||
notificationIntent,
|
||||
withImmutableFlag(0)
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
builder.setContentIntent(intent)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import androidx.core.app.NotificationManagerCompat
|
|||
import androidx.core.content.ContextCompat
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.extensions.withImmutableFlag
|
||||
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
|
|
@ -73,7 +72,7 @@ class TaskReceiver : BroadcastReceiver() {
|
|||
context,
|
||||
System.currentTimeMillis().toInt(),
|
||||
intent,
|
||||
withImmutableFlag(0)
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
||||
|
||||
|
|
@ -91,9 +90,7 @@ class TaskReceiver : BroadcastReceiver() {
|
|||
.setAutoCancel(true)
|
||||
.setContentIntent(pendingIntent)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
notificationBuilder = notificationBuilder.setCategory(Notification.CATEGORY_REMINDER)
|
||||
}
|
||||
notificationBuilder = notificationBuilder.setCategory(Notification.CATEGORY_REMINDER)
|
||||
|
||||
if (task.type == TaskType.DAILY || task.type == TaskType.TODO) {
|
||||
val completeIntent =
|
||||
|
|
@ -107,7 +104,7 @@ class TaskReceiver : BroadcastReceiver() {
|
|||
context,
|
||||
task.id.hashCode(),
|
||||
completeIntent,
|
||||
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABE
|
||||
)
|
||||
notificationBuilder.addAction(
|
||||
0,
|
||||
|
|
|
|||
|
|
@ -87,9 +87,7 @@ class AdventureGuideActivity : BaseActivity() {
|
|||
val completed = achievements.count { it.earned }
|
||||
binding.progressBar.max = achievements.size
|
||||
binding.progressBar.progress = completed
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||
binding.progressBar.progressBackgroundTintMode = PorterDuff.Mode.SRC_OVER
|
||||
}
|
||||
binding.progressBar.progressBackgroundTintMode = PorterDuff.Mode.SRC_OVER
|
||||
|
||||
if (completed > 0) {
|
||||
binding.progressTextview.text =
|
||||
|
|
|
|||
|
|
@ -186,10 +186,8 @@ class LoginActivity : BaseActivity() {
|
|||
private fun configureForRegistering() {
|
||||
binding.submitButton.text = getString(R.string.register_btn)
|
||||
binding.username.setHint(R.string.username)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
binding.username.setAutofillHints("newUsername")
|
||||
binding.password.setAutofillHints("newPassword")
|
||||
}
|
||||
binding.username.setAutofillHints("newUsername")
|
||||
binding.password.setAutofillHints("newPassword")
|
||||
binding.password.imeOptions = EditorInfo.IME_ACTION_NEXT
|
||||
binding.googleLoginButton.setText(R.string.register_btn_google)
|
||||
|
||||
|
|
@ -199,10 +197,8 @@ class LoginActivity : BaseActivity() {
|
|||
private fun configureForLogin() {
|
||||
binding.submitButton.text = getString(R.string.login_btn)
|
||||
binding.username.setHint(R.string.email_username)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
binding.username.setAutofillHints("username")
|
||||
binding.password.setAutofillHints("password")
|
||||
}
|
||||
binding.username.setAutofillHints("username")
|
||||
binding.password.setAutofillHints("password")
|
||||
binding.password.imeOptions = EditorInfo.IME_ACTION_DONE
|
||||
binding.googleLoginButton.setText(R.string.login_btn_google)
|
||||
this.resetLayout()
|
||||
|
|
@ -409,9 +405,7 @@ class LoginActivity : BaseActivity() {
|
|||
|
||||
private fun onForgotPasswordClicked() {
|
||||
val input = EditText(this)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
input.setAutofillHints(EditText.AUTOFILL_HINT_EMAIL_ADDRESS)
|
||||
}
|
||||
input.setAutofillHints(EditText.AUTOFILL_HINT_EMAIL_ADDRESS)
|
||||
input.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|
||||
input.hint = getString(R.string.forgot_password_hint_example)
|
||||
input.textSize = 16f
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ import java.util.Date
|
|||
import javax.inject.Inject
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.toDuration
|
||||
import androidx.core.view.isVisible
|
||||
|
||||
var mainActivityCreatedAt: Date? = null
|
||||
|
||||
|
|
@ -458,22 +459,20 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
|
|||
}
|
||||
|
||||
private fun setupNotifications() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val channelId = "default"
|
||||
val channel =
|
||||
NotificationChannel(
|
||||
channelId,
|
||||
"Habitica Notifications",
|
||||
NotificationManager.IMPORTANCE_DEFAULT
|
||||
)
|
||||
val manager = getSystemService(NotificationManager::class.java)
|
||||
manager?.createNotificationChannel(channel)
|
||||
}
|
||||
val channelId = "default"
|
||||
val channel =
|
||||
NotificationChannel(
|
||||
channelId,
|
||||
"Habitica Notifications",
|
||||
NotificationManager.IMPORTANCE_DEFAULT
|
||||
)
|
||||
val manager = getSystemService(NotificationManager::class.java)
|
||||
manager?.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
private fun setupBottomnavigationLayoutListener() {
|
||||
binding.content.bottomNavigation.viewTreeObserver.addOnGlobalLayoutListener {
|
||||
if (binding.content.bottomNavigation.visibility == View.VISIBLE) {
|
||||
if (binding.content.bottomNavigation.isVisible) {
|
||||
snackbarContainer.setPadding(
|
||||
0,
|
||||
0,
|
||||
|
|
|
|||
|
|
@ -118,32 +118,17 @@ class ReportMessageActivity : BaseActivity() {
|
|||
private fun setStatusBarDim(dim: Boolean) {
|
||||
if (dim) {
|
||||
binding.appbar.elevation = 0f
|
||||
window.statusBarColor = getThemeColor(R.attr.colorPrimaryDark)
|
||||
binding.closeButton.visibility = View.GONE
|
||||
binding.toolbarTitle.setTypeface(null, Typeface.BOLD)
|
||||
} else {
|
||||
binding.appbar.elevation = 8f
|
||||
window.statusBarColor = ContextCompat.getColor(this, R.color.offset_background)
|
||||
binding.closeButton.visibility = View.VISIBLE
|
||||
binding.toolbarTitle.setTypeface(null, Typeface.NORMAL)
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= VERSION_CODES.M) {
|
||||
setSystemBarTheme(dim)
|
||||
}
|
||||
}
|
||||
|
||||
override fun finish() {
|
||||
dismissKeyboard()
|
||||
super.finish()
|
||||
}
|
||||
|
||||
@RequiresApi(api = VERSION_CODES.M)
|
||||
fun setSystemBarTheme(isDark: Boolean) {
|
||||
// Fetch the current flags.
|
||||
val lFlags = window.decorView.systemUiVisibility
|
||||
// Update the SystemUiVisibility dependening on whether we want a Light or Dark theme.
|
||||
window.decorView.systemUiVisibility =
|
||||
if (isDark) lFlags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv() else lFlags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,13 +135,9 @@ class TaskFormActivity : BaseActivity() {
|
|||
alert.setMessage(R.string.push_notification_system_settings_description)
|
||||
alert.addButton(R.string.settings, isPrimary = true, isDestructive = false) { _, _ ->
|
||||
val notifSettingIntent: Intent =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.putExtra(Settings.EXTRA_APP_PACKAGE, applicationContext?.packageName)
|
||||
} else {
|
||||
return@addButton
|
||||
}
|
||||
Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.putExtra(Settings.EXTRA_APP_PACKAGE, applicationContext?.packageName)
|
||||
startActivity(notifSettingIntent)
|
||||
}
|
||||
alert.addButton(R.string.cancel, false) { _, _ ->
|
||||
|
|
|
|||
|
|
@ -80,9 +80,7 @@ class HabiticaAccountDialog(private var thisContext: Context) :
|
|||
|
||||
private fun showForgotPasswordDialog() {
|
||||
val input = EditText(requireContext())
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
input.setAutofillHints(EditText.AUTOFILL_HINT_EMAIL_ADDRESS)
|
||||
}
|
||||
input.setAutofillHints(EditText.AUTOFILL_HINT_EMAIL_ADDRESS)
|
||||
input.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|
||||
input.hint = getString(R.string.forgot_password_hint_example)
|
||||
input.textSize = 16f
|
||||
|
|
|
|||
|
|
@ -271,17 +271,15 @@ class PreferencesFragment :
|
|||
val alert = context?.let { HabiticaAlertDialog(it) }
|
||||
alert?.setTitle(R.string.push_notification_system_settings_title)
|
||||
alert?.setMessage(R.string.push_notification_system_settings_description)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
alert?.addButton(R.string.open_settings, true, false) { _, _ ->
|
||||
val notifSettingIntent: Intent =
|
||||
Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.putExtra(
|
||||
Settings.EXTRA_APP_PACKAGE,
|
||||
context?.applicationContext?.packageName
|
||||
)
|
||||
startActivity(notifSettingIntent)
|
||||
}
|
||||
alert?.addButton(R.string.open_settings, true, false) { _, _ ->
|
||||
val notifSettingIntent: Intent =
|
||||
Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.putExtra(
|
||||
Settings.EXTRA_APP_PACKAGE,
|
||||
context?.applicationContext?.packageName
|
||||
)
|
||||
startActivity(notifSettingIntent)
|
||||
}
|
||||
alert?.addButton(R.string.cancel, false) { _, _ ->
|
||||
alert.dismiss()
|
||||
|
|
|
|||
|
|
@ -22,15 +22,8 @@ class TimePreferenceDialogFragment : PreferenceDialogFragmentCompat() {
|
|||
get() {
|
||||
val lastHour: Int
|
||||
val lastMinute: Int
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
lastHour = picker.hour
|
||||
lastMinute = picker.minute
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
lastHour = picker.currentHour
|
||||
@Suppress("DEPRECATION")
|
||||
lastMinute = picker.currentMinute
|
||||
}
|
||||
lastHour = picker.hour
|
||||
lastMinute = picker.minute
|
||||
return lastHour.toString() + ":" + String.format(Locale.UK, "%02d", lastMinute)
|
||||
}
|
||||
|
||||
|
|
@ -46,15 +39,8 @@ class TimePreferenceDialogFragment : PreferenceDialogFragmentCompat() {
|
|||
val preference = timePreference
|
||||
val lastHour = preference.lastHour
|
||||
val lastMinute = preference.lastMinute
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
picker.hour = lastHour
|
||||
picker.minute = lastMinute
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
picker.currentHour = lastHour
|
||||
@Suppress("DEPRECATION")
|
||||
picker.currentMinute = lastMinute
|
||||
}
|
||||
picker.hour = lastHour
|
||||
picker.minute = lastMinute
|
||||
}
|
||||
|
||||
override fun onDialogClosed(positiveResult: Boolean) {
|
||||
|
|
|
|||
|
|
@ -50,9 +50,6 @@ object ToolbarColorHelper {
|
|||
backgroundColor ?: activity.getThemeColor(R.attr.headerBackgroundColor)
|
||||
)
|
||||
val toolbarIconsColor = iconColor ?: activity.getThemeColor(R.attr.headerTextColor)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
activity.window.statusBarColor = activity.getThemeColor(R.attr.colorPrimaryDark)
|
||||
}
|
||||
val colorFilter = PorterDuffColorFilter(toolbarIconsColor, PorterDuff.Mode.MULTIPLY)
|
||||
for (i in 0 until toolbar.childCount) {
|
||||
when (val v = toolbar.getChildAt(i)) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import com.habitrpg.common.habitica.extensions.DataBindingUtils
|
|||
import com.habitrpg.common.habitica.extensions.inflate
|
||||
import com.habitrpg.shared.habitica.models.responses.FeedResponse
|
||||
import dagger.hilt.android.internal.managers.ViewComponentManager
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
|
||||
class PetViewHolder(
|
||||
parent: ViewGroup,
|
||||
|
|
@ -92,9 +93,7 @@ class PetViewHolder(
|
|||
binding.imageView.alpha = 0.2f
|
||||
}
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||
binding.trainedProgressBar.progressBackgroundTintMode = PorterDuff.Mode.SRC_OVER
|
||||
}
|
||||
binding.trainedProgressBar.progressBackgroundTintMode = PorterDuff.Mode.SRC_OVER
|
||||
binding.imageView.background = null
|
||||
binding.activeIndicator.visibility =
|
||||
if (currentPet.equals(animal?.key)) View.VISIBLE else View.GONE
|
||||
|
|
@ -103,10 +102,7 @@ class PetViewHolder(
|
|||
val resources = itemView.context.resources ?: return@loadImage
|
||||
val drawable =
|
||||
if (trained == 0 && canRaiseToMount) {
|
||||
BitmapDrawable(
|
||||
resources,
|
||||
it.toBitmap().extractAlpha()
|
||||
)
|
||||
it.toBitmap().extractAlpha().toDrawable(resources)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ class AuthenticationViewModel @Inject constructor(
|
|||
sharedPrefs.edit {
|
||||
putString("UserID", user)
|
||||
val encryptedKey =
|
||||
if (keyHelper != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (keyHelper != null) {
|
||||
try {
|
||||
keyHelper.encrypt(api)
|
||||
} catch (e: Exception) {
|
||||
|
|
|
|||
|
|
@ -179,10 +179,8 @@ class SubscriptionOptionView(context: Context, attrs: AttributeSet) : FrameLayou
|
|||
binding.priceLabel.setTextColor(textColor)
|
||||
}
|
||||
binding.descriptionTextView.setTextColor(textColor)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
TextViewCompat.setCompoundDrawableTintList(binding.gemCapTextView, ContextCompat.getColorStateList(context, R.color.yellow_100))
|
||||
TextViewCompat.setCompoundDrawableTintList(binding.hourglassTextView, ContextCompat.getColorStateList(context, R.color.yellow_100))
|
||||
}
|
||||
TextViewCompat.setCompoundDrawableTintList(binding.gemCapTextView, ContextCompat.getColorStateList(context, R.color.yellow_100))
|
||||
TextViewCompat.setCompoundDrawableTintList(binding.hourglassTextView, ContextCompat.getColorStateList(context, R.color.yellow_100))
|
||||
} else {
|
||||
binding.selectedIndicator.animate()
|
||||
.alpha(0f)
|
||||
|
|
@ -215,10 +213,8 @@ class SubscriptionOptionView(context: Context, attrs: AttributeSet) : FrameLayou
|
|||
R.color.brand_600
|
||||
)
|
||||
)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
TextViewCompat.setCompoundDrawableTintList(binding.gemCapTextView, ContextCompat.getColorStateList(context, R.color.brand_400))
|
||||
TextViewCompat.setCompoundDrawableTintList(binding.hourglassTextView, ContextCompat.getColorStateList(context, R.color.brand_400))
|
||||
}
|
||||
TextViewCompat.setCompoundDrawableTintList(binding.gemCapTextView, ContextCompat.getColorStateList(context, R.color.brand_400))
|
||||
TextViewCompat.setCompoundDrawableTintList(binding.hourglassTextView, ContextCompat.getColorStateList(context, R.color.brand_400))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -420,23 +420,13 @@ constructor(
|
|||
weekdays =
|
||||
if (daysOfMonth?.isNotEmpty() == true) {
|
||||
val date = startDateCalendar.get(Calendar.DATE)
|
||||
val formattedDate =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val formatter = MessageFormat("{0,ordinal}", LanguageHelper.systemLocale)
|
||||
formatter.format(arrayOf(date))
|
||||
} else {
|
||||
date.toString()
|
||||
}
|
||||
val formatter = MessageFormat("{0,ordinal}", LanguageHelper.systemLocale)
|
||||
val formattedDate = formatter.format(arrayOf(date))
|
||||
" on the $formattedDate"
|
||||
} else {
|
||||
val week = startDateCalendar.get(Calendar.WEEK_OF_MONTH)
|
||||
val formattedWeek =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val formatter = MessageFormat("{0,ordinal}", LanguageHelper.systemLocale)
|
||||
formatter.format(arrayOf(week))
|
||||
} else {
|
||||
week.toString()
|
||||
}
|
||||
val formatter = MessageFormat("{0,ordinal}", LanguageHelper.systemLocale)
|
||||
val formattedWeek = formatter.format(arrayOf(week))
|
||||
val dayLongName =
|
||||
startDateCalendar.getDisplayName(
|
||||
Calendar.DAY_OF_WEEK,
|
||||
|
|
|
|||
|
|
@ -23,11 +23,7 @@ class DateDeserializer : JsonDeserializer<Date>, JsonSerializer<Date> {
|
|||
addFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
|
||||
addFormat("E MMM dd yyyy HH:mm:ss zzzz")
|
||||
addFormat("yyyy-MM-dd'T'HH:mm:sszzz")
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
addFormat("yyyy-MM-dd'T'HH:mmX")
|
||||
} else {
|
||||
addFormat("yyyy-MM-dd'T'HH:mm")
|
||||
}
|
||||
addFormat("yyyy-MM-dd'T'HH:mmX")
|
||||
addFormat("yyyy-MM-dd")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import android.content.Intent
|
|||
import android.view.View
|
||||
import android.widget.RemoteViews
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.withImmutableFlag
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
|
|
@ -203,7 +202,7 @@ class AvatarStatsWidgetProvider : BaseWidgetProvider() {
|
|||
context,
|
||||
0,
|
||||
openAppIntent,
|
||||
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABE
|
||||
)
|
||||
remoteViews.setOnClickPendingIntent(android.R.id.background, openApp)
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import android.widget.RemoteViews
|
|||
import androidx.core.content.ContextCompat
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.extensions.withImmutableFlag
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.common.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.common.habitica.helpers.MarkdownParser
|
||||
|
|
@ -144,7 +143,7 @@ class HabitButtonWidgetService : Service() {
|
|||
context,
|
||||
widgetId + direction.hashCode(),
|
||||
taskIntent,
|
||||
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABE
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ import android.net.Uri
|
|||
import android.widget.RemoteViews
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.extensions.withImmutableFlag
|
||||
import com.habitrpg.android.habitica.extensions.withMutableFlag
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.common.habitica.helpers.ExceptionHandler
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
|
@ -95,7 +93,7 @@ abstract class TaskListWidgetProvider : BaseWidgetProvider() {
|
|||
context,
|
||||
0,
|
||||
openAppIntent,
|
||||
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABE
|
||||
)
|
||||
rv.setOnClickPendingIntent(R.id.widget_title, openApp)
|
||||
|
||||
|
|
@ -108,7 +106,7 @@ abstract class TaskListWidgetProvider : BaseWidgetProvider() {
|
|||
context,
|
||||
0,
|
||||
taskIntent,
|
||||
withMutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_MUTABLE
|
||||
)
|
||||
rv.setPendingIntentTemplate(R.id.list_view, toastPendingIntent)
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class HostConfig {
|
|||
}
|
||||
} else {
|
||||
val key = sharedPreferences.getString("APIToken", null)
|
||||
if (key?.isNotBlank() == true && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (key?.isNotBlank() == true) {
|
||||
val encryptedKey = keyHelper?.encrypt(key)
|
||||
sharedPreferences.edit {
|
||||
putString(userID, encryptedKey)
|
||||
|
|
|
|||
|
|
@ -9,12 +9,7 @@ import android.util.Patterns
|
|||
import java.util.Locale
|
||||
|
||||
fun String.fromHtml(): CharSequence {
|
||||
return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
||||
Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
Html.fromHtml(this)
|
||||
}
|
||||
return Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)
|
||||
}
|
||||
|
||||
fun String.addZeroWidthSpace(): CharSequence {
|
||||
|
|
|
|||
|
|
@ -34,9 +34,5 @@ object HealthFormatter {
|
|||
}
|
||||
|
||||
private fun getDefaultLocale() =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
Locale.getDefault(Locale.Category.FORMAT)
|
||||
} else {
|
||||
Locale.getDefault()
|
||||
}
|
||||
Locale.getDefault(Locale.Category.FORMAT)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,55 +49,26 @@ constructor(ctx: Context, var sharedPreferences: SharedPreferences, var keyStore
|
|||
}
|
||||
|
||||
init {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
this.generateEncryptKey(ctx)
|
||||
}
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
try {
|
||||
this.generateAESKey()
|
||||
} catch (e: Exception) {
|
||||
HLogger.logException("KeyHelper", "Error initializing", e)
|
||||
}
|
||||
}
|
||||
this.generateEncryptKey(ctx)
|
||||
}
|
||||
|
||||
@Throws(NoSuchProviderException::class, NoSuchAlgorithmException::class, InvalidAlgorithmParameterException::class, KeyStoreException::class, CertificateException::class, IOException::class)
|
||||
private fun generateEncryptKey(ctx: Context) {
|
||||
keyStore?.load(null)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (keyStore?.containsAlias(KEY_ALIAS) == false) {
|
||||
val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE)
|
||||
keyGenerator.init(
|
||||
KeyGenParameterSpec.Builder(
|
||||
KEY_ALIAS,
|
||||
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
|
||||
)
|
||||
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
|
||||
.setRandomizedEncryptionRequired(false)
|
||||
.build()
|
||||
if (keyStore?.containsAlias(KEY_ALIAS) == false) {
|
||||
val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE)
|
||||
keyGenerator.init(
|
||||
KeyGenParameterSpec.Builder(
|
||||
KEY_ALIAS,
|
||||
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
|
||||
)
|
||||
keyGenerator.generateKey()
|
||||
}
|
||||
} else {
|
||||
if (keyStore?.containsAlias(KEY_ALIAS) == false) {
|
||||
// Generate a key pair for encryption
|
||||
val start = Calendar.getInstance()
|
||||
val end = Calendar.getInstance()
|
||||
end.add(Calendar.YEAR, 30)
|
||||
val spec =
|
||||
KeyPairGeneratorSpec.Builder(ctx)
|
||||
.setAlias(KEY_ALIAS)
|
||||
.setSubject(X500Principal("CN=$KEY_ALIAS"))
|
||||
.setSerialNumber(BigInteger.TEN)
|
||||
.setStartDate(start.time)
|
||||
.setEndDate(end.time)
|
||||
.build()
|
||||
val kpg = KeyPairGenerator.getInstance("RSA", ANDROID_KEY_STORE)
|
||||
kpg.initialize(spec)
|
||||
kpg.generateKeyPair()
|
||||
}
|
||||
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
|
||||
.setRandomizedEncryptionRequired(false)
|
||||
.build()
|
||||
)
|
||||
keyGenerator.generateKey()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -158,20 +129,11 @@ constructor(ctx: Context, var sharedPreferences: SharedPreferences, var keyStore
|
|||
val c: Cipher
|
||||
val publicIV = getRandomIV()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
c = Cipher.getInstance(AES_MODE_M)
|
||||
try {
|
||||
c.init(Cipher.ENCRYPT_MODE, aesKeyFromKS, GCMParameterSpec(128, Base64.decode(publicIV, Base64.DEFAULT)))
|
||||
} catch (e: Exception) {
|
||||
HLogger.logException("KeyHelper", "Error encrypting", e)
|
||||
}
|
||||
} else {
|
||||
c = Cipher.getInstance(AES_MODE_M)
|
||||
try {
|
||||
c.init(Cipher.ENCRYPT_MODE, getSecretKey(), GCMParameterSpec(128, Base64.decode(publicIV, Base64.DEFAULT)))
|
||||
} catch (e: Exception) {
|
||||
HLogger.logException("KeyHelper", "Error encrypting", e)
|
||||
}
|
||||
c = Cipher.getInstance(AES_MODE_M)
|
||||
try {
|
||||
c.init(Cipher.ENCRYPT_MODE, aesKeyFromKS, GCMParameterSpec(128, Base64.decode(publicIV, Base64.DEFAULT)))
|
||||
} catch (e: Exception) {
|
||||
HLogger.logException("KeyHelper", "Error encrypting", e)
|
||||
}
|
||||
val encodedBytes = c.doFinal(input.toByteArray(charset("UTF-8")))
|
||||
return Base64.encodeToString(encodedBytes, Base64.DEFAULT)
|
||||
|
|
@ -182,20 +144,11 @@ constructor(ctx: Context, var sharedPreferences: SharedPreferences, var keyStore
|
|||
val c: Cipher
|
||||
val publicIV = getRandomIV()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
c = Cipher.getInstance(AES_MODE_M)
|
||||
try {
|
||||
c.init(Cipher.DECRYPT_MODE, aesKeyFromKS, GCMParameterSpec(128, Base64.decode(publicIV, Base64.DEFAULT)))
|
||||
} catch (e: Exception) {
|
||||
HLogger.logException("KeyHelper", "Error decrypting", e)
|
||||
}
|
||||
} else {
|
||||
c = Cipher.getInstance(AES_MODE_M)
|
||||
try {
|
||||
c.init(Cipher.DECRYPT_MODE, getSecretKey(), GCMParameterSpec(128, Base64.decode(publicIV, Base64.DEFAULT)))
|
||||
} catch (e: Exception) {
|
||||
HLogger.logException("KeyHelper", "Error decrypting", e)
|
||||
}
|
||||
c = Cipher.getInstance(AES_MODE_M)
|
||||
try {
|
||||
c.init(Cipher.DECRYPT_MODE, aesKeyFromKS, GCMParameterSpec(128, Base64.decode(publicIV, Base64.DEFAULT)))
|
||||
} catch (e: Exception) {
|
||||
HLogger.logException("KeyHelper", "Error decrypting", e)
|
||||
}
|
||||
|
||||
return try {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[versions]
|
||||
minSdk = "21"
|
||||
minSdk = "26"
|
||||
targetSdk = "35"
|
||||
wearOsTargetSdk = "34"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue