From 66138f2e9c0cbf5ad1320dfbd731ae909a265502 Mon Sep 17 00:00:00 2001 From: uniquare <142790259+uniquare@users.noreply.github.com> Date: Thu, 28 Sep 2023 15:16:34 +0200 Subject: [PATCH] fix(android): Ask for POST_NOTIFICATIONS permission if necessary (#238) * fix(android): Ask for POST_NOTIFICATIONS permission if necessary --------- Co-authored-by: Daniel Zupan --- plugin.xml | 1 + .../com/adobe/phonegap/push/PushPlugin.kt | 55 ++++++++++++++++++- www/push.js | 9 +-- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/plugin.xml b/plugin.xml index 8e85ddb90..fd9632d18 100755 --- a/plugin.xml +++ b/plugin.xml @@ -32,6 +32,7 @@ + diff --git a/src/android/com/adobe/phonegap/push/PushPlugin.kt b/src/android/com/adobe/phonegap/push/PushPlugin.kt index 3675c069a..904c4262b 100644 --- a/src/android/com/adobe/phonegap/push/PushPlugin.kt +++ b/src/android/com/adobe/phonegap/push/PushPlugin.kt @@ -1,5 +1,6 @@ package com.adobe.phonegap.push +import android.Manifest import android.annotation.SuppressLint import android.annotation.TargetApi import android.app.Activity @@ -7,6 +8,7 @@ import android.app.NotificationChannel import android.app.NotificationManager import android.content.ContentResolver import android.content.Context +import android.content.pm.PackageManager import android.content.res.Resources.NotFoundException import android.media.AudioAttributes import android.net.Uri @@ -37,12 +39,15 @@ class PushPlugin : CordovaPlugin() { const val PREFIX_TAG: String = "cordova-plugin-push" private const val TAG: String = "$PREFIX_TAG (PushPlugin)" + private const val REQ_CODE_INITIALIZE_PLUGIN = 0 + /** * Is the WebView in the foreground? */ var isInForeground: Boolean = false private var pushContext: CallbackContext? = null + private var pluginInitData: JSONArray? = null private var gWebView: CordovaWebView? = null private val gCachedExtras = Collections.synchronizedList(ArrayList()) @@ -433,11 +438,16 @@ class PushPlugin : CordovaPlugin() { // Better Logging fun formatLogMessage(msg: String): String = "Execute::Initialize: ($msg)" + pushContext = callbackContext + pluginInitData = data; + + var hasPermission = checkForPostNotificationsPermission() + if (!hasPermission) + return + cordova.threadPool.execute(Runnable { Log.v(TAG, formatLogMessage("Data=$data")) - pushContext = callbackContext - val sharedPref = applicationContext.getSharedPreferences( PushConstants.COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE @@ -600,6 +610,22 @@ class PushPlugin : CordovaPlugin() { }) } + private fun checkForPostNotificationsPermission(): Boolean { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + if (!PermissionHelper.hasPermission(this, Manifest.permission.POST_NOTIFICATIONS)) + { + PermissionHelper.requestPermission( + this, + REQ_CODE_INITIALIZE_PLUGIN, + Manifest.permission.POST_NOTIFICATIONS + ) + return false + } + } + + return true + } + private fun executeActionUnregister(data: JSONArray, callbackContext: CallbackContext) { // Better Logging fun formatLogMessage(msg: String): String = "Execute::Unregister: ($msg)" @@ -872,4 +898,29 @@ class PushPlugin : CordovaPlugin() { FirebaseMessaging.getInstance().unsubscribeFromTopic(it) } } + + override fun onRequestPermissionResult( + requestCode: Int, + permissions: Array?, + grantResults: IntArray? + ) { + super.onRequestPermissionResult(requestCode, permissions, grantResults) + + for (r in grantResults!!) { + if (r == PackageManager.PERMISSION_DENIED) { + pushContext?.sendPluginResult( + PluginResult( + PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, + "Permission to post notifications was denied by the user" + ) + ) + return + } + } + + if (requestCode == REQ_CODE_INITIALIZE_PLUGIN) + { + executeActionInitialize(pluginInitData!!, pushContext!!) + } + } } diff --git a/www/push.js b/www/push.js index a789474b1..57f9f138a 100644 --- a/www/push.js +++ b/www/push.js @@ -9,10 +9,11 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } -function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } -function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + /*! * Module dependencies. */