Add support for intent scheme URI and deep links in clickAction and actionable notifications (#2888)

* Add support for intent scheme URI in clickAction and actionable notifications

* Add a new prefix for app links in actions

* Rename app link to deep link to be more precise

* Use correct intent prefix

* Take user to the play store if the app is not installed

* Fix taking user to the market if app is missing, remove ability for deep links since we can't get the package name

* Only open the play store if we have an actual package to open to
This commit is contained in:
Daniel Shokouhi 2022-09-24 13:00:29 -07:00 committed by GitHub
parent 763819746a
commit 2e19dc4474
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 8 deletions

View file

@ -102,6 +102,8 @@ class MessagingManager @Inject constructor(
const val TAG = "MessagingService"
const val APP_PREFIX = "app://"
const val DEEP_LINK_PREFIX = "deep-link://"
const val INTENT_PREFIX = "intent:"
const val MARKET_PREFIX = "https://play.google.com/store/apps/details?id="
const val SETTINGS_PREFIX = "settings://"
const val NOTIFICATION_HISTORY = "notification_history"
@ -1586,6 +1588,7 @@ class MessagingManager @Inject constructor(
private fun createOpenUriPendingIntent(
uri: String
): PendingIntent {
val needsPackage = uri.startsWith(APP_PREFIX) || uri.startsWith(INTENT_PREFIX)
val intent = when {
uri.isBlank() -> {
WebViewActivity.newInstance(context)
@ -1593,15 +1596,23 @@ class MessagingManager @Inject constructor(
uri.startsWith(APP_PREFIX) -> {
context.packageManager.getLaunchIntentForPackage(uri.substringAfter(APP_PREFIX))
}
uri.startsWith(INTENT_PREFIX) -> {
Intent.parseUri(uri, Intent.URI_INTENT_SCHEME)
}
uri.startsWith(SETTINGS_PREFIX) -> {
if (uri.substringAfter(SETTINGS_PREFIX) == NOTIFICATION_HISTORY)
SettingsActivity.newInstance(context)
else
WebViewActivity.newInstance(context)
}
UrlHandler.isAbsoluteUrl(uri) -> {
UrlHandler.isAbsoluteUrl(uri) || uri.startsWith(DEEP_LINK_PREFIX) -> {
Intent(Intent.ACTION_VIEW).apply {
this.data = Uri.parse(uri)
this.data = Uri.parse(
if (uri.startsWith(DEEP_LINK_PREFIX))
uri.removePrefix(DEEP_LINK_PREFIX)
else
uri
)
}
}
else -> {
@ -1611,6 +1622,7 @@ class MessagingManager @Inject constructor(
if (uri.startsWith(SETTINGS_PREFIX) && uri.substringAfter(SETTINGS_PREFIX) == NOTIFICATION_HISTORY)
intent.putExtra("fragment", NOTIFICATION_HISTORY)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
@ -1618,7 +1630,20 @@ class MessagingManager @Inject constructor(
return PendingIntent.getActivity(
context,
(uri.hashCode() + System.currentTimeMillis()).toInt(),
intent,
if (needsPackage) {
val intentPackage = intent.`package`?.let {
context.packageManager.getLaunchIntentForPackage(
it
)
}
if (intentPackage == null && (!intent.`package`.isNullOrEmpty() || uri.startsWith(APP_PREFIX))) {
val marketIntent = Intent(Intent.ACTION_VIEW)
marketIntent.data = Uri.parse(MARKET_PREFIX + if (uri.startsWith(INTENT_PREFIX)) intent.`package`.toString() else uri.removePrefix(APP_PREFIX))
marketIntent
} else
intent
} else
intent,
PendingIntent.FLAG_IMMUTABLE
)
}

View file

@ -115,7 +115,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
private const val TAG = "WebviewActivity"
private const val APP_PREFIX = "app://"
private const val INTENT_PREFIX = "intent://"
private const val INTENT_PREFIX = "intent:"
private const val MARKET_PREFIX = "https://play.google.com/store/apps/details?id="
fun newInstance(context: Context, path: String? = null): Intent {
@ -384,15 +384,14 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
it1
)
}
if (intentPackage != null)
startActivity(intent)
else {
if (intentPackage == null && !intent.`package`.isNullOrEmpty()) {
Log.w(TAG, "No app found for intent prefix, opening app store")
val marketIntent = Intent(Intent.ACTION_VIEW)
marketIntent.data =
Uri.parse(MARKET_PREFIX + intent.`package`.toString())
startActivity(marketIntent)
}
} else
startActivity(intent)
return true
} else if (!webView.url.toString().contains(it.toString())) {
Log.d(TAG, "Launching browser")