2017年2月20日 星期一

Android 6.0+ 請求 SYSTEM_ALERT_WINDOW權限

Reference:

http://stackoverflow.com/questions/32652533/android-system-overlay-window
http://caiyao.name/2016/03/02/Android-6-0%E8%BF%90%E8%A1%8C%E6%97%B6%E6%9D%83%E9%99%90%E5%B0%8F%E7%BB%93/

Error message:

Unable to add window android.view.ViewRoot$W@XXXXXXXX — permission denied for this window type


Code snippet:

在 Android 6.0+ (SDK 23+) 用 TYPE_SYSTEM_ALERT,即使在 Manifest裡有宣告 permission
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
依舊會出現上面的 Error message.
這時候要先透過 Settings.canDrawOverlays檢查 app是否有權限,如果沒有的話,發出 Settings.ACTION_MANAGE_OVERLAY_PERMISSION 的 Intent,讓使用者打開權限

@Overrideprotected void onResume() {
    super.onResume();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if(!Settings.canDrawOverlays(this)){
            requestAlertWindowPermission();
        } else{
            // do something
        }
    } else{
        // do something
    }
}


private static final int REQUEST_CODE = 1;
private  void requestAlertWindowPermission() {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
    intent.setData(Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, REQUEST_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Settings.canDrawOverlays(this)) {
                Log.i(TAG, "onActivityResult granted");
                // do something
            } else{
                Log.i(TAG, "onActivityResult not granted");
            }
        }
    }
}


2017年2月6日 星期一

Turning on screen and keep screen lon

Reference:

http://stackoverflow.com/questions/2891337/turning-on-screen-programmatically

Advance:
Turn on screen and dismiss keyguard
http://stackoverflow.com/questions/30246425/turning-on-screen-from-receiver-service

Code snippet:

在需要打開螢幕的地方加入下面的 code
WakeLock wl = ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
     PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
wl.acquire();

在離開前要記得釋放 wake lock,以免螢幕保持開啟,造成耗電的問題
wl.release();

Note:
釋放 (release)的 wake lock要和獲取 (acquire)的是同一個,不要再重新建立一個新的wake lock,否則釋放 wake lock時會不能正常運作