Android M及以上版本系统 悬浮窗权限 的解决方案

 

Android的窗口体系中,WindowManager占有非常重要的地位,平时我们使用悬浮窗会遇到一些权限的问题。
当 Android工程在
targetSdkVersion 23
编译,Android6.0及其以上版本手机使用悬浮窗功能时候,会发生如下的异常,导致程序崩溃。

java.lang.RuntimeException: Unable to create service com.fb.tangyc.fbtools.service.FBService: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@123e0ab -- permission denied for this window type


当Android工程在
targetSdkVersion 22
编译,Android6.0及其以上版本手机使用悬浮窗功能会正常使用
其实原因很简单,大部分的Android6.0手机(尤其是三星,谷歌原生手机)
在大于等于23版本下编译,悬浮窗权限默认是关闭没有权限,然在小于23版本下编译悬浮窗权限是开启有权限的。
所以在大于23版本下编译时需要去检测悬浮窗权限,并且获取悬浮窗权限,下面我就罗列下怎么去检测悬浮窗权限并且获取悬浮窗权限

if ( Build.VERSION.SDK_INT> = 23 ) {       if (Settings.canDrawOverlays(this)) {           //有悬浮窗权限开启服务绑定 绑定权限           Intent intent = new Intent(MainActivity.this, MyService.class);           startService(intent);       } else {           //没有悬浮窗权限m,去开启悬浮窗权限           try {                   Intent  intent=new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);             startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);           } catch (Exception e) {               e.printStackTrace();           }       }} else {    // 默认有悬浮窗权限  但是 华为, 小米,oppo 等手机会有自己的一套 Android6.0 以下      // 会有自己的一套悬浮窗权限管理 也需要做适配    Intent intent = new Intent(MainActivity.this, MyService.class);    startService(intent);}    

每次使用悬浮窗的时候都要去检测权限,因为悬浮窗权限是可以手动关闭的。
位置位于 (三星S6为例Android6.0.1版本)设置-- 应用程序--应用程序管理器 -- 更多 --可出现在顶部的应用程序 --- 选择你的APP -- 运行在其他应用的上层显示

 

 

下图所示:

Android M及以上版本系统 悬浮窗权限 的解决方案_第1张图片

 

当你点击悬浮窗权限app开关时候 退出 会在activity 有回调方法。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {    if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {        if(Build.VERSION.SDK_INT>=23) {            if (!Settings.canDrawOverlays(this)) {                Toast.makeText(this, "权限授予失败,无法开启悬浮窗", Toast.LENGTH_SHORT).show();            } else {                       Toast.makeText(this, "权限授予成功!", Toast.LENGTH_SHORT).show();               //有悬浮窗权限开启服务绑定 绑定权限                Intent intent = new Intent(MainActivity.this, FBService.class);                startService(intent);            }        }    }}

下面就罗列下Service中启动悬浮的实现
首先 你需要在配置文件悬浮窗权限

第二需要在服务中开启悬浮窗

public class FBService extends Service  {    private WindowManager wManager;// 窗口管理者    private WindowManager.LayoutParams mParams;// 窗口的属性    private FloatButtonLayout windowView;    private SurfaceHolder holder;    public static final String *ACTION_ALPHA *= "com.fb.alpha";    private ServiceReceiver receiver;    @Override    public void onCreate() {        super.onCreate();        wManager = (WindowManager) getSystemService(Context.*WINDOW_SERVICE*);        mParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.*TYPE_SYSTEM_ERROR*, WindowManager.LayoutParams.*FLAG_NOT_FOCUSABLE*, PixelFormat.*TRANSPARENT*);        mParams.type = WindowManager.LayoutParams.*TYPE_SYSTEM_ERROR*;// 系统提示window        mParams.format = PixelFormat.*TRANSLUCENT*;// 支持透明        // mParams.format = PixelFormat.RGBA_8888;        mParams.flags |= WindowManager.LayoutParams.*FLAG_NOT_TOUCH_MODAL *| WindowManager.LayoutParams.*FLAG_NOT_FOCUSABLE*;// 焦点        mParams.width = WindowManager.LayoutParams.*WRAP_CONTENT*;// 窗口的宽和高        mParams.height = WindowManager.LayoutParams.*WRAP_CONTENT*;        mParams.gravity = Gravity.*LEFT *| Gravity.*TOP*;        mParams.y = SharedPreferencesUtils.*getSharedPreferencesUtils*().getParamsY(getApplicationContext());        mParams.x = SharedPreferencesUtils.*getSharedPreferencesUtils*().getParamsX(getApplicationContext());        mParams.windowAnimations = android.R.style.*Animation_Toast*;        // mParams.alpha = 0.8f;//窗口的透明度        LayoutInflater layoutInflater = LayoutInflater.*from*(getApplicationContext());        windowView = (FloatButtonLayout) layoutInflater.inflate(R.layout.*float_button_layout*, null);        wManager.addView(windowView, mParams);// 添加窗口          }       

第三,关闭服务时候,关闭悬浮窗

@Overridepublic void onDestroy() {    if (wManager!=null&&windowView != null) {            wManager.removeView(windowView);    }    super.onDestroy();}

这就是在Android下面开启悬浮窗权限的全部流程。

更多相关文章

  1. android sdk 各个版本的区别
  2. Android(2)—Mono For Android App版本自动更新
  3. Android系统中的ROOT和System权限的区别
  4. 一个轻量级、高可用性的 Android 版本更新框架
  5. Android老版本项目导入到新版SDK提示错误
  6. android boot.img 拆包,修改adb 具有root权限,以i9250为例

随机推荐

  1. centos 磁盘管理与维护
  2. 【前端词典】arr.filter(parseInt) 考查
  3. 这些有趣的 API 着实有点炫
  4. 关于 刚刚放假在家准备认真学习的自我保
  5. 学习C第二天-转义字符
  6. 自己能挖到比特币吗?比特币到底有多香?
  7. flask示例
  8. C#基础入门第十二天(面向对象多态,File操作
  9. JavaWeb-LayUI框架的介绍与使用方式(前端
  10. 服务器Tomcat,你会安装了吗?