Несоответствие контрольной суммы APK администратора устройства при инициализации через QR на новом устройстве AndroidAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Несоответствие контрольной суммы APK администратора устройства при инициализации через QR на новом устройстве Android

Сообщение Anonymous »

Я пытаюсь подключить приложение Android Device Admin на совершенно новом устройстве с помощью QR-кода. Раньше я сталкивался с ошибкой об отсутствующих компонентах, но теперь приложение завершается с ошибкой из-за несоответствия контрольной суммы.
Настройка:
 – я создаю APK-файл выпуска с помощью Gradle в GitHub Actions с хранилищем ключей выпуска.
 – Рабочий процесс копирует APK на сервер через SCP.
-SHA256 APK в GitHub Действия:

Код: Выделить всё

78b718df0e56ce5c6f3673c4a2ce277dc83d001544234cf6b00648709828048c
-SHA256 APK, скачанного с сервера:

Код: Выделить всё

78b718df0e56ce5c6f3673c4a2ce277dc83d001544234cf6b00648709828048c
Предоставление JSON:

Код: Выделить всё

{
"android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME": "com.example.kios_app/.KioskDeviceAdminReceiver",
"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION": "http://example.com/downloads/app-release.apk",
"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM": "78b718df0e56ce5c6f3673c4a2ce277dc83d001544234cf6b00648709828048c",
"android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE": {"server_url": "http://example.com/api"},
"android.app.extra.PROVISIONING_SKIP_ENCRYPTION": true,
"android.app.extra.PROVISIONING_WIFI_SSID": "MySSID",
"android.app.extra.PROVISIONING_WIFI_PASSWORD": "MyPassword",
"android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE": "WPA"
}
Фрагмент манифеста:

Код: Выделить всё















































android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="deviceManagement" />
















Класс KioskDeviceAdminReceiver:

Код: Выделить всё

package com.example.kios_app

import android.app.admin.DeviceAdminReceiver
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.UserManager
import android.provider.Settings
import android.util.Log

class KioskDeviceAdminReceiver : DeviceAdminReceiver() {

companion object {
private const val TAG = "KioskDeviceAdmin"
const val REQUEST_CODE_ENABLE_ADMIN = 1001

fun getComponentName(context: Context): ComponentName =
ComponentName(context.applicationContext, KioskDeviceAdminReceiver::class.java)
}

override fun onEnabled(context: Context, intent: Intent) {
super.onEnabled(context, intent)
Log.d(TAG, "Device Admin Enabled")

setupDevicePolicies(context)
}

override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
Log.d(TAG, "onReceive: ${intent.action}")

when (intent.action) {
ACTION_DEVICE_ADMIN_ENABLED -> {
Log.d(TAG, "Device admin enabled")
setupDevicePolicies(context)
}
ACTION_PROFILE_PROVISIONING_COMPLETE ->  {
Log.d(TAG, "Profile provisioning complete")
completeDeviceOwnerSetup(context)
}
}
}

override fun onProfileProvisioningComplete(context: Context, intent: Intent) {
super.onProfileProvisioningComplete(context, intent)
Log.d(TAG, "🎯 Profile Provisioning Complete - Device Owner mode activated")

completeDeviceOwnerSetup(context)
}

private fun setupDevicePolicies(context: Context) {
try {
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val admin = getComponentName(context)

dpm.setLockTaskPackages(admin, arrayOf(context.packageName))

if (dpm.isDeviceOwnerApp(context.packageName)) {
setupDeviceOwnerPolicies(dpm, admin, context)
Log.d(TAG, "🚀 Device Owner policies applied")
} else {
Log.d(TAG, "ℹ️ Regular Device Admin mode")
}

} catch (e: Exception) {
Log.e(TAG, "Error setting up device policies", e)
}
}

private fun completeDeviceOwnerSetup(context: Context) {
try {
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager

if (dpm.isDeviceOwnerApp(context.packageName)) {
Log.d(TAG, "Device Owner confirmed")

val intent = Intent(context, MainActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
}
context.startActivity(intent)
} else {
Log.w(TAG, "Not Device Owner after provisioning")
}

} catch (e: Exception) {
Log.e(TAG, "Error completing device owner setup", e)
}
}

private fun setupDeviceOwnerPolicies(dpm: DevicePolicyManager, admin: ComponentName, context: Context) {
try {
dpm.setPasswordMinimumLength(admin, 0)
dpm.setPasswordQuality(admin, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)

dpm.setSecureSetting(admin, Settings.Secure.INSTALL_NON_MARKET_APPS, "1")

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
dpm.addUserRestriction(admin, UserManager.DISALLOW_SAFE_BOOT)
dpm.addUserRestriction(admin, UserManager.DISALLOW_FACTORY_RESET)
dpm.addUserRestriction(admin, UserManager.DISALLOW_ADD_USER)
dpm.addUserRestriction(admin, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA)
}

try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
dpm.setStatusBarDisabled(admin, true)
}
} catch (e: Exception) {
Log.w(TAG, "Cannot disable status bar: ${e.message}")
}

dpm.addUserRestriction(admin, UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS)

Log.d(TAG, "Device Owner policies setup complete")

} catch (e: Exception) {
Log.e(TAG, "Error setting device owner policies", e)
}
}

override fun onDisableRequested(context: Context, intent: Intent): CharSequence {
return "Disabling device administration will take it out of kiosk mode."
}

override fun onDisabled(context: Context, intent:  Intent) {
super.onDisabled(context, intent)
Log.w(TAG, "Device Admin Disabled")
}
}
Наблюдения/Попытки:
-APK на сервере идентичен тому, который был создан локально (соответствует SHA256).
-Загрузка с помощью Curl -L, включая метку времени для обхода кэширования, по-прежнему дает ту же контрольную сумму.
-APK подписан с хранилищем ключей выпуска.
-Устройство не удается выполнить инициализацию из-за несоответствия контрольной суммы.
Вопросы:
  • Почему устройство жалуется на несоответствие контрольной суммы, даже если SHA256 соответствует?
  • Может ли это быть вызвано кэшированием HTTP, подписанием или предоставлением метаданных QR?
  • Как убедиться, что устройство принимает APK для подготовки без ошибок контрольной суммы?
Среда:
-устройство Android 13/14
-Gradle 8.13
- GitHub Action runner: ubuntu-latest
-Nginx, обслуживающий APK

Подробнее здесь: https://stackoverflow.com/questions/798 ... -android-d
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»