Android浮窗小球的特殊权限申请的变动和解决

制作浮窗小球:
步骤1:浮窗管理者创建(单例)
* a.私有化构造函数
* b.创建静态的返回浮窗管理类的方法。
*
* 步骤2:浮窗球小球的制作(自定义控件)
* a.onMeasure确定该控件或子控件的大小
* b.onLayout确定该控件及子控件在父窗体中的位置
* c.onDraw绘制该控件的内容
*
* 步骤3:显示浮窗小球(Window Manager)
* a.addView()向当前的手机窗口界面添加view
* b.removeView()从当前的窗体上移除View
* c.updateviewLayout()刷新当前View的显示

问题描述:

 按照以前的写法:用

TYPE_PHONE和<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>会报错:
AndroidRuntime: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@c8d1f1a -- permission denied for window type 2002
* 后面的2002表示设置的type为TYPE_PHONE


解决方法:(对于Android O之后

1。注册文件中声明权限:

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

2.将windowmanager的addview()中的params参数中的type改为如下:

WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

“TYPE_APPLICATION_OVERLAY”是重点

如果不设置该TYPE,应用会Crash。

3.申请android.permission.SYSTEM_ALERT_WINDOW(该权限不能使用 requestPermissions 方法。)

  if (! Settings.canDrawOverlays(MainActivity.this)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent,10);
        }

@RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (requestCode == 10) {
            if (!Settings.canDrawOverlays(this)) {
                // SYSTEM_ALERT_WINDOW permission not granted...
                Toast.makeText(MainActivity.this,"not granted",Toast.LENGTH_SHORT);
            }
        }
    }

然后运行app,按照下图勾选后返回即可看见浮窗。

 
  
 

1.Windowmanager配置:

扫描二维码关注公众号,回复: 8743423 查看本文章
package com.yinlei.jiasuqiu.engine;

import android.content.Context;
import android.graphics.PixelFormat;
import android.view.Gravity;
import android.view.WindowManager;

import com.yinlei.jiasuqiu.view.FloatCircleView;

/**
* @date on 2019/6/22
* @author Yinlei
* @packagename
* @email [email protected]
* @describe 浮窗管理者创建.
 * 记得在清单文件中声明权限:
 *     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
 *
 *     报错:AndroidRuntime: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@c8d1f1a -- permission denied for window type 2002
 * 后面的2002表示设置的type为TYPE_PHONE
 *     危险权限需要动态申请
*/
public class FloatViewManager {
    private  Context context;
    private  WindowManager wm;//通过这个WindowManager来操控父窗体的显示和隐藏以及位置的改变
    private FloatCircleView circleView;//自定义浮窗小球view

    private FloatViewManager(Context context){
        this.context = context;
         wm= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

         circleView=new FloatCircleView(context);
    }

    private static FloatViewManager instance;

    public  static  FloatViewManager getInstance(Context context){
        if(instance ==null){
            synchronized (FloatViewManager.class){
                if(instance ==null){
                    instance = new FloatViewManager(context);
                }
            }
        }
        return instance;
    }


    /**
     * 展示浮窗小球到窗口上
     */
    public void showFloatCircleView(){
        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.width=circleView.width;
        params.height=circleView.height;
        params.gravity= Gravity.TOP|Gravity.LEFT;
        params.x=0;
        params.y=0;
        //以悬浮在其他应用上的权限展示。因为打电话是悬浮在其他应用上的。用此type即可。
        params.type= WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
//        params.type= WindowManager.LayoutParams.TYPE_PHONE;
        //不去抢焦点
        params.flags= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
        params.format= PixelFormat.RGBA_8888;

        wm.addView(circleView,params);
    }
}

2.相关浮窗小球的配置代码如下:(简易版)

package com.yinlei.jiasuqiu.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* @date on 2019/6/22
* @author Yinlei
* @packagename
* @email [email protected]
* @describe 浮窗球小球的制作.
*/
public class FloatCircleView extends View {
    public int width = 150;
    public int height = 150;

    Paint  circlePaint;
    Paint textPaint;
    private String text = "50%";

    public FloatCircleView(Context context) {
        super(context);
        initPaints();
    }

    public FloatCircleView(Context context, @Nullable AttributeSet attrs) {//AttributeSet表示自定义属性在attr.xml中
        super(context, attrs);
        initPaints();
    }

    public FloatCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {//defStyleAttr表示在xml布局文件中
        super(context, attrs, defStyleAttr);
        initPaints();
    }

    private void initPaints() {
          circlePaint = new Paint();
        circlePaint.setColor(Color.GRAY);
        circlePaint.setAntiAlias(true);

         textPaint = new Paint();
        textPaint.setTextSize(25);
        textPaint.setColor(Color.WHITE);
        textPaint.setAntiAlias(true);
        textPaint.setFakeBoldText(true);
    }

//    public FloatCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
//        super(context, attrs, defStyleAttr, defStyleRes);
//    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(width,height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawCircle(width/2,height/2,width/2,circlePaint);
        float textWidth=textPaint.measureText(text);
        float x = width/2-textWidth/2;
        //考虑基线base line
        Paint.FontMetrics metrics = textPaint.getFontMetrics();
        float dy = (metrics.descent+metrics.ascent)/2;
        float y = height/2+dy;
        canvas.drawText(text,x,y,textPaint);
    }
}
发布了268 篇原创文章 · 获赞 36 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_39969226/article/details/93317320