Android6.0(Android M) 悬浮窗被禁用,无权限开启悬浮窗的解决方案

来源:互联网 发布:爽肤水推荐知乎 编辑:程序博客网 时间:2024/05/16 23:43

最近需要在Android6.0的机子上实现一个悬浮窗的功能,发现6.0之前的机子都能使用悬浮窗,但是唯独6.0版本不行,以下我是查到的相关资料,挺有意思的,顺带说一下:

国内查,所有的新闻统一都说是谷歌有意禁止该功能(默认关闭),且说不会妥协去修改,仅此而已,未找到相关的开发者解决方案。

国外查,尼玛人家说这个android6.0的bug,在6.0.1之后会修复。。。。

WTF,那么问题来了,本猿该信谁。。。。。。。。

Whatever,我要的是解决方案,直奔主题

——————————————————————————我是一条一本正经的分割线————————————————————————————

解决方案有两种:

一是如果你做的是系统应用开发,只要给apk签名,那么默认悬浮窗权限是给予的,显然这种情况不符合大多数开发者的要求。

二是在开启悬浮窗之前,引导用户去开启权限,本博文重点介绍这种方法

权限开启的UI路径是 “ 通用 -- 应用管理 -- 更多 -- 配置应用 --- 在其他应用的上层显示 --- 选择你的APP -- 运行在其他应用的上层显示 ”  >_< 藏得也是够深的!!!


【步骤1】在AndroidManifest.xml中添加悬浮窗的权限

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />  


【步骤2】Activity的编写如下


[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package test.floatWin;  
  2.   
  3. import android.content.Intent;  
  4. import android.net.Uri;  
  5. import android.os.Bundle;  
  6. import android.provider.Settings;  
  7. import android.support.v7.app.AppCompatActivity;  
  8. import android.view.View;  
  9. import android.widget.Toast;  
  10.   
  11. import com.cxq.selftestdemo.R;  
  12.   
  13. public class TestFloatWinActivity extends AppCompatActivity {  
  14.   
  15.     private static final String TAG = "TestFloatWinActivity";  
  16.     public static int OVERLAY_PERMISSION_REQ_CODE = 1234;  
  17.     //开启悬浮窗的Service  
  18.     Intent floatWinIntent;  
  19.   
  20.     @Override  
  21.     protected void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.activity_test_floatwin);  
  24.         floatWinIntent = new Intent(TestFloatWinActivity.this, FloatWinService.class);  
  25.     }  
  26.   
  27.     /** 
  28.      * 按下begin按钮 
  29.      * 
  30.      * @param v 
  31.      */  
  32.     public void begin(View v) {  
  33.         //开启悬浮框前先请求权限  
  34.         askForPermission();  
  35.     }  
  36.   
  37.     /** 
  38.      * 按下end按钮 
  39.      * 
  40.      * @param v 
  41.      */  
  42.     public void end(View v) {  
  43.         //关闭悬浮框  
  44.         stopService(floatWinIntent);  
  45.     }  
  46.   
  47.   
  48.     /** 
  49.      * 请求用户给予悬浮窗的权限 
  50.      */  
  51.     public void askForPermission() {  
  52.         if (!Settings.canDrawOverlays(this)) {  
  53.             Toast.makeText(TestFloatWinActivity.this"当前无权限,请授权!", Toast.LENGTH_SHORT).show();  
  54.             Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,  
  55.                     Uri.parse("package:" + getPackageName()));  
  56.             startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);  
  57.         } else {  
  58.             startService(floatWinIntent);  
  59.         }  
  60.     }  
  61.   
  62.     /** 
  63.      * 用户返回 
  64.      * 
  65.      * @param requestCode 
  66.      * @param resultCode 
  67.      * @param data 
  68.      */  
  69.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  70.         if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {  
  71.             if (!Settings.canDrawOverlays(this)) {  
  72.                 Toast.makeText(TestFloatWinActivity.this"权限授予失败,无法开启悬浮窗", Toast.LENGTH_SHORT).show();  
  73.             } else {  
  74.                 Toast.makeText(TestFloatWinActivity.this"权限授予成功!", Toast.LENGTH_SHORT).show();  
  75.                 //启动FxService  
  76.                 startService(floatWinIntent);  
  77.             }  
  78.   
  79.         }  
  80.     }  
  81.   
  82.     @Override  
  83.     public void onDestroy() {  
  84.         super.onDestroy();  
  85.     }  
  86. }  

大概解释一下,Activity中有两个Button,

一个Begin,对应方法是开启悬浮窗,但是在开启前回去检测权限,权限有则直接运行悬浮框,没有则直接跳转到权限请求页面,引导用户开启

一个End,对应的方法是关闭悬浮窗


悬浮窗的开启我是放在Service中的,Service开启悬浮窗运行,Serive停止悬浮窗关闭,这点大家可以根据自己的需求去改。

0 0