내가 선호가 이 변화없이 질문에 게시 된 내가 그것을 gettting하지 않은 실수 할 수있는 예를 들어 게시물을하지만 난 창 관리자 객체로 뷰 그룹 추가에서 오류가 발생했습니다, 나는 서비스에 대해 동일한 클래스를 사용했다
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} …”
-
API의 SYSTEM_ALERT_WINDOW PERMISSION> = 23 (다른 앱 위에 그리기 등) :
- 더 이상 앱의 권한 화면에 나타나지 않습니다.
- 이상하게 혼동되는 새로운 “모든 권한”화면에도 나타나지 않습니다.
-
이 권한으로 Activity.requestPermissions () 호출,
- 사용자에게 허용 / 거부 대화 상자가 표시되지 않습니다.
- 대신 Activity.onRequestPermissionsResult () 콜백이 거부 된 플래그와 함께 즉시 호출됩니다.
해결책:
앱이 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 “-> 권한의 권한에 표시되지 않습니다. 또한 …이 권한이 다른 권한과 다른 이유에 대한 설명 요청하는 방법은 무엇입니까? – Anonymous Feb 12 at 21:01 “
정상적이고 위험한 권한처럼 작동하지 않는 몇 가지 권한이 있습니다. SYSTEM_ALERT_WINDOW 및 WRITE_SETTINGS는 특히 민감하므로 대부분의 앱에서 사용해서는 안됩니다. 앱에 이러한 권한 중 하나가 필요한 경우 매니페스트에서 권한을 선언하고 사용자의 승인을 요청하는 인 텐트를 보내야합니다. 시스템은 사용자에게 세부 관리 화면을 표시하여 의도에 응답합니다.
편집 II :
FragmentActivity를 확장하는 활동에서이 코드를 사용했는데 예외 java.lang.IllegalArgumentException : 사용 된 요청 코드가 0 .. 65535 범위에 있지 않기 때문에 requestCode에 대해 하위 16 비트 만 사용할 수 있습니다. 요청 코드를 다음으로 변경하는 것을 고려할 수 있습니다. 적절한 값. – mtsahakis
말 그대로 :
요청 코드 는 0 .. 65535 범위에 있어야합니다 .
이것은 때문입니다.
- Java의 정수는 32 비트로 표시됩니다.
- requestCode에 대해 하위 16 비트를 사용할 수 있습니다.
- 다른 비트는 요청 처리에 사용됩니다.
예를 들면 :
integer value: 5463 ///hi 16 bits // | // lo 16 bits //
as binary string will look like: 0000 0000 0000 0000 0001 0101 0101 0111
주어진 범위의 간단한 사용 코드
편집 III :
AOSP API 26을 대상으로하는 앱용 (Android oreo / 8+)
SYSTEM_ALERT_WINDOW 권한을 사용하는 앱은 더 이상 다음 창 유형을 사용하여 다른 앱 및 시스템 창 위에 경고 창을 표시 할 수 없습니다.
TYPE_PHONE
TYPE_PRIORITY_PHONE
TYPE_SYSTEM_ALERT
TYPE_SYSTEM_OVERLAY
TYPE_SYSTEM_ERROR
대신 앱은 TYPE_APPLICATION_OVERLAY라는 새 창 유형을 사용해야합니다.
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)
답변
경고 대화 상자를 추가하는 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에서 변경하십시오.