安卓6.0版本下悬浮窗实现

悬浮窗在安卓中实现起来还是比较容易的,这几天在网上温习了相关资料,运行在我安卓6.0手机上才发现,原来在6.0手机上不是行的。
第一反应肯定是权限相关问题,做了相关处理后,果然让悬浮窗原形毕露了。直接贴代码。
public class MainActivity extends AppCompatActivity {
    private static final int ALERT_WINDOW_PERMISSION_CODE = 100;
    private Button start_float;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        start_float = (Button) findViewById(R.id.start_float);
        this.start_float.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Build.VERSION.SDK_INT > 22) {
                    sdk23Permission();
                } else {
                    startService(new Intent(MainActivity.this, FloatService.class));
                    finish();
                }
            }
        });
    }

    /**
     * @description 安卓6.0下权限处理
     * @author ldm
     * @time 2017/3/20 15:00
     */
    public void sdk23Permission() {
        if (!Settings.canDrawOverlays(this)) {
            Toast.makeText(MainActivity.this, "当前无权限使用悬浮窗,请授权!", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, ALERT_WINDOW_PERMISSION_CODE);
        } else {
            startService(new Intent(MainActivity.this, FloatService.class));
            finish();
        }
    }

    /**
     * 用户返回
     */
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == ALERT_WINDOW_PERMISSION_CODE) {
            if (!Settings.canDrawOverlays(this)) {
                Toast.makeText(MainActivity.this, "权限授予失败,无法开启悬浮窗", Toast.LENGTH_SHORT).show();
            } else {
                startService(new Intent(MainActivity.this, FloatService.class));
                finish();
            }

        }
    }
}

对应Service:

public class FloatService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        FloatViewUtils.getInstance(this).addFloatView();
        super.onCreate();
    }
}

简单地FloatView:

public class FloatView extends View {
    public static final int WIDTH = 150;
    public static final int HEIGHT = 150;
    private Paint circlePaint;
    private Paint textPaint;
    private static final String text = "50%";

    public FloatView(Context context) {
        this(context, null, 0);
    }

    public FloatView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FloatView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaints();
    }

    /**
     * @description 初始化相关画笔Paint
     * @author ldm
     * @time 2017/3/20
     */
    private void initPaints() {
        circlePaint = new Paint();
        circlePaint.setAntiAlias(true);
        circlePaint.setColor(Color.GRAY);
        textPaint = new Paint();
        //设置抗锯齿
        textPaint.setAntiAlias(true);
        //设置字体大小
        textPaint.setTextSize(30);
        //设置颜色
        textPaint.setColor(Color.WHITE);
        //设置(仿)粗体
        textPaint.setFakeBoldText(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(WIDTH, HEIGHT);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(WIDTH / 2, HEIGHT / 2, WIDTH / 2, circlePaint);
        float textWidth = textPaint.measureText(text);
        float x = WIDTH / 2 - textWidth / 2;
        Paint.FontMetrics fms = textPaint.getFontMetrics();
        float dy = -(fms.descent + fms.ascent) / 2;
        float y = HEIGHT / 2 + dy;
        canvas.drawText(text, x, y, textPaint);
    }
}

以及FloatView管理工具类:

public class FloatViewUtils {
    private static FloatViewUtils instance;
    private Context mContext;
    private WindowManager manager;
    private FloatView floatView;

    private FloatViewUtils(Context mContext) {
        this.mContext = mContext;
        manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        floatView = new FloatView(mContext);
    }

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

    public void addFloatView() {
        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
        //悬浮窗口大小
        lp.width = floatView.WIDTH;
        lp.height = floatView.HEIGHT;
        // 调整悬浮窗口位置
        lp.gravity = Gravity.LEFT | Gravity.CENTER;
        // 以屏幕左上角为原点,设置x、y初始值
//        lp.x = 0;
//        lp.y = 0;
        //设置悬浮窗口类型
        lp.type = WindowManager.LayoutParams.TYPE_PHONE;
        //设置悬浮窗口不接受焦点及触摸事件
        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
        //设置图片格式,效果为背景透明
        lp.format = PixelFormat.RGBA_8888;
        manager.addView(floatView, lp);
    }
}

最后不要忘记在AndroidManifest.xml中添加权限(当然还有注册Service):

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值