代码之家  ›  专栏  ›  技术社区  ›  Derwrecked

Android:使用type\u APPLICATION\u覆盖拒绝2038窗口类型的权限

  •  20
  • Derwrecked  · 技术社区  · 7 年前

    我试图创建一个高于其他应用程序的视图:

    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);
    

    安卓看法WindowManager$BadTokenException:无法添加窗口 2038 at型 在安卓。应用程序。活动线程-wrap21(ActivityThread.java)位于 安卓应用程序。ActivityThread$H.handleMessage(ActivityThread.java:1583) 在安卓。操作系统。处理程序。dispatchMessage(Handler.java:102)位于 安卓应用程序。活动线程。main(ActivityThread.java:6121)位于 Java语言郎。反思。方法调用(本机方法) 作者:安卓。看法WindowManager$BadTokenException:无法添加窗口 安卓看法ViewRootImpl$W@1f47e89--拒绝对窗口的权限 在 在安卓。看法WindowManagerImpl。addView(WindowManagerImpl.java:93) 在 头服务。TwoViewManager。(TwoViewManager.java:99) 在 头服务。UIHeadService。onStartCommand(UIHeadService.java:65) 安卓应用程序。活动线程。handleServiceArgs(ActivityThread.java:3327) 在安卓。应用程序。活动线程-wrap21(ActivityThread.java)位于 在安卓。操作系统。处理程序。dispatchMessage(Handler.java:102)位于 安卓操作系统。活套。循环(Looper.java:154) Java语言郎。反思。方法调用(本机方法) 通用域名格式。安卓内部的操作系统。ZygoteInit$MethodandArgscaler。运行(ZygoteInit.java:889) 在com。安卓内部的操作系统。合子岩。main(ZygoteInit.java:779)

    6 回复  |  直到 7 年前
        1
  •  44
  •   Cédric Dufouil    7 年前

    我也有同样的问题。我想你应该区分目标(奥利奥前后)

    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);
    
        2
  •  12
  •   dieterxu Varalakshmi Ganta    7 年前
    <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 ****/
        }
    }
    
        3
  •  6
  •   bikram    7 年前

    您是否通过调用以下意图请求运行时权限?

    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() 检查是否设置。canDrawOverlays(this)为true,否则通过调用上述方法再次请求权限。

        4
  •  1
  •   VNY    7 年前

    Source 允许应用程序使用type type\u APPLICATION\u覆盖创建窗口,显示在所有其他应用程序的顶部。很少有应用程序应该使用此权限;这些窗口旨在与用户进行系统级交互。

    注意:如果应用程序的目标API级别为23或更高,则应用程序用户必须通过权限管理屏幕向应用程序明确授予此权限。应用程序通过发送带有action action\u MANAGE\u OVERLAY\u权限的意向来请求用户批准。应用程序可以通过调用设置来检查是否具有此授权。canDrawOverlays()。

        5
  •  1
  •   wendjia    5 年前
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        }else {
            layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
        }
    
        6
  •  0
  •   hungr    7 年前

    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY WindowManager.LayoutParams.TYPE_PHONE