Notification使用,沒有懸浮窗權限,重新申請

 1、在android O版本之後,橫幅彈出需要創建channelId,設置給notification,定義的channelId賦值必須是數字字符串,否則橫幅彈出失敗,:

如下代碼實現:

1、應用切後臺後彈出橫幅,點擊橫幅後打開應用並彈出dialog,提示用戶授權懸浮窗權限

2、如果用戶點擊前往設置,則進入設置,如果授權成功,返回應用後則彈框消失,否則彈框繼續存在

3、在懸浮窗授權界面不彈出橫幅通知

4、在彈出dialog後,選擇取消,再次切後臺後繼續走1-3流程。

    private static final String TAG = "MainActivity";

    private static final int RELEASE_LOCK_DELAY_TIME = 1000;

    private static final int NOTIFICATION_ID = 1;

    private static final String EXTRA_FROM_NOTIFICATION = "from_notification";

    private TextView mScreenOnTxt;

    private PowerManager.WakeLock mWakeLock;

    private boolean mIsClickToGainOverlayPermission = false;

    // channelId必須是數字
    private String channelId = "1";

    private NotificationManager notificationManager;

    private AlertDialog mAlertDialog;

    // 如果第一次啓動界面,從首次置後臺後再返回時彈出dialog
    // 提示用戶,切後臺後需要懸浮窗權限
    private int isFirstCreateAndBackground = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate");
        setContentView(R.layout.activity_main);

        mScreenOnTxt = findViewById(R.id.screen_on_txt);
        registerScreenOnReceiver();
        createChannelId();
        isFirstCreateAndBackground = 0;
    }

    BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "action = " + intent.getAction());
            if (Intent.ACTION_SCREEN_ON.equalsIgnoreCase(intent.getAction())) {
                Log.d(TAG, "screen on.");
            } else if (Intent.ACTION_SCREEN_OFF.equalsIgnoreCase(intent.getAction())) {
                Log.d(TAG, "screen off");
                mScreenOnTxt.setText("screen off");
                /* 如果滅屏後,點亮屏幕 */
                wakeUpScreen();
            }
        }
    };

    private void registerScreenOnReceiver() {
        // 註冊監聽屏幕亮滅屏動作
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        registerReceiver(mBroadcastReceiver, filter);
    }

    private void wakeUpScreen() {
        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        if (mWakeLock == null) {
            // 強制亮屏,並且弱光點亮屏幕
            mWakeLock = powerManager.newWakeLock(
                PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK,
                "MainActivity:wakeup");
        }
        // 點亮屏幕,如果屏幕亮屏,則不需要點亮屏幕
        if (powerManager.isScreenOn()) {
            return;
        }
        if (mWakeLock.isHeld()) {
            mWakeLock.release();
        }
        mWakeLock.acquire(RELEASE_LOCK_DELAY_TIME);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
        Intent intent = getIntent();
        Log.d(TAG, "onResume intent = " + intent);
        // 收到的intent中,是否從點擊notification過來的
        boolean backFromClickNotification = false;
        if (intent != null && intent.hasExtra(EXTRA_FROM_NOTIFICATION)) {
            backFromClickNotification =
                intent.getBooleanExtra(EXTRA_FROM_NOTIFICATION, false);
        }
        Log.d(TAG, "from notification extra value = " + backFromClickNotification +
            "isFirstCreateAndBackground=" + isFirstCreateAndBackground);
        if (isFirstCreateAndBackground == 1 || backFromClickNotification) {
            displayDialogToNotifyUserToGainOverlayPermission();
        }
        cancelNotification();
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop");
        checkOverlayPermissionBeforeBackground();
        isFirstCreateAndBackground = 1;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
        unregisterReceiver(mBroadcastReceiver);
        mWakeLock= null;
    }

    private void checkOverlayPermissionBeforeBackground() {
        if (mIsClickToGainOverlayPermission) {
            return;
        }
        if (!Settings.canDrawOverlays(this)) {
            Log.d(TAG, "need overlay permissions.");
            displayNotificationForOverlay();
        } else {
            Log.d(TAG, "has overlay permissions.");
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d(TAG, "onNewIntent, intent = " + intent);
        setIntent(intent);
    }

    private void createChannelId() {
        String channelName = "MainActivity";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId, channelName,
                NotificationManager.IMPORTANCE_MAX);
            notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }

    private void displayNotificationForOverlay() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId);
        builder.setContentTitle("電話通知");
        builder.setContentText("設置後臺需要懸浮窗權限");
        builder.setSmallIcon(R.drawable.ic_launcher_background);
        builder.setAutoCancel(true);
        builder.setChannelId(channelId);

        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra(EXTRA_FROM_NOTIFICATION, true);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pi = PendingIntent.getActivity(MainActivity.this,
            0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(pi);
        Notification notification = builder.build();
        notificationManager.notify(NOTIFICATION_ID, notification);
    }

    private void cancelNotification() {
        if (notificationManager != null) {
            Log.d(TAG, "cancelNotification, cancel.");
            notificationManager.cancel(NOTIFICATION_ID);
        }
    }

    private void displayDialogToNotifyUserToGainOverlayPermission() {
        if (Settings.canDrawOverlays(this)) {
            return;
        }
        if (mAlertDialog != null) {
            return;
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("需要使用懸浮窗權限");
        builder.setPositiveButton("前往設置", new DialogInterface.OnClickListener(){
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.d(TAG, "click dialog goto gain overlay permissions.");
                mAlertDialog.dismiss();
                mAlertDialog = null;
                mIsClickToGainOverlayPermission = true;
                gotoGainOverlayPermission();
            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(MainActivity.this, "取消授權", Toast.LENGTH_SHORT).show();
                mAlertDialog = null;
            }
        });
        builder.setCancelable(true);
        mAlertDialog = builder.create();
        mAlertDialog.show();
        mIsClickToGainOverlayPermission = false;
    }

    private void gotoGainOverlayPermission() {
        if (!Settings.canDrawOverlays(this)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
            try {
                startActivity(intent);
            } catch (ActivityNotFoundException e) {
                Log.d(TAG, "gotoGainOverlayPermission activity not founded");
            }
        }
        return;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章