Многие разработчики, впервые задумываясь о создании приложения для блокировки экрана, задаются вопросом: возможно ли создать android locker на языке kotlin? Короткий ответ — да, но с важными ограничениями. Полноценный системный локер, который полностью заменяет встроенный экран блокировки Android, без root-прав или системных привилегий не сделать. Однако создать кастомный экран с PIN-кодом, графическим ключом или биометрией для защиты самого приложения или его отдельных функций — задача вполне выполнимая. В этой статье мы разберём оба подхода и напишем работающий пример.
Два типа локеров: что действительно можно сделать
Прежде чем погружаться в код, важно разграничить понятия. Под термином «Android Locker» могут скрываться два принципиально разных продукта: app locker и screen locker. Первый защищает доступ к выбранным приложениям, второй пытается заменить системный экран блокировки. Разница между ними определяет и требования к разрешениям, и саму возможность размещения в Google Play.
| Характеристика | App Locker (блокировщик приложений) | Screen Locker (кастомный экран блокировки) |
|---|---|---|
| Как работает | Отслеживает запуск выбранных приложений через UsageStats API или foreground service и показывает свой экран с запросом пароля | Пытается отключить системный Keyguard и показать собственную Activity поверх локскрина |
| Системные разрешения | PACKAGE_USAGE_STATS, FOREGROUND_SERVICE, SYSTEM_ALERT_WINDOW (опционально) | Требует DevicePolicyManager или root-доступа для полного контроля |
| Допустим ли в Google Play | Да, при корректной реализации | Строго ограничен: Google пропускает только приложения с обоснованной необходимостью (например, корпоративные) |
| Сложность реализации | Средняя | Высокая, с риском блокировки аккаунта разработчика |
Поэтому, когда мы говорим возможно ли создать android locker на языке kotlin, практический ответ такой: app locker — да, screen locker — только для корпоративного использования или экспериментальных проектов вне Google Play.
App Locker: создаём блокировщик приложений
App Locker — наиболее реалистичный сценарий для начинающего разработчика. Принцип работы сводится к трём шагам: получить список установленных приложений, отследить запуск выбранного приложения и показать экран с запросом кода. Для хранения пароля используется Room, для проверки — BiometricPrompt API или собственный PIN-экран.
Необходимые разрешения и зависимости
В AndroidManifest.xml нужно прописать два ключевых разрешения: PACKAGE_USAGE_STATS для доступа к статистике запуска приложений и FOREGROUND_SERVICE для работы фонового сервиса. Также добавьте разрешение на использование биометрии, если планируете разблокировку по отпечатку пальца.
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
В build.gradle.kts модуля app добавьте Room для хранения паролей и Biometric для fingerprint-аутентификации. Jetpack Compose для интерфейса ускорит разработку в разы.
dependencies {
implementation("androidx.room:room-runtime:2.6.1")
ksp("androidx.room:room-compiler:2.6.1")
implementation("androidx.biometric:biometric:1.4.0")
implementation("androidx.lifecycle:lifecycle-service:2.5.1")
}
Отслеживание запуска приложений
Сердце любого app locker — фоновый сервис, который периодически опрашивает UsageStatsManager и проверяет, не запущено ли сейчас заблокированное приложение. Частоту опроса стоит выбирать с умом: слишком частая проверка сажает батарею, слишком редкая — позволяет увидеть содержимое приложения до появления блокировки.
class LockerService : Service() {
private lateinit var usageStatsManager: UsageStatsManager
override fun onCreate() {
super.onCreate()
usageStatsManager = getSystemService(USAGE_STATS_SERVICE) as UsageStatsManager
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
checkForegroundApp()
return START_STICKY
}
private fun checkForegroundApp() {
val currentTime = System.currentTimeMillis()
val stats = usageStatsManager.queryUsageStats(
UsageStatsManager.INTERVAL_DAILY, currentTime - 1000, currentTime
)
val foregroundPackage = stats.maxByOrNull { it.lastTimeUsed }?.packageName
// проверить, заблокировано ли это приложение, и показать LockScreenActivity
}
}
Биометрическая аутентификация
Для современного локера пароль — не единственный способ защиты. BiometricPrompt API позволяет разблокировать приложение по отпечатку пальца или распознаванию лица. В Kotlin это реализуется лаконично:
val biometricPrompt = BiometricPrompt(
this,
ContextCompat.getMainExecutor(this),
object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
// разблокировать приложение
finish()
}
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
// показать fallback на PIN
}
}
)
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Разблокировка")
.setSubtitle("Подтвердите личность")
.setNegativeButtonText("PIN")
.build()
biometricPrompt.authenticate(promptInfo)
Screen Locker: почему это сложно
Создание кастомного экрана блокировки, который полностью заменяет системный, сопряжено с фундаментальными ограничениями Android. Начиная с API 15, метод KeyguardManager.KeyguardLock.disableKeyguard() объявлен устаревшим, а его использование на современных версиях Android может приводить к непредсказуемому поведению. Официальная документация рекомендует использовать вместо него Activity.setShowWhenLocked(true) в сочетании с флагом окна FLAG_SHOW_WHEN_LOCKED.
Этот подход позволяет вашему Activity отображаться поверх системного локскрина, но не отключает системную блокировку полностью. Для корпоративных устройств существует DevicePolicyManager с методом setKeyguardDisabled(), но он требует прав администратора устройства и не предназначен для массового распространения через Play Store.
Jetpack Compose для экрана блокировки
Современный способ создания UI для локера — Jetpack Compose. Он позволяет за несколько десятков строк написать стильный экран с анимациями ввода PIN-кода. Открытый проект ComposeLockScreen на GitHub демонстрирует именно такой подход: Material 3, тёмная и светлая темы, анимации при вводе и проверке кода. Вот минимальный пример PIN-экрана на Compose:
@Composable
fun PinLockScreen(onSuccess: () -> Unit) {
var pin by remember { mutableStateOf("") }
val maxLength = 4
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text("Введите PIN", style = MaterialTheme.typography.headlineMedium)
Spacer(modifier = Modifier.height(24.dp))
// индикатор введённых цифр
Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
repeat(maxLength) { index ->
val filled = index < pin.length
Box(
modifier = Modifier
.size(16.dp)
.background(
if (filled) MaterialTheme.colorScheme.primary
else Color.Gray,
shape = CircleShape
)
)
}
}
Spacer(modifier = Modifier.height(32.dp))
// сетка цифровых кнопок
val keys = listOf("1", "2", "3", "4", "5", "6", "7", "8", "9", "", "0", "⌫")
LazyVerticalGrid(columns = GridCells.Fixed(3)) {
items(keys) { key ->
if (key.isNotEmpty()) {
Button(onClick = {
if (key == "⌫") pin = pin.dropLast(1)
else if (pin.length < maxLength) pin += key
if (pin.length == maxLength) onSuccess()
}) {
Text(key, fontSize = 20.sp)
}
}
}
}
}
}
На языке Kotlin или Java: что выбрать
До 2019 года этот вопрос был предметом споров, но сегодня ответ однозначен. Google официально перевела Android-разработку на Kotlin-first, и все современные библиотеки — Jetpack Compose, Room, WorkManager — в первую очередь тестируются на Kotlin. Для создания локера преимущества Kotlin особенно заметны в работе с асинхронщиной, биометрией и Compose. Ответ с площадки Ответы Mail.ru подтверждает: «С недавних пор Kotlin предпочтительный язык для андроида, сам гугл рекомендует на нем писать».
Советы начинающему разработчику
Первое и главное правило: не пытайтесь сразу написать идеальный локер, который заменит системный. Начните с простого app blocker для одного-двух приложений, используя Compose и Room. Следующие шаги помогут выстроить процесс:
- Сначала реализуйте UI. Напишите экран ввода PIN-кода на Jetpack Compose и протестируйте на реальном устройстве. Убедитесь, что анимации плавные и кнопки отзывчивые.
- Затем добавьте Room. Сохраняйте PIN не в открытом виде, а в виде хэша. Для этого подойдёт SHA-256, реализованный парой строк на Kotlin.
- Подключите UsageStatsManager. Реализуйте foreground service и проверьте, что при открытии заблокированного приложения появляется ваш lock screen.
- Добавьте биометрию. BiometricPrompt API повысит удобство и безопасность.
- Оптимизируйте потребление батареи. Не опрашивайте UsageStatsManager каждую секунду — интервала в 500 миллисекунд достаточно для быстрой реакции.
Коротко о главном
Итак, возможно ли создать android locker на языке kotlin? Да, app locker с PIN-кодом, графическим ключом и биометрией создаётся штатными средствами Android и публикуется в Google Play. Полноценный системный screen locker — задача принципиально иного уровня, с ограничениями платформы и политикой модерации. Начните с малого: напишите экран блокировки на Compose, добавьте Room для хранения паролей и foreground service для отслеживания запуска приложений. Полученный опыт станет отличной базой для более сложных проектов в сфере мобильной безопасности.