Android canDrawOverlays всегда ложьAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Android canDrawOverlays всегда ложь

Сообщение Anonymous »

У системы есть разрешение на отображение поверх других приложений.
Но когда я проверяю canDrawOverlays с внутренним кодом Android, я всегда получаю false.

val mode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
appOpsManager.unsafeCheckOpNoThrow(
AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW,
uid,
packageName
)
} else {
@Suppress("DEPRECATION")
appOpsManager.checkOpNoThrow(
AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW,
uid,
packageName
)
}

Log.d(TAG, "AppOpsManager mode: $mode")

Поэтому, когда я запускаю приведенный выше код, значение режима получается как MODE_ERRORED (2).

Однако, если React-Native вызывает ту же функцию в Native Module, это обычно так.

То же самое верно, даже если вы удаляете и повторно разрешаете разрешения.

Я использовал тот же apk, но это происходило только на определенных устройствах.

Некоторые устройства являются версиями Android 16, но это также происходило и на других устройствах, поэтому я не думаю, что это проблема только Android 16.

Что мне делать?
CheckPermission.kt
object CheckPermission {

private const val TAG = "customNative - CheckPermission"

fun hasAllRequiredPermissions(context: Context): Boolean {
val requiredPermissions = mutableListOf(
Manifest.permission.READ_CALL_LOG,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.READ_CONTACTS,
Manifest.permission.READ_PHONE_NUMBERS
)

if (Build.VERSION.SDK_INT
ContextCompat.checkSelfPermission(context, perm) == PackageManager.PERMISSION_GRANTED
}

val canDrawOverlays = checkOverlayPermissionViaAppOps(context);

val hasFilePermission = MMKVHelper.hasRecordingPermission(context)

return allPermissionsGranted && canDrawOverlays && hasFilePermission
}

fun checkOverlayPermissionViaAppOps(context: Context): Boolean {
return try {
val appContext = context.applicationContext ?: return false

val appOpsManager = appContext.getSystemService(Context.APP_OPS_SERVICE) as? AppOpsManager
if (appOpsManager == null) {
Log.e(TAG, "❌ AppOpsManager null")
return false
}

val packageName = appContext.packageName
val uid = appContext.applicationInfo.uid

Log.d(TAG, "Package: $packageName, UID: $uid")

val mode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
appOpsManager.unsafeCheckOpNoThrow(
AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW,
uid,
packageName
)
} else {
@Suppress("DEPRECATION")
appOpsManager.checkOpNoThrow(
AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW,
uid,
packageName
)
}

Log.d(TAG, "AppOpsManager mode: $mode (0=ALLOW, 1=MODE_IGNORED, 2=ERRORED, 3=DEFAULT, 4=FOREGROUND)")

val result = mode == AppOpsManager.MODE_ALLOWED

result

} catch (e: Exception) {
Log.e(TAG, "❌ AppOpsManager 확인 실패", e)
e.printStackTrace()
false
}
}
}

NativeModule.kt
@ReactMethod
fun canDrawOverlays(promise: Promise) {
try {
val canDraw = CheckPermission.checkOverlayPermissionViaAppOps(reactApplicationContext)
promise.resolve(canDraw)
} catch (e: Exception) {
promise.reject("OVERLAY_CHECK_ERROR", e.message)
}
}

PhoneStateReceiver.kt
class PhoneStateReceiver : BroadcastReceiver() {

companion object {
private const val TAG = "customNative - PhoneStateReceiver"
var isIncomingCall = false
private var callState = ""
private var lastCallNumber = ""
}

@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("ScheduleExactAlarm", "UnsafeProtectedBroadcastReceiver")
override fun onReceive(context: Context, intent: Intent) {

val appContext = MainApplication.getAppContext() ?: context.applicationContext

if (!CheckPermission.hasAllRequiredPermissions(appContext)) {
return //always false!
}
}
}


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

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

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

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

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

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