Tengo prefieren este mensaje, por ejemplo, pero me dio el error en la adición de ViewGroup en el objeto gestor de ventanas, he utilizado la misma clase para el servicio tal como fue anunciado en la cuestión sin ningún cambio en el que puedo error que yo no gettting se
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params); // here
cuando agrego vista al WindowManger
aquí está mi archivo de manifiesto
<?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>
error
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, ¿sabe cómo lograrlo para> = M? ActivityCompat.requestPermissions (esto, nueva Cadena [] {Manifest.permission.SYSTEM_ALERT_WINDOW} ..."
SYSTEM_ALERT_WINDOW PERMISSION en API> = 23 (Dibujar sobre otras aplicaciones, etc.):
Llamando Activity.requestPermissions () con este permiso,
Solución:
código de ejemplo:
/** 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 } } }
"¿Y cómo puede el usuario deshabilitar este permiso? No se muestra en los permisos de configuración-> aplicaciones ->" MyApp "-> permisos. Además ... cualquier explicación de por qué este permiso es diferente de los demás en el cómo lo solicitamos? - Anónimo 12 de febrero a las 21:01 "
Permisos especiales
editar II:
Usé este código en una actividad que extendía FragmentActivity y obtuve la excepción java.lang.IllegalArgumentException: solo puedo usar 16 bits inferiores para requestCode porque el código de solicitud utilizado no está en el rango de 0 .. 65535. Podría considerar cambiar su código de solicitud a un valor apropiado. - mtsahakis
como dice:
esto es porque:
así por ejemplo:
integer value: 5463 ///hi 16 bits // | // lo 16 bits // as binary string will look like: 0000 0000 0000 0000 0001 0101 0101 0111
código de uso simple en un rango dado
editar III:
Las aplicaciones que usan el permiso SYSTEM_ALERT_WINDOW ya no pueden usar los siguientes tipos de ventana para mostrar ventanas de alerta sobre otras aplicaciones y ventanas del sistema:
TYPE_PHONE TYPE_PRIORITY_PHONE TYPE_SYSTEM_ALERT TYPE_SYSTEM_OVERLAY TYPE_SYSTEM_ERROR
En su lugar, las aplicaciones deben usar un nuevo tipo de ventana llamado TYPE_APPLICATION_OVERLAY.
Tipo de ventana: las ventanas de superposición de aplicaciones se muestran encima de todas las ventanas de actividad (tipos entre FIRST_APPLICATION_WINDOW y LAST_APPLICATION_WINDOW) pero debajo de las ventanas críticas del sistema, como la barra de estado o IME.
El sistema puede cambiar la posición, el tamaño o la visibilidad de estas ventanas en cualquier momento para reducir el desorden visual para el usuario y también administrar los recursos.
Requiere permiso SYSTEM_ALERT_WINDOW.
El sistema ajustará la importancia de los procesos con este tipo de ventana para reducir la posibilidad de que el asesino de poca memoria los mate. En los sistemas multiusuario, solo se muestra en la pantalla del usuario propietario.
WindowManager.LayoutParams wLp = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE; Window.setAttributes(WindowManager.LayoutParams)
fuente
java.lang.IllegalArgumentException: Can only use lower 16 bits for requestCode
porque el código de solicitud usado no está en el rango de 0 .. 65535. Puede considerar cambiar su código de solicitud a un valor apropiado.Siguiendo la respuesta de ceph3us para agregar un diálogo de alerta, esto funcionó bien
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();
Pero el uso de TYPE_SYSTEM_ALERT podría activar la política de eliminación de Google de aplicaciones que usan permisos peligrosos. Asegúrese de tener una justificación válida en caso de que Google lo requiera.
fuente
Puede cambiar su SDK de destino a 22 o menos, luego también funciona en API 23.
Cámbielo en Gradle.Build.
fuente