2017-09-14 97 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(本)檢查其自帶 回。
  • 我已經做了這裏permission denied for window type

位於一切我仍然得到「 - 否認窗式2038權限」的錯誤。到目前爲止,我正在使用TYPE_PHONE並且它可以工作,但它已被棄用,並聲稱使用TYPE_APPLICATION_OVERLAY。可有一個人跟進以此爲TYPE_PHONE答案是不是真正的分辨率但採用的是Android O.

棄用

一個「拼補」的解決方案,我在Android 7.1.2

運行Android。 view.WindowManager $ BadTokenException:無法添加窗口 [email protected] - 權限被拒絕窗口 類型2038在 android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3344) at android.app .ActivityThread.-wrap21(ActivityThread.java)at android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1583) 在android.os.Handler.dispatchMessage(Handler.java:102)在 android.os.Looper.loop(Looper.java:154)在 android.app.ActivityThread.main(ActivityThread.java:6121)在 java.lang.reflect.Method.invoke(Native Method)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:889) at com.android.internal.os.ZygoteInit.main(ZygoteInit .java:779)引起 作者:android.view.WindowManager $ BadTokenException:無法添加窗口 [email protected] - 權限被拒絕窗口 類型2038 at android.view.ViewRootImpl.setView(ViewRootImpl .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)在 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)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:889) at com.android.internal.os.ZygoteInit.main(ZygoteInit。java:779)

+0

只是好奇你是否找到了TYPE_APPLICATION_OVERLAY的實際解決方案?根據我的理解,下面的答案都沒有真正解決這個問題。他們都建議使用另一種類型。 – HeyThere

+0

這是因爲接受的答案描述你必須考慮到奧利奧之前和之後,即你將使用兩種類型。 – 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

TYPE_PHONE它的工作。但是當安裝.apk文件時,我無法獲取安裝按鈕。任何解決方案 – hungtdo

0

嘗試將WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY更改爲WindowManager.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

<使用權限android:name =「android.permission.SYSTEM_ALERT_WINDOW」/> –