ウィンドウを追加できませんandroid.view.ViewRoot $ W @ 44da9bc0 —このウィンドウタイプの権限が拒否されました


82

たとえば、私はこの投稿を好みますが、ウィンドウマネージャーオブジェクトにビューグループを追加するときにエラーが発生しました。質問に投稿されたのと同じクラスをサービスに使用しましたが、間違いなく取得できませんでした。

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

回答:


154

でこの権限を使用してみてください AndroidManifest.

android.permission.SYSTEM_ALERT_WINDOW

API> = 23については


@ ceph3us> = Mでそれを達成する方法を知っていますか?ActivityCompat.requestPermissions(this、new String [] {Manifest.permission.SYSTEM_ALERT_WINDOW}、Perm.PERMISSIONS_REQUEST_SYSTEM_ALERT_WINDOW); 何も発射しません。と同じ:ActivityCompat.requestPermissions(this、new String [] {Manifest.permission.SYSTEM_ALERT_WINDOW}、Perm.PERMISSIONS_REQUEST_SYSTEM_ALERT_WINDOW);
Martin Pfeffer

さらに、プログラムで、または電話の設定から手動で、明示的に許可を与える必要がある場合があります。Huawei Nexus 6pを使用していて、アプリケーションの設定で、画面セクションの他のアプリケーションで描画するときに[はい]をクリックしました。
アミール2018年

良い解決策のためにこれを参照してください。github.com/facebook/react-native/issues/...
ウィラ

144

" @ ceph3us> = Mでそれを達成する方法を知っていますか?ActivityCompat.requestPermissions(this、new String [] {Manifest.permission.SYSTEM_ALERT_WINDOW} ..."

  1. APIのSYSTEM_ALERT_WINDOWPERMISSION> = 23(他のアプリの上に描画するなど):

    • アプリの権限画面に表示されなくなりました。
    • 奇妙に紛らわしい新しい「すべての権限」画面にも表示されません
  2. この権限で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」->権限の権限には表示されません。また...この権限が他の権限と異なる理由についての説明私たちがそれを要求する方法は?–匿名の2月12日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)

2
そして、ユーザーはどのようにしてこの権限を無効にできますか?[設定]-> [アプリ]-> [MyApp]-> [権限]の権限には表示されません。また...この許可が私たちが要求する方法で他の許可と異なる理由についての説明はありますか?
匿名

1
FragmentActivityを拡張するアクティビティでこのコードを使用しましたが、java.lang.IllegalArgumentException: Can only use lower 16 bits for requestCode使用されたリクエストコードが0 .. 65535の範囲にないため、例外が発生しました。リクエストコードを適切な値に変更することを検討してください。
mtsahakis 2016年

1
このリクエストコードを使用してください....... public final static int REQUEST_CODE = 5463&0xffffff00;
ムハンマドアディル2016

@MuhammadAdilここでビット単位の目的は何ですか?u値を5376に変更します
ceph3us 2016

@ ceph3usここで、そのREQUEST_CODEを使用すると、このエラーが発生します..... java.lang.IllegalArgumentException:requestCode ........には下位16ビットしか使用できないため、修正する必要があります。
ムハンマドアディル2016

3

アラートダイアログを追加するための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削除ポリシーがトリガーされる可能性があります。グーグルがそれを要求する場合に備えて、あなたが有効な正当化を持っていることを確認してください。


TYPE_APPLICATION_OVERLAYを使用していませんが、Android 7.1.1以下の電話で他のタイプ(私の場合はTYPE_PHONE)を使用すると、この厄介なBadTokenExceptionを取り除くことができました。stackoverflow.com/questions/32224452/を

-8

ターゲットSDKを22以下に変更すると、API23でも機能します。

Gradle.Buildで変更します。


3
@ハルクそれはおそらく最善の解決策ではありませんが、それを指摘するのは良いことです。
クォーク

これは問題を修正しません。これは使用できる簡単な回避策ですが、api> 23
Aaron
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.