Я предпочитаю этот пост, например, но у меня возникла ошибка при добавлении группы просмотра в объект windowmanager, я использовал тот же класс для Сервиса, который был опубликован в вопросе, без изменений, где я могу ошибиться, я не получил его
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params); // here
когда я добавляю представление в WindowManger
вот мой файл манифеста
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.searce.testoverlay"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="TestOverlayActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".HUD"></service>
</application>
</manifest>
ошибка
09-27 18:49:23.561: ERROR/AndroidRuntime(653): Uncaught handler: thread main exiting due to uncaught exception
09-27 18:49:23.571: ERROR/AndroidRuntime(653): java.lang.RuntimeException: Unable to create service com.searce.testoverlay.HUD: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRoot$W@44da9bc0 -- permission denied for this window type
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2790)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at android.app.ActivityThread.access$3200(ActivityThread.java:119)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1917)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at android.os.Handler.dispatchMessage(Handler.java:99)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at android.os.Looper.loop(Looper.java:123)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at android.app.ActivityThread.main(ActivityThread.java:4363)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at java.lang.reflect.Method.invokeNative(Native Method)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at java.lang.reflect.Method.invoke(Method.java:521)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at dalvik.system.NativeStart.main(Native Method)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): Caused by: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRoot$W@44da9bc0 -- permission denied for this window type
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at android.view.ViewRoot.setView(ViewRoot.java:492)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at com.searce.testoverlay.HUD.onCreate(HUD.java:41)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2780)
09-27 18:49:23.571: ERROR/AndroidRuntime(653): ... 10 more
" @ ceph3us, знаете ли вы, как добиться этого для> = M? ActivityCompat.requestPermissions (this, new String [] {Manifest.permission.SYSTEM_ALERT_WINDOW} ..."
SYSTEM_ALERT_WINDOW PERMISSION на API> = 23 (рисовать поверх других приложений и т. Д.):
Вызов Activity.requestPermissions () с этим разрешением,
Решение:
пример кода:
/** code to post/handler request for permission */ public final static int REQUEST_CODE = -1010101; *(see edit II)* public void checkDrawOverlayPermission() { /** check if we already have permission to draw over other apps */ if (!Settings.canDrawOverlays(Context)) { /** if not construct intent to request permission */ Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); /** request permission via start activity for result */ startActivityForResult(intent, REQUEST_CODE); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { /** check if received result code is equal our requested code for draw permission */ if (requestCode == REQUEST_CODE) { / ** if so check once again if we have permission */ if (Settings.canDrawOverlays(this)) { // continue here - permission was granted } } }
«И как пользователь может отключить это разрешение? Это не отображается в разрешениях в настройках -> приложения ->« MyApp »-> разрешения. Также ... любое объяснение того, почему это разрешение отличается от других в как мы просим об этом? - Аноним, 12 февраля в 21:01 "
Особые разрешения
редактировать II:
Я использовал этот код в Activity, расширяющем FragmentActivity, и получил Exception java.lang.IllegalArgumentException: для requestCode можно использовать только младшие 16 бит, поскольку используемый код запроса не находится в диапазоне 0 .. 65535. Вы можете подумать об изменении кода запроса на подходящее значение. - мцахаки
как говорится:
это потому что:
так например:
integer value: 5463 ///hi 16 bits // | // lo 16 bits // as binary string will look like: 0000 0000 0000 0000 0001 0101 0101 0111
простой код использования в заданном диапазоне
редактировать III:
Приложения, использующие разрешение SYSTEM_ALERT_WINDOW, больше не могут использовать следующие типы окон для отображения окон предупреждений над другими приложениями и системными окнами:
TYPE_PHONE TYPE_PRIORITY_PHONE TYPE_SYSTEM_ALERT TYPE_SYSTEM_OVERLAY TYPE_SYSTEM_ERROR
Вместо этого приложения должны использовать новый тип окна под названием TYPE_APPLICATION_OVERLAY.
Тип окна: оверлейные окна приложения отображаются над всеми окнами активности (типы между FIRST_APPLICATION_WINDOW и LAST_APPLICATION_WINDOW), но ниже важных системных окон, таких как строка состояния или IME.
Система может изменить положение, размер или видимость этих окон в любое время, чтобы уменьшить визуальный беспорядок для пользователя, а также управлять ресурсами.
Требуется разрешение SYSTEM_ALERT_WINDOW.
Система будет регулировать важность процессов с помощью этого типа окна, чтобы снизить вероятность их уничтожения из-за нехватки памяти. В многопользовательских системах отображается только на экране пользователя-владельца.
WindowManager.LayoutParams wLp = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE; Window.setAttributes(WindowManager.LayoutParams)
источник
java.lang.IllegalArgumentException: Can only use lower 16 bits for requestCode
потому что используемый код запроса не находится в диапазоне 0 .. 65535. Вы можете подумать об изменении кода запроса на подходящее значение.После ответа ceph3us на добавление диалогового окна предупреждений это сработало нормально
final AlertDialog dialog = dialogBuilder.create(); final Window dialogWindow = dialog.getWindow(); final WindowManager.LayoutParams dialogWindowAttributes = dialogWindow.getAttributes(); // Set fixed width (280dp) and WRAP_CONTENT height final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); lp.copyFrom(dialogWindowAttributes); lp.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 280, getResources().getDisplayMetrics()); lp.height = WindowManager.LayoutParams.WRAP_CONTENT; dialogWindow.setAttributes(lp); // Set to TYPE_SYSTEM_ALERT so that the Service can display it if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { dialogWindow.setType(WindowManager.LayoutParams.TYPE_TOAST); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { dialogWindow.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY); } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { dialogWindow.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); } dialog.show();
Но использование TYPE_SYSTEM_ALERT может привести к срабатыванию политики удаления приложений Google, использующих опасные разрешения. Убедитесь, что у вас есть веское обоснование на случай, если это потребуется Google.
источник
Вы можете изменить целевой SDK на 22 или меньше, тогда он также будет работать с API 23.
Измените его в Gradle.Build.
источник