无法添加窗口android.view.ViewRootImpl$W@5ccfc1d-窗口类型为2002

时间:2019-03-05 10:41:53

标签: java android xml

我想制作一个浮动动作按钮,例如facebook Messenger按钮,该按钮可以覆盖其他应用程序并执行特定的工作,我在清单中获得了许可,但该应用程序仍然崩溃。

清单权限

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"> 
 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:name=".view_model.FloatImage"
        android:theme="@style/AppTheme">

        <activity
            android:name=".view.MainActivity"
            android:label="@string/title_activity_main"
            android:theme="@style/AppTheme.NoActionBar">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>

        <service android:name=".model.FloatingCircle" />


    </application>

</manifest>

这是我的浮动按钮课程

   public void onCreate() {
    super.onCreate();
    initializeView();
    getScreenSize();
    showFloat();
}

@SuppressLint("ClickableViewAccessibility")
private void showFloat() {
    _closeParams = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);

    _closeParams.gravity = Gravity.BOTTOM | Gravity.CENTER;
    _closeParams.x = 0;
    _closeParams.y = 100;


    myParams = new WindowManager.LayoutParams(
            (int) (0.18 * screen_width),
            (int) (0.18 * screen_width),
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT
    );

    myParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
    myParams.x = screen_width / 2; // horizontal center for the image
    myParams.y = 0;
    //   myParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

    if (Build.VERSION.SDK_INT >= 23) {
        if (Settings.canDrawOverlays(context)) {

            if (!smallCircle.isShown()) {
                windowManager.addView(smallCircle, myParams);
                windowManagerClose.addView(layout, _closeParams);
                layout.setVisibility(View.INVISIBLE);
                close.startAnimation(shake);


            }
        }


    } else {

        if (!smallCircle.isShown()) {
            windowManager.addView(smallCircle, myParams);
            windowManagerClose.addView(layout, _closeParams);
            layout.setVisibility(View.INVISIBLE);
            close.startAnimation(shake);

        }
    }


    try {
        // for moving the picture on touch and slide
        smallCircle.setOnTouchListener(new View.OnTouchListener() {
            public WindowManager.LayoutParams myParams2;
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;

            @Override
            public boolean onTouch(View v, final MotionEvent event) {

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        initialX = myParams.x;
                        initialY = myParams.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        animator.stop();
                        break;
                    case MotionEvent.ACTION_UP:
                        if (MathUtil.betweenExclusive(myParams.x, -100, 100) && !MathUtil.betweenExclusive(myParams.y, screen_height / 3, screen_height / 2)) {
                            //moving to center range of screen


                            animator.start(screen_width / 2, myParams.y);
                            android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                            layoutParams.width = (int) (0.18 * screen_width);
                            layoutParams.height = (int) (0.18 * screen_width);
                            smallCircle.setLayoutParams(layoutParams);
                            windowManager.updateViewLayout(v, myParams);
                            layout.setVisibility(View.INVISIBLE);


                        } else if (MathUtil.betweenExclusive((int) event.getRawX(), 0, screen_width / 5)) {
                            //move to left of screen

                            if (MathUtil.betweenExclusive((int) event.getRawY(), 0, screen_height / 10)) {

                                // myParams.y = 0 ;
                                animator.start(-screen_width / 2, -((screen_height / 2) - 150));
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            } else if (MathUtil.betweenExclusive((int) event.getRawY(), 9 * (screen_height / 10), screen_height)) {
                                animator.start(-screen_width / 2, screen_height / 2 - 150);
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            } else {
                                animator.start(-screen_width / 2, myParams.y);
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            }

                        } else if (MathUtil.betweenExclusive((int) event.getRawX(), screen_width - (screen_width / 5), screen_width)) {
                            //move to right of screen

                            if (MathUtil.betweenExclusive((int) event.getRawY(), 0, screen_height / 10)) {

                                // myParams.y = 0 ;
                                animator.start(screen_width / 2, -((screen_height / 2) - 150));
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            } else if (MathUtil.betweenExclusive((int) event.getRawY(), 9 * (screen_height / 10), screen_height)) {
                                animator.start(screen_width / 2, screen_height / 2 - 150);
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            } else {
                                animator.start(screen_width / 2, myParams.y);
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            }

                        } else if (MathUtil.betweenExclusive((int) event.getRawX(), screen_width / 5, 2 * (screen_width / 5))) {
                            //move to left of screen
                            if (MathUtil.betweenExclusive((int) event.getRawY(), 0, screen_height / 10)) {


                                animator.start(-screen_width / 2, -((screen_height / 2) - 150));
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            } else if (MathUtil.betweenExclusive((int) event.getRawY(), 9 * (screen_height / 10), screen_height)) {
                                animator.start(-screen_width / 2, screen_height / 2 - 150);
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            } else {
                                animator.start(-screen_width / 2, myParams.y);
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            }
                        } else if (MathUtil.betweenExclusive((int) event.getRawX(), 3 * (screen_width / 5), screen_width)) {
                            //move to right of screen
                            if (MathUtil.betweenExclusive((int) event.getRawY(), 0, screen_height / 10)) {

                                // myParams.y = 0 ;
                                animator.start(screen_width / 2, -((screen_height / 2) - 150));
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            } else if (MathUtil.betweenExclusive((int) event.getRawY(), 9 * (screen_height / 10), screen_height)) {
                                animator.start(screen_width / 2, screen_height / 2 - 150);
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            } else {
                                animator.start(screen_width / 2, myParams.y);
                                android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                                layoutParams.width = (int) (0.18 * screen_width);
                                layoutParams.height = (int) (0.18 * screen_width);
                                smallCircle.setLayoutParams(layoutParams);
                                windowManager.updateViewLayout(v, myParams);
                                layout.setVisibility(View.INVISIBLE);
                            }
                        } else if (MathUtil.betweenExclusive(myParams.x, -50, 50) && MathUtil.betweenExclusive(myParams.y, screen_height / 3, screen_height / 2)) {

                            Visibility();
                            stopSelf();


                        } else {

                            //not in either of the above cases
                            animator.start(screen_width / 2, myParams.y);
                            android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                            layoutParams.width = (int) (0.18 * screen_width);
                            layoutParams.height = (int) (0.18 * screen_width);
                            smallCircle.setLayoutParams(layoutParams);
                            windowManager.updateViewLayout(v, myParams);
                            layout.setVisibility(View.INVISIBLE);

                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        layout.setVisibility(View.VISIBLE);
                        myParams.x = initialX + (int) (event.getRawX() - initialTouchX);
                        myParams.y = initialY + (int) (event.getRawY() - initialTouchY);
                        windowManager.updateViewLayout(v, myParams);
                        if (MathUtil.betweenExclusive((int) event.getRawX(), 0, screen_width / 5) || MathUtil.betweenExclusive((int) event.getRawX(), screen_width - (screen_width / 5), screen_width)) {
                            android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                            layoutParams.width = (int) (0.18 * screen_width);
                            layoutParams.height = (int) (0.18 * screen_width);
                            smallCircle.setLayoutParams(layoutParams);
                            windowManager.updateViewLayout(v, myParams);
                        } else if (MathUtil.betweenExclusive((int) event.getRawX(), 2 * (screen_width / 5), 3 * (screen_width / 5))) {
                            android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                            layoutParams.width = (int) (0.18 * screen_width) + 100 + 100;
                            layoutParams.height = (int) (0.18 * screen_width) + 100 + 100;
                            smallCircle.setLayoutParams(layoutParams);
                            windowManager.updateViewLayout(v, myParams);
                        } else if (MathUtil.betweenExclusive((int) event.getRawX(), screen_width / 5, 2 * (screen_width / 5)) || MathUtil.betweenExclusive((int) event.getRawX(), 3 * (screen_width / 5), screen_width)) {
                            android.view.ViewGroup.LayoutParams layoutParams = smallCircle.getLayoutParams();
                            layoutParams.width = (int) (0.18 * screen_width) + 100;
                            layoutParams.height = (int) (0.18 * screen_width) + 100;
                            smallCircle.setLayoutParams(layoutParams);
                            windowManager.updateViewLayout(v, myParams);
                        }


                        break;
                }
                return true;

            }

        });

    } catch (Exception e) {

    }

}

