Reputation: 58
Past few days I have been trying to figure out how to start app shortcuts added in Android API 25 and I have been somewhat successful. Starting some shortcuts like Google Play Music's work without problem I'm guessing because these shortcuts are starting activities with action.MAIN and category.LAUNCHER or exported, but other activities throw "java.lang.SecurityException: Permission Denial: starting Intent" which seems reasonable as well. This seems dooable since apps like Pixel Launcher, Sesame Shortcuts etc. can do this, there must be some special intent flag or something. I even tried catching shortcut intent inside my app and replicating it but no success
Here is example of how I do this for Google Chrome's "New Tab" shortcut:
val componentName = ComponentName("com.android.chrome", "org.chromium.chrome.browser.LauncherShortcutActivity")
val intent = Intent(action)
intent.component = componentName
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME)
startActivity(intent)
I got these values from activityInfo metaData which can be fetched with PackageManager
Upvotes: 0
Views: 1215
Reputation: 89668
Here's the code to list all available shortcuts and then launch whatever the first shortcut is (just as an example):
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
val shortcutQuery = LauncherApps.ShortcutQuery()
// Set these flags to match your use case, for static shortcuts only,
// use FLAG_MATCH_MANIFEST on its own.
shortcutQuery.setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC
or LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST
or LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED)
shortcutQuery.setPackage(packageName)
val shortcuts = try {
launcherApps.getShortcuts(shortcutQuery, Process.myUserHandle())
} catch (e: SecurityException) {
// This exception will be thrown if your app is not the default launcher
Collections.emptyList<ShortcutInfo>()
}
// Lists all shortcuts from the query
shortcuts.forEach {
Log.d(TAG, "Shortcut found ${it.`package`}, ${it.id}")
}
// Starts the first shortcut, as an example (this of course is not safe like this,
// it will crash if the list is empty, etc).
val shortcut = shortcuts[0]
launcherApps.startShortcut(shortcut.`package`, shortcut.id, null, null, Process.myUserHandle())
This code assumes that you have a variable named context
of type Context
and a variable named packageName
of type String
from somewhere.
Credits: This is all based on Quan Vu's work on this topic, his article here and the corresponding repository here.
Upvotes: 1