2017-09-14 3 views
5

を使用してウィンドウタイプ2038年、私は他のアプリケーションの上にあるビューを作成しようとしているために拒否された権限:アンドロイド:TYPE_APPLICATION_OVERLAY

WindowManager.LayoutParams paramsDirectorView = new WindowManager.LayoutParams(
     WindowManager.LayoutParams.WRAP_CONTENT, 
     WindowManager.LayoutParams.WRAP_CONTENT, 
     WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, 
     WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 
     PixelFormat.TRANSLUCENT); 

私は他の回答に見て、「アプリケーション上で描く」ために、以下のことを発見しました。

  • 私はandroid.permission.SYSTEM_ALERT_WINDOWマニフェスト
  • に私は(これを)Settings.canDrawOverlaysをやってきた01来るをチェックが真です。
  • 私はまだ取得していますここでpermission denied for window type

位置にすべてを行っている「 - ウィンドウタイプ2038年のために拒否された権限」のエラーを。現時点ではTYPE_PHONEを使用していますが、動作しますが、非推奨となりTYPE_APPLICATION_OVERLAYを使用するようになりました。 TYPE_PHONEの答えは、本当に私はアンドロイド

のAndroid 7.1.2上で動作しているのですが、解像度のAndroid O.

で廃止され、「パッチワーク」ソリューションではありませんとしていくつかのいずれかが、このフォローアップすることができます。 view.WindowManager $ BadTokenException: - ウィンドウ タイプ2038用の拒否権をandroid.appで android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3344) でウィンドウ [email protected]を追加することができません。 .ActivityThread.-wrap21(ActivityThread.java)at android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1583)android.os.Handler.dispatchMessage(Handler.java:102)at android.os.Looper.loop(Looper.java:154)at android.app.ActivityThread.main(ActivityThread.java:6121)at java.lang.reflect.Method.invoke(ネイティブメソッド)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:889) at com.android.internal.os.ZygoteInit.main(ZygoteInit .java:779)原因: [email protected] - 許可が拒否されました。 .java:703) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:342)でandroid.view.WindowManagerImpl.addView(WindowManagerImpl.java:93) でHeadService.TwoViewManager。(TwoViewManager.java:99) でHeadService.UIHeadService.onStartCommand(UIHeadService.java:65) アンドロイドで。 app.ActivityThread.handleServiceArgs(ActivityThread.java:3327) android.app.ActivityThread.-wrap21(ActivityThread.java)at android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1583) とandroid.osで.Handler.dispatchMessage(Handler.java:102)at android.os.Looper.loop(Looper.java:154)at android.app.ActivityThread.main(ActivityThread.java:6121)at java.lang.reflect .Method.invoke(Native Met) hod) com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:889) at com.android.internal.os.ZygoteInit.main(ZygoteInit。java:779)

+0

TYPE_APPLICATION_OVERLAYの実際の解決策を見つけましたか?私が理解しているところから、以下の答えのどれも実際に問題を解決するものはありません。それらのすべてが別のTYPEの使用を提案していました。 – HeyThere

+0

Oreoの前後で2つのタイプを使用する必要があるということは、受け入れられた答えと同じです。 – Derwrecked

答えて

10

私はまったく同じ問題を抱えていました。私はあなたが私が(前とマシュマロ後)サービスクラスでまったく同じ問題があった

int LAYOUT_FLAG; 
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 
    LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 
} else { 
     LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE; 
} 

params = new WindowManager.LayoutParams(
     WindowManager.LayoutParams.WRAP_CONTENT, 
     WindowManager.LayoutParams.WRAP_CONTENT, 
     LAYOUT_FLAG, 
     WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 
     PixelFormat.TRANSLUCENT); 
+0

私は結局解決策を書くつもりでしたが、それ! – Derwrecked

+0

私はこれを使うと、オーバーレイされたレイアウトとやりとりすることはできません。それ以外の方法はありますか? –

+0