private void Visibility() {
    if (windowManager != null) {
        windowManager.removeViewImmediate(smallCircle);
        windowManagerClose.removeViewImmediate(layout);
    }
}

private void initializeView() {
    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    windowManagerClose = (WindowManager) getSystemService(WINDOW_SERVICE);
    smallCircle = new ImageView(this);
    smallCircle.setImageResource(R.mipmap.dummy);
    close = new ImageView(this);
    close.setImageResource(R.mipmap._close);
    context = FloatingCircle.this;
    shake = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.wiggle);
    shake.setRepeatCount(Animation.INFINITE);
    layout = new LinearLayout(this);
    layout.addView(close);
    animator = new MoveAnimator();
}

private void getScreenSize() {
    Display display = windowManager.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    screen_width = size.x;
    screen_height = size.y;

}

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

private static class MathUtil {
    public static boolean betweenExclusive(int x, int min, int max) {
        return x > min && x < max;
    }
}


//this class is written to move the image to either corners if touch_up
private class MoveAnimator implements Runnable {

    private Handler handler = new Handler(Looper.getMainLooper());
    private float destinationX;
    private float destinationY;
    private long startingTime;

    private void start(float x, float y) {
        this.destinationX = x;
        this.destinationY = y;
        startingTime = System.currentTimeMillis();
        handler.post(this);
    }

