Ответ 1
Попробуйте использовать это разрешение в AndroidManifest.
android.permission.SYSTEM_ALERT_WINDOW
Я предпочитаю этот пост, но я получил ошибку при добавлении viewgroup в объект 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 [email protected] -- 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 [email protected] -- 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
Попробуйте использовать это разрешение в AndroidManifest.
android.permission.SYSTEM_ALERT_WINDOW
"@ceph3us вы знаете, как его достичь для >= M? ActivityCompat.requestPermissions(это новая строка [] {Manifest.permission.SYSTEM_ALERT_WINDOW}..."
SYSTEM_ALERT_WINDOW PERMISSION для API >= 23 (нарисуйте другие приложения и т.д.):
Вызов Activity.requestPermissions() с этим разрешением,
Решение:
Если приложение нацелено на уровень API 23 или выше, пользователь приложения должен прямо разрешать это разрешение приложению через разрешение экран управления. Приложение запрашивает одобрение пользователя, отправив с действием ACTION_MANAGE_OVERLAY_PERMISSION. Приложение может проверять имеет ли оно это разрешение, позвонив Settings.canDrawOverlays()
пример кода:
/** 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"
Существует несколько разрешений, которые не ведут себя как нормальные и опасные разрешения. SYSTEM_ALERT_WINDOW и WRITE_SETTINGS - особенно чувствительны, поэтому большинство приложений не должны их использовать. Если приложение требуется одно из этих разрешений, оно должно объявить разрешение в манифест и отправить намерение, запрашивающее авторизацию пользователя. система реагирует на намерение, показывая подробный экран управления пользователю.
edit II:
Я использовал этот код в активном расширении FragmentActivity, и я получил Exception java.lang.IllegalArgumentException: может использовать только младшие 16 бит для requestCode, потому что используемый код запроса не находится в диапазоне 0.. 65535. Вы можете подумать об изменении своего запросить код до соответствующего значения. - mtsahakis
поскольку это sais:
код запроса должен находиться в диапазоне 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
код простого использования в заданном диапазоне
Вы можете изменить целевой SDK на 22 или меньше, а затем работать с API 23.
Измените его в Gradle.Build.