Android6.0(Android M) 懸浮窗被禁用,無許可權開啟懸浮窗的解決方案
阿新 • • 發佈:2019-02-18
最近需要在Android6.0的機子上實現一個懸浮窗的功能,發現6.0之前的機子都能使用懸浮窗,但是唯獨6.0版本不行,以下我是查到的相關資料,挺有意思的,順帶說一下:
國內查,所有的新聞統一都說是谷歌有意禁止該功能(預設關閉),且說不會妥協去修改,僅此而已,未找到相關的開發者解決方案。
國外查,尼瑪人家說這個android6.0的bug,在6.0.1之後會修復。。。。
WTF,那麼問題來了,本猿該信誰。。。。。。。。
Whatever,我要的是解決方案,直奔主題
——————————————————————————我是一條一本正經的分割線————————————————————————————
解決方案有兩種:
一是如果你做的是系統應用開發,只要給apk簽名,那麼預設懸浮窗許可權是給予的,顯然這種情況不符合大多數開發者的要求。
二是在開啟懸浮窗之前,引導使用者去開啟許可權,本博文重點介紹這種方法
許可權開啟的UI路徑是 “ 通用 -- 應用管理 -- 更多 -- 配置應用 --- 在其他應用的上層顯示 --- 選擇你的APP -- 執行在其他應用的上層顯示 ” >_< 藏得也是夠深的!!!
【步驟1】在AndroidManifest.xml中新增懸浮窗的許可權
【步驟2】Activity的編寫如下<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
package test.floatWin; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.provider.Settings; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Toast; import com.cxq.selftestdemo.R; public class TestFloatWinActivity extends AppCompatActivity { private static final String TAG = "TestFloatWinActivity"; public static int OVERLAY_PERMISSION_REQ_CODE = 1234; //開啟懸浮窗的Service Intent floatWinIntent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test_floatwin); floatWinIntent = new Intent(TestFloatWinActivity.this, FloatWinService.class); } /** * 按下begin按鈕 * * @param v */ public void begin(View v) { //開啟懸浮框前先請求許可權 askForPermission(); } /** * 按下end按鈕 * * @param v */ public void end(View v) { //關閉懸浮框 stopService(floatWinIntent); } /** * 請求使用者給予懸浮窗的許可權 */ public void askForPermission() { if (!Settings.canDrawOverlays(this)) { Toast.makeText(TestFloatWinActivity.this, "當前無許可權,請授權!", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE); } else { startService(floatWinIntent); } } /** * 使用者返回 * * @param requestCode * @param resultCode * @param data */ protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == OVERLAY_PERMISSION_REQ_CODE) { if (!Settings.canDrawOverlays(this)) { Toast.makeText(TestFloatWinActivity.this, "許可權授予失敗,無法開啟懸浮窗", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(TestFloatWinActivity.this, "許可權授予成功!", Toast.LENGTH_SHORT).show(); //啟動FxService startService(floatWinIntent); } } } @Override public void onDestroy() { super.onDestroy(); } }
大概解釋一下,Activity中有兩個Button,
一個Begin,對應方法是開啟懸浮窗,但是在開啟前回去檢測許可權,許可權有則直接執行懸浮框,沒有則直接跳轉到許可權請求頁面,引導使用者開啟
一個End,對應的方法是關閉懸浮窗
懸浮窗的開啟我是放在Service中的,Service開啟懸浮窗執行,Serive停止懸浮窗關閉,這點大家可以根據自己的需求去改。