    @Override
    public void run() {
        if (smallCircle != null && smallCircle.getParent() != null) {
            float progress = Math.min(1, (System.currentTimeMillis() - startingTime) / 400f);

            float deltaX = (destinationX - myParams.x) * progress;
            float deltaY = (destinationY - myParams.y) * progress;
            move(deltaX, deltaY);
            if (progress < 1) {
                handler.post(this);
            }
        }
    }

    private void stop() {
        handler.removeCallbacks(this);
    }
}

protected void move(float deltaX, float deltaY) {
    myParams.x += deltaX;
    myParams.y += deltaY;
    windowManager.updateViewLayout(smallCircle, myParams);
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Visibility();
    _closeParams = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);
    _closeParams.gravity = Gravity.BOTTOM | Gravity.CENTER;
    _closeParams.x = 0;
    _closeParams.y = 100;


    myParams = new WindowManager.LayoutParams(
            (int) (0.18 * screen_width),
            (int) (0.18 * screen_width),
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT
    );

    myParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
    myParams.x = screen_width / 2; // horizontal center for the image
    myParams.y = 0;
    windowManager.addView(smallCircle, myParams);


    windowManagerClose.addView(layout, _closeParams);
    layout.setVisibility(View.INVISIBLE);
    close.startAnimation(shake);

    return START_STICKY; //system will try to recreate the service if in case its killed
}

这是我的主要活动

        FloatingActionButton fab = findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void onClick(View view) {
            //add the service here
            //make the button gone

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

        }
    });

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
        startService(new Intent(context, FloatingCircle.class));

    }
}

这是我的Logcat错误

  

2019-03-05 15:45:19.086 31841-31851 /? E / zygote64:发送失败   回复调试器:管道损坏       2019-03-05 15:45:20.401 31841-31841 / com.anam.floatimage E / WindowManager:BadTokenException或InvalidDisplayException,干净   起来       2019-03-05 15:45:20.403 31841-31841 / com.anam.floatimage E / Android运行时:致命异常:主要           流程:com.anam.floatimage,PID:31841           java.lang.RuntimeException:无法创建服务com.anam.floatimage.model.FloatingCircle:   android.view.WindowManager $ BadTokenException:无法添加窗口   android.view.ViewRootImpl$W@5ccfc1d-窗口权限被拒绝   2002型               在android.app.ActivityThread.handleCreateService(ActivityThread.java:3385)               在android.app.ActivityThread.-wrap4(未知来源:0)               在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1703)               在android.os.Handler.dispatchMessage(Handler.java:106)               在android.os.Looper.loop(Looper.java:176)               在android.app.ActivityThread.main(ActivityThread.java:6635)               在java.lang.reflect.Method.invoke(本机方法)               在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:547)               在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)            原因:android.view.WindowManager $ BadTokenException:无法添加窗口android.view.ViewRootImpl$W@5ccfc1d-权限   窗口类型2002拒绝               在android.view.ViewRootImpl.setView(ViewRootImpl.java:820)               在android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)               在android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)               在com.anam.floatimage.model.FloatingCircle.showFloat(FloatingCircle.java:86)               在com.anam.floatimage.model.FloatingCircle.onCreate(FloatingCircle.java:50)               在android.app.ActivityThread.handleCreateService(ActivityThread.java:3375)               在android.app.ActivityThread.-wrap4(未知来源:0)               在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1703)               在android.os.Handler.dispatchMessage(Handler.java:106)               在android.os.Looper.loop(Looper.java:176)               在android.app.ActivityThread.main(ActivityThread.java:6635)               在java.lang.reflect.Method.invoke(本机方法)               在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:547)               在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)

0 个答案:

没有答案