ArrayList
- это сборники данных разных типов, тогда как List<>
представляет собой совокупность аналогичных типов собственных депектенций.
Для того, что должно быть совершенно очевидными причинами, обычным приложениям не разрешается создавать произвольные окна поверх экрана блокировки. Как вы думаете, что я мог бы сделать, если бы я создал окно на вашем заблокированном экране, которое могло бы идеально подражать реальному экрану блокировки, чтобы вы не могли разглядеть разницу?
Техническая причина вашей ошибки заключается в использовании функции TYPE_KEYGUARD_DIALOG
- для этого требуется android.permission.INTERNAL_SYSTEM_WINDOW
, который является разрешением на уровне подписи. Это означает, что только приложения, подписанные с одним и тем же сертификатом в качестве создателя разрешения, могут его использовать.
Создателем android.permission.INTERNAL_SYSTEM_WINDOW
является сама система Android, поэтому, если ваше приложение является частью ОС, у вас нет шансов.
Есть хорошо определенные и хорошо документированные способы уведомлять пользователя о информации с блокировки экрана . Вы можете создавать настраиваемые уведомления, которые отображаются на заблокированном экране, и пользователь может взаимодействовать с ними.
, если вы используете apiLevel >= 19
, не используйте
WindowManager.LayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
, который получает следующую ошибку:
android.view.WindowManager $ BadTokenException: не удается добавить окно android.view.ViewRootImpl$W@40ec8528 - разрешено для этого типа окна
blockquote>Используйте это вместо:
LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL
TYPE_SYSTEM_ALERT
отлично работает на Android 5.1 с android.permission.SYSTEM_ALERT_WINDOW
, предоставленным в манифесте.
– Sam
18 May 2016 в 08:27
android.permission.SYSTEM_ALERT_WINDOW
с LayoutParams.TYPE_TOAST
?
– t0m
21 February 2017 в 13:38
Я попытался изо всех сил попробовать все примеры, доступные для этой проблемы. Наконец, я получил ответ на этот вопрос, я не знаю, насколько он надежный, но мое приложение сейчас не сбой.
windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
//here is all the science of params
final LayoutParams myParams = new LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
PixelFormat.TRANSLUCENT
);
В вашем файле манифеста просто дайте разрешение
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Дополнение к этому вы также можете проверить для уровня API, если его> = 23, тогда
if(Build.VERSION.SDK_INT >= 23) {
if (!Settings.canDrawOverlays(Activity.this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 1234);
}
}
else
{
Intent intent = new Intent(Activity.this, Service.class);
startService(intent);
}
Я надеюсь, что это кому-то поможет. Полный пример https://anam-android-codes.blogspot.in/?m=1
LayoutParams.TYPE_PHONE устарел. Я обновил свой код следующим образом.
parameters = if (Build.VERSION.SDK_INT > 25) {
LayoutParams(
minHW * 2 / 3, minHW * 2 / 3,
LayoutParams.TYPE_APPLICATION_OVERLAY,
LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT)
}else {
LayoutParams(
minHW * 2 / 3, minHW * 2 / 3,
LayoutParams.TYPE_PHONE,
LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT)
}
LayoutParams.TYPE_APPLICATION_OVERLAY требует api level 26 или выше.
Я предполагаю, что вы должны отличать цель (до и после Oreo)
int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
LAYOUT_FLAG,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
Build.VERSION_CODES.O
& amp; WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
. Моя targetSdkVersion - 26
– Gabe O'Leary
20 February 2018 в 23:06
Мне удалось наконец отобразить окно на экране блокировки с использованием TYPE_SYSTEM_OVERLAY
вместо TYPE_KEYGUARD_DIALOG
. Это работает так, как ожидалось, и добавляет окно на экран блокировки.
Проблема заключается в том, что окно добавляется поверх всего, что возможно. То есть, окно будет отображаться поверх блокировки клавиатуры или шаблона в случае защищенных экранов блокировки. В случае незащищенного экрана блокировки он появится поверх лотка уведомлений, если вы откроете его из экрана блокировки.
Для меня это неприемлемо. Я надеюсь, что это может помочь кому-либо еще столкнуться с этой проблемой.
Поиск
Нарисуйте другие приложения
blockquote>в настройках и включите приложение. Для Android 8 Oreo попробуйте
Настройки> Приложения и amp; Уведомления> Информация о приложении> Показать другие приложения> Включить
blockquote>
Для уровня API Android 8.0.0 вы должны использовать
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
вместо LayoutParams.TYPE_TOAST или TYPE_APPLICATION_PANEL или SYSTEM_ALERT.
измените флагом флага Windowmanger «TYPE_SYSTEM_OVERLAY» на «TYPE_APPLICATION_OVERLAY» в вашем проекте, чтобы сделать совместимым с android O
WindowManager.LayoutParams.TYPE_PHONE to WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY