diff --git a/README.md b/README.md
index 6dd6c1b..821853c 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ Duress password trigger.
height="80">](https://play.google.com/store/apps/details?id=me.lucky.duress)
@@ -30,8 +30,16 @@ When found, it can send a broadcast message or wipe the device.
* ACCESSIBILITY - listen for a duress password on the lockscreen
* DEVICE_ADMIN - wipe the device (optional)
+## Localization
+
+[](https://crwd.in/me-lucky-duress)
+
## Related
+* [pam_duress](https://github.com/rafket/pam_duress)
* [pam_panic](https://github.com/pampanic/pam_panic)
* [pam-party](https://github.com/x13a/pam-party)
* [lockup](https://github.com/nekohasekai/lockup)
diff --git a/app/build.gradle b/app/build.gradle
index 184f287..d401221 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,8 +10,8 @@ android {
applicationId "me.lucky.duress"
minSdk 23
targetSdk 32
- versionCode 9
- versionName "1.0.8"
+ versionCode 10
+ versionName "1.0.9"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -40,7 +40,7 @@ android {
dependencies {
implementation 'androidx.core:core-ktx:1.8.0'
- implementation 'androidx.appcompat:appcompat:1.4.2'
+ implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
@@ -48,6 +48,10 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'androidx.security:security-crypto:1.0.0'
- implementation 'androidx.preference:preference-ktx:1.2.0'
+ // https://issuetracker.google.com/issues/238425626
+ implementation('androidx.preference:preference-ktx:1.2.0') {
+ exclude group: 'androidx.lifecycle', module:'lifecycle-viewmodel'
+ exclude group: 'androidx.lifecycle', module:'lifecycle-viewmodel-ktx'
+ }
implementation 'androidx.biometric:biometric:1.1.0'
}
\ No newline at end of file
diff --git a/app/src/main/java/me/lucky/duress/AccessibilityService.kt b/app/src/main/java/me/lucky/duress/AccessibilityService.kt
index 7283768..a76e7a1 100644
--- a/app/src/main/java/me/lucky/duress/AccessibilityService.kt
+++ b/app/src/main/java/me/lucky/duress/AccessibilityService.kt
@@ -16,7 +16,6 @@ class AccessibilityService : AccessibilityService() {
companion object {
private const val MIN_KEYGUARD_LEN = 4
private const val MIN_LEN = MIN_KEYGUARD_LEN + 2
- private const val KEY = "code"
private const val BUTTON_DELETE_DESC = "delete"
private const val BUTTON_OK_DESC = "ok"
private const val BUTTON_ENTER_DESC = "enter"
@@ -226,8 +225,8 @@ class AccessibilityService : AccessibilityService() {
)
}
addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
- val secret = prefs.secret
- if (secret.isNotEmpty()) putExtra(KEY, secret)
+ val extraKey = prefs.extraKey
+ if (extraKey.isNotEmpty()) putExtra(extraKey, prefs.extraValue)
})
}
diff --git a/app/src/main/java/me/lucky/duress/MainActivity.kt b/app/src/main/java/me/lucky/duress/MainActivity.kt
index bba9bf2..7ddb126 100644
--- a/app/src/main/java/me/lucky/duress/MainActivity.kt
+++ b/app/src/main/java/me/lucky/duress/MainActivity.kt
@@ -57,7 +57,6 @@ class MainActivity : AppCompatActivity() {
prefsdb = Preferences(this, encrypted = false)
prefs.copyTo(prefsdb)
accessibilityManager = getSystemService(AccessibilityManager::class.java)
- NotificationManager(this).createNotificationChannels()
}
private fun init2() {
@@ -66,7 +65,8 @@ class MainActivity : AppCompatActivity() {
tabs.selectTab(tabs.getTabAt(prefs.mode))
action.editText?.setText(prefs.action)
receiver.editText?.setText(prefs.receiver)
- secret.editText?.setText(prefs.secret)
+ extraKey.editText?.setText(prefs.extraKey)
+ extraValue.editText?.setText(prefs.extraValue)
passwordOrLen.editText?.setText(prefs.passwordOrLen)
keyguardType.check(when (prefs.keyguardType) {
KeyguardType.A.value -> R.id.keyguardTypeA
@@ -139,8 +139,11 @@ class MainActivity : AppCompatActivity() {
receiver.editText?.doAfterTextChanged {
prefs.receiver = it?.toString()?.trim() ?: ""
}
- secret.editText?.doAfterTextChanged {
- prefs.secret = it?.toString()?.trim() ?: ""
+ extraKey.editText?.doAfterTextChanged {
+ prefs.extraKey = it?.toString()?.trim() ?: ""
+ }
+ extraValue.editText?.doAfterTextChanged {
+ prefs.extraValue = it?.toString()?.trim() ?: ""
}
passwordOrLen.editText?.doAfterTextChanged {
prefs.passwordOrLen = it?.toString()?.trim() ?: ""
@@ -166,16 +169,21 @@ class MainActivity : AppCompatActivity() {
val v = when (prefs.mode) {
Mode.BROADCAST.value -> View.VISIBLE
Mode.WIPE.value -> View.GONE
- Mode.TEST.value -> View.GONE
+ Mode.TEST.value -> {
+ NotificationManager(this).createNotificationChannels()
+ View.GONE
+ }
else -> View.GONE
}
binding.apply {
action.visibility = v
receiver.visibility = v
- secret.visibility = v
+ extraKey.visibility = v
+ extraValue.visibility = v
space1.visibility = v
space2.visibility = v
space3.visibility = v
+ space4.visibility = v
}
}
diff --git a/app/src/main/java/me/lucky/duress/Preferences.kt b/app/src/main/java/me/lucky/duress/Preferences.kt
index d4234a4..fcd3e26 100644
--- a/app/src/main/java/me/lucky/duress/Preferences.kt
+++ b/app/src/main/java/me/lucky/duress/Preferences.kt
@@ -15,7 +15,8 @@ class Preferences(ctx: Context, encrypted: Boolean = true) {
private const val MODE = "mode"
private const val ACTION = "action"
private const val RECEIVER = "receiver"
- private const val SECRET = "secret"
+ private const val EXTRA_KEY = "extra_key"
+ private const val EXTRA_VALUE = "extra_value"
private const val PASSWORD_OR_LEN = "password_or_len"
private const val KEYGUARD_TYPE = "keyguard_type"
private const val SHOW_PROMINENT_DISCLOSURE = "show_prominent_disclosure"
@@ -25,6 +26,7 @@ class Preferences(ctx: Context, encrypted: Boolean = true) {
private const val SERVICE_ENABLED = "service_enabled"
private const val AUTHENTICATION_CODE = "authentication_code"
private const val PASSWORD_LEN = "password_len"
+ private const val SECRET = "secret"
fun new(ctx: Context) = Preferences(
ctx,
@@ -64,12 +66,22 @@ class Preferences(ctx: Context, encrypted: Boolean = true) {
get() = prefs.getString(RECEIVER, "") ?: ""
set(value) = prefs.edit { putString(RECEIVER, value) }
- var secret: String
- get() = prefs.getString(SECRET, prefs.getString(AUTHENTICATION_CODE, "")) ?: ""
- set(value) = prefs.edit { putString(SECRET, value) }
+ var extraKey: String
+ get() = prefs.getString(EXTRA_KEY, "code") ?: ""
+ set(value) = prefs.edit { putString(EXTRA_KEY, value) }
+
+ var extraValue: String
+ get() = prefs.getString(
+ EXTRA_VALUE,
+ prefs.getString(SECRET, prefs.getString(AUTHENTICATION_CODE, "")),
+ ) ?: ""
+ set(value) = prefs.edit { putString(EXTRA_VALUE, value) }
var passwordOrLen: String
- get() = prefs.getString(PASSWORD_OR_LEN, prefs.getString(PASSWORD_LEN, "")) ?: ""
+ get() = prefs.getString(
+ PASSWORD_OR_LEN,
+ prefs.getInt(PASSWORD_LEN, 0).toString(),
+ ) ?: ""
set(value) = prefs.edit { putString(PASSWORD_OR_LEN, value) }
var keyguardType: Int
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index ae53dee..c193755 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -84,10 +84,10 @@
android:layout_marginVertical="5dp" />
+ android:hint="@string/extra_key">
+
+
+
+
+
+
+
+
+
+ Duress
+ Service indisponible
+ Divulgation Importante
+ L\'application utilise le service d\'accessibilité pour écouter un mot de passe de contrainte sur l\'écran de verrouillage. Une fois trouvé, il peut envoyer un message de diffusion ou effacer l\'appareil.
+ Accepter
+ Quitter
+ action*
+ récepteur
+ Code PIN/mot de passe ou longueur*
+ La longueur doit être d\'au moins la longueur de votre code PIN/mot de passe plus deux.
+ DIFFUSER
+ EFFACER
+ TEST
+ Garde-clefs:
+ A
+ B (PIN uniquement)
+ Si vous utilisez un code PIN/mot de passe (et non la longueur), le Garde-clefs A requiert que l\'option d\'affichage des caractères du mot de passe lors de la saisie soit activée. Garde-clefs B peut être dépendant de la langue (EN). Si vous changez le type de Garde-clefs, redémarrez le service d\'accessibilité.
+ Authentification
+ Défaut
+ Test
+
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 11b3574..c733493 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -8,5 +8,4 @@
Выйти
Действие *
Получатель
- Код аутентификации
\ No newline at end of file
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
new file mode 100644
index 0000000..db601b0
--- /dev/null
+++ b/app/src/main/res/values-uk/strings.xml
@@ -0,0 +1,23 @@
+
+
+ Duress
+ Сервіс недоступний
+ Помітне розкриття інформації
+ Додаток використовує службу доступності, щоб прослуховувати примусовий пароль на екрані блокування. Коли він знайдений, він може надіслати широкомовне повідомлення або стерти пристрій.
+ Прийняти
+ Вихід
+ дія*
+ приймач
+ PIN-код/пароль або довжина*
+ Довжина має бути принаймні довжиною вашого PIN-коду/пароля не менше 2.
+ ТРАНСЛЯЦІЯ
+ ОЧИЩЕННЯ
+ ТЕСТ
+ Блокування клавіш:
+ A
+ B (лише PIN-код)
+ Якщо ви використовуєте PIN-код/пароль (а не довжину), функція блокування клавіатури A вимагає відображення символів пароля під час введення. Блокування клавіатури B може залежати від мови (EN). Якщо ви змінили тип блокування клавіатури, перезапустіть службу доступності.
+ Автентифікація
+ За замовчуванням
+ Тест
+
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..d992253
--- /dev/null
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,24 @@
+
+
+ 緊急脅迫
+ 服務無法使用
+ 重要訊息揭露
+ 這個APP使用無障礙服務來在鎖定螢幕上監聽脅迫密碼。當發現時會發送廣播訊息或清除裝置。
+ 接受
+ 離開
+ 動作*
+ 接收器
+ PIN/密碼或長度*
+ 長度至少要是你的PIN或密碼的長度加2
+ 廣播
+ 清除裝置
+ 測試
+ 鍵盤類型:
+ A
+ B(僅限PIN)
+ 如果你使用PIN或密碼(而非長度),鍵盤A需要啟用輸入時顯示密碼字元之選項,鍵盤B可能限定語言(如英文)
+如果你改變鍵盤類型,需重啟無障礙服務
+ 驗證
+ 預設值
+ 測試
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 52fbfcb..7d7bf7f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -8,7 +8,8 @@
Exit
action*
receiver
- secret
+ key
+ value
PIN/password or length*
The length has to be at least your PIN/password length plus two.
BROADCAST
diff --git a/build.gradle b/build.gradle
index 4711aa7..255b9b3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
- id 'com.android.application' version '7.2.1' apply false
- id 'com.android.library' version '7.2.1' apply false
+ id 'com.android.application' version '7.2.2' apply false
+ id 'com.android.library' version '7.2.2' apply false
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
}
diff --git a/fastlane/metadata/android/en-US/changelogs/10.txt b/fastlane/metadata/android/en-US/changelogs/10.txt
new file mode 100644
index 0000000..7a8728b
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/10.txt
@@ -0,0 +1,5 @@
+custom extra key
+prepare Android 13
+add Ukrainian translation, thanks to GNCanva
+add French translation, thanks to Nathanaël Gagnepain (@Ilithy)
+add Chinese Traditional translation, thanks to rdol724
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
index e906b9c..bcd9949 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