それは働いています。しかし、私は.apkファイルをインストールするときにボタンをインストールすることはできません。どんな解決策ですか? – hungtdo

0

WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAYWindowManager.LayoutParams.TYPE_PHONEに変更してください。

+0

返信いただきありがとうございます!しかし、私が記事で言ったように、私は既にこの を回避策として使っていますが、このTYPE_PHONEはAndroid Oでは廃止されており、これはAndroid Oで最終的に動作するようにしたいと考えています。 – Derwrecked

0

あなたは以下のインテントを呼び出すことによってランタイム許可を要求しましたか?

private void requestOverlayPermission() { 
    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) { 
     return; 
    } 

    Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); 
    myIntent.setData(Uri.parse("package:" + getPackageName())); 
    startActivityForResult(myIntent, APP_PERMISSIONS); 
} 

その後でonActivityResult()かどうかをチェックしSettings.canDrawOverlays(これは)そうでない場合は上記の方法を呼び出すことにより、再び許可を求める真です。

0

Source SYSTEM_ALERT_WINDOW 文字列SYSTEM_ALERT_WINDOW すべての他のアプリの上に示され、式TYPE_APPLICATION_OVERLAYを使用してウィンドウを作成することをアプリに許可します。このアクセス許可を使用するアプリはほとんどありません。これらのウィンドウは、ユーザーとのシステムレベルの対話を目的としています。

注:アプリがAPIレベル23以上をターゲットにしている場合、アプリユーザーは権限管理画面を通じてこの権限をアプリに明示的に付与する必要があります。アプリはACTION_MANAGE_OVERLAY_PERMISSIONというアクションでインテントを送信してユーザーの承認を要求します。アプリは、この権限を持っているかどうかをSettings.canDrawOverlays()を呼び出して確認できます。

1
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 

(オレオの前と後に)ターゲットを区別する必要がありますね。

if (Build.VERSION.SDK_INT >= 23) { 
    if (!Settings.canDrawOverlays(this)) { 
     Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, 
      Uri.parse("package:" + getPackageName())); 
     startActivityForResult(intent, 1234); 
    } 
} else { 
    startService(new Intent(SplashActivity.this,      
    CheckServicesForApps.class)); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (requestCode == 1234) { 
      startService(new Intent(SplashActivity.this, 
      CheckServicesForApps.class)); 

    } 
} 

public class CheckServicesForApps extends Service { 
    private Context context = null; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     ImageView imageView = new ImageView(context); 
     imageView.setVisibility(View.GONE); 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
      try { 
       windowManager = (WindowManager)getSystemService(WINDOW_SERVICE); 

       //here is all the science of params 
       final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
         WindowManager.LayoutParams.WRAP_CONTENT, 
         WindowManager.LayoutParams.WRAP_CONTENT, 
         WindowManager. LayoutParams.TYPE_SYSTEM_ERROR, 
         WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 
           | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON 
           | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, 
         PixelFormat.TRANSLUCENT 
       ); 

       windowManager.addView(imageView, params); 
       hand=new Handler(); 

      } catch (Exception e) { 
       hand=new Handler(); 
       e.printStackTrace(); 
      } 
     }else{ 
      windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); 

      final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT, 
        WindowManager.LayoutParams.WRAP_CONTENT, 
        WindowManager.LayoutParams.TYPE_PHONE, 
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 
        PixelFormat.TRANSLUCENT); 

      params.gravity = Gravity.TOP | Gravity.CENTER; 
      params.x = ((getApplicationContext().getResources().getDisplayMetrics().widthPixels)/2); 
      params.y = ((getApplicationContext().getResources().getDisplayMetrics().heightPixels)/2); 
      windowManager.addView(imageView, params); 
     } 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     /* We want this service to continue running until it is explicitly 
     * stopped, so return sticky. 
     */ 
     return START_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 

     if (imageView != null) { 
      try { 
       windowManager.removeView(imageView); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
     /**** added to fix the bug of view not attached to window manager ****/ 
    } 
} 
+0