From e7cbfa995d32b0480942af90db0c05128dc0d152 Mon Sep 17 00:00:00 2001 From: Kevin Hufnagle Date: Fri, 4 Aug 2017 17:03:48 -0700 Subject: [PATCH] docs: Updated ShortcutManager API reference guide. The guide now contains supplemental, rather than duplicate, information relative to the "App Shortcuts" guide, available at https://developer.android.com/guide/topics/ui/shortcuts.html Test: make ds-docs -j8 Bug: 64401518 Change-Id: Iefa34299a9765eb5d853da71d9197a0edb346026 --- .../android/content/pm/ShortcutManager.java | 559 ++++-------------- 1 file changed, 113 insertions(+), 446 deletions(-) diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java index c0b82b4dfee3f..61b0eb0b51f8f 100644 --- a/core/java/android/content/pm/ShortcutManager.java +++ b/core/java/android/content/pm/ShortcutManager.java @@ -36,161 +36,72 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.List; /** - * The ShortcutManager manages an app's shortcuts. Shortcuts provide users - * with quick access to activities other than an app's main activity in the currently-active - * launcher. For example, - * an email app may publish the "compose new email" action, which will directly open the - * compose activity. The {@link ShortcutInfo} class contains information about each of the - * shortcuts themselves. + * The ShortcutManager manages an app's shortcuts. Shortcuts provide users with quick + * access to activities other than an app's main activity in the currently-active launcher, provided + * that the launcher supports app shortcuts. For example, an email app may publish the "compose new + * email" action, which will directly open the compose activity. The {@link ShortcutInfo} class + * contains information about each of the shortcuts themselves. * - *

Static Shortcuts and Dynamic Shortcuts

+ *

This page discusses the implementation details of the ShortcutManager class. For + * guidance on performing operations on app shortcuts within your app, see the + * App Shortcuts feature guide. * - *

- * There are several different types of shortcuts: + *

Shortcut characteristics

* - * + *

Important security note: All shortcut information is stored in + * credential encrypted storage, so your app + * cannot access a user's shortcuts until after they've unlocked the device. * - *

Only main activities—activities that handle the {@code MAIN} action and the - * {@code LAUNCHER} category—can have shortcuts. - * If an app has multiple main activities, these activities have different sets - * of shortcuts. + *

Static and dynamic shortcuts

* *

Static shortcuts and dynamic shortcuts are shown in a supported launcher when the user - * long-presses on an app's launcher icon. Note that the actual gesture may be different - * depending on the launcher app. + * performs a specific gesture. On currently-supported launchers, the gesture is a long-press on the + * app's launcher icon, but the actual gesture may be different on other launcher apps. * - *

Each launcher icon can have at most {@link #getMaxShortcutCountPerActivity()} number of - * static and dynamic shortcuts combined. + *

The {@link LauncherApps} class provides APIs for launcher apps to access shortcuts. * + *

Pinned shortcuts

* - *

Pinning Shortcuts

+ *

Because pinned shortcuts appear in the launcher itself, they're always visible. A pinned + * shortcut is removed from the launcher only in the following situations: + *

* - *

Apps running in the foreground can also pin shortcuts at runtime, subject to user - * permission, using this class's APIs. Each pinned shortcut is a copy of a static shortcut or a - * dynamic shortcut. Although users can pin a shortcut multiple times, the system calls the pinning - * API only once to complete the pinning process. Unlike static and dynamic shortcuts, pinned - * shortcuts appear as separate icons, visually distinct from the app's launcher icon, in the - * launcher. There is no limit to the number of pinned shortcuts that an app can create. + *

Because the system performs + * backup and restore on pinned + * shortcuts automatically, these shortcuts' IDs should contain either stable, constant strings or + * server-side identifiers, rather than identifiers generated locally that might not make sense on + * other devices. * - *

Pinned shortcuts cannot be removed by publisher apps. They're removed only - * when the user removes them, when the publisher app is uninstalled, or when the user performs the - * clear data action on the publisher app from the device's Settings app. + *

Shortcut display order

* - *

However, the publisher app can disable pinned shortcuts so they cannot be started. - * See the following sections for details. + *

When the launcher displays an app's shortcuts, they should appear in the following order: * - *

Updating and Disabling Shortcuts

+ * * - *

When a dynamic shortcut is pinned, even when the publisher removes it as a dynamic shortcut, - * the pinned shortcut will still be visible and launchable. This allows an app to have - * more than {@link #getMaxShortcutCountPerActivity()} number of shortcuts. + *

Shortcut ranks are non-negative, sequential integers that determine the order in which + * shortcuts appear, assuming that the shortcuts are all in the same category. You can update ranks + * of existing shortcuts when you call {@link #updateShortcuts(List)}, + * {@link #addDynamicShortcuts(List)}, or {@link #setDynamicShortcuts(List)}. * - *

For example, suppose {@link #getMaxShortcutCountPerActivity()} is 5: - *

    - *
  1. A chat app publishes 5 dynamic shortcuts for the 5 most recent - * conversations (c1, c2, ..., c5). + *

    Note: Ranks are auto-adjusted so that they're unique for each type of + * shortcut (static or dynamic). For example, if there are 3 dynamic shortcuts with ranks 0, 1 and + * 2, adding another dynamic shortcut with a rank of 1 represents a request to place this shortcut + * at the second position. In response, the third and fourth shortcuts move closer to the bottom of + * the shortcut list, with their ranks changing to 2 and 3, respectively. * - *

  2. The user pins all 5 of the shortcuts. - * - *
  3. Later, the user has started 3 additional conversations (c6, c7, and c8), - * so the publisher app - * re-publishes its dynamic shortcuts. The new dynamic shortcut list is: - * c4, c5, ..., c8. - * The publisher app has to remove c1, c2, and c3 because it can't have more than - * 5 dynamic shortcuts. - * - *
  4. However, even though c1, c2, and c3 are no longer dynamic shortcuts, the pinned - * shortcuts for these conversations are still available and launchable. - * - *
  5. At this point, the user can access a total of 8 shortcuts that link to activities in - * the publisher app, including the 3 pinned - * shortcuts, even though an app can have at most 5 dynamic shortcuts. - * - *
  6. The app can use {@link #updateShortcuts(List)} to update any of the existing - * 8 shortcuts, when, for example, the chat peers' icons have changed. - *
- * The {@link #addDynamicShortcuts(List)} and {@link #setDynamicShortcuts(List)} methods - * can also be used - * to update existing shortcuts with the same IDs, but they cannot be used - * for updating non-dynamic, pinned shortcuts because these two methods try to convert the given - * lists of shortcuts to dynamic shortcuts. - * - * - *

Disabling Static Shortcuts

- *

When an app is upgraded and the new version - * no longer uses a static shortcut that appeared in the previous version, this deprecated - * shortcut isn't published as a static shortcut. - * - *

If the deprecated shortcut is pinned, then the pinned shortcut will remain on the launcher, - * but it's disabled automatically. When a pinned shortcut is disabled, this class's APIs cannot - * update it. - * - *

Disabling Dynamic Shortcuts

- * Sometimes pinned shortcuts become obsolete and may not be usable. For example, a pinned shortcut - * to a group chat becomes unusable when the associated group chat is deleted. In cases like this, - * apps should use {@link #disableShortcuts(List)}, which removes the specified dynamic - * shortcuts and also makes any specified pinned shortcuts un-launchable. - * The {@link #disableShortcuts(List, CharSequence)} method can also be used to disable shortcuts - * and show users a custom error message when they attempt to launch the disabled shortcuts. - * - * - *

Publishing Static Shortcuts

- * - *

- * In order to add static shortcuts to your app, first add - * {@code } to your main activity in - * AndroidManifest.xml: - *

- *<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- *             package="com.example.myapplication">
- *  <application ... >
- *    <activity android:name="Main">
- *      <intent-filter>
- *        <action android:name="android.intent.action.MAIN" />
- *        <category android:name="android.intent.category.LAUNCHER" />
- *      </intent-filter>
- *      <meta-data android:name="android.app.shortcuts"
- *                 android:resource="@xml/shortcuts" />
- *    </activity>
- *  </application>
- *</manifest>
- * 
- * - * Then, define your app's static shortcuts in the res/xml/shortcuts.xml - * file: - *
- *<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
- *  <shortcut
- *    android:shortcutId="compose"
- *    android:enabled="true"
- *    android:icon="@drawable/compose_icon"
- *    android:shortcutShortLabel="@string/compose_shortcut_short_label1"
- *    android:shortcutLongLabel="@string/compose_shortcut_long_label1"
- *    android:shortcutDisabledMessage="@string/compose_disabled_message1">
- *    <intent
- *      android:action="android.intent.action.VIEW"
- *      android:targetPackage="com.example.myapplication"
- *      android:targetClass="com.example.myapplication.ComposeActivity" />
- *    <!-- If your shortcut is associated with multiple intents, include them
- *         here. The last intent in the list is what the user sees when they
- *         launch this shortcut. -->
- *    <categories android:name="android.shortcut.conversation" />
- *  </shortcut>
- *  <!-- Specify more shortcuts here. -->
- *</shortcuts>
- * 
+ *

Options for static shortcuts

* * The following list includes descriptions for the different attributes within a static shortcut: *
@@ -236,9 +147,10 @@ import java.util.List; * {@code android:action} is mandatory. * See Using intents for the * other supported tags. - * You can provide multiple intents for a single shortcut so that the last defined activity is launched - * with the other activities in the back stack. - * See {@link android.app.TaskStackBuilder} for details. + *

You can provide multiple intents for a single shortcut so that the last defined activity is + * launched with the other activities in the + * back stack. See + * {@link android.app.TaskStackBuilder} for details. *

Note: String resources may not be used within an {@code } element. * *

{@code categories}
@@ -247,337 +159,92 @@ import java.util.List; * *
* - *

Publishing Dynamic Shortcuts

- * - *

- * Apps can publish dynamic shortcuts with {@link #setDynamicShortcuts(List)} - * or {@link #addDynamicShortcuts(List)}. The {@link #updateShortcuts(List)} method can also be - * used to update existing, mutable shortcuts. - * Use {@link #removeDynamicShortcuts(List)} or {@link #removeAllDynamicShortcuts()} to remove - * dynamic shortcuts. - * - *

The following code snippet shows how to create a single dynamic shortcut: - *

- *ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
- *
- *ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "id1")
- *    .setShortLabel("Web site")
- *    .setLongLabel("Open the web site")
- *    .setIcon(Icon.createWithResource(context, R.drawable.icon_website))
- *    .setIntent(new Intent(Intent.ACTION_VIEW,
- *                   Uri.parse("https://www.mysite.example.com/")))
- *    .build();
- *
- *shortcutManager.setDynamicShortcuts(Arrays.asList(shortcut));
- * 
- * - *

Publishing Pinned Shortcuts

- * - *

Apps can pin an existing shortcut (either static or dynamic) or an entirely new shortcut to a - * supported launcher programatically using {@link #requestPinShortcut(ShortcutInfo, IntentSender)}. - * You pass two arguments into this method: - * - *

- * - * The following code snippet shows how to pin a single shortcut that already exists and is enabled: - * - *
- *ShortcutManager mShortcutManager =
- *        context.getSystemService(ShortcutManager.class);
- *
- *if (mShortcutManager.isRequestPinShortcutSupported()) {
- *
- *    // This example defines a new shortcut; that is, this shortcut hasn't
- *    // been published before.
- *    ShortcutInfo pinShortcutInfo = new ShortcutInfo.Builder()
- *            .setIcon(myIcon)
- *            .setShortLabel("My awesome shortcut")
- *            .setIntent(myIntent)
- *            .build();
- *
- *    PendingIntent resultPendingIntent = null;
- *
- *    // Create the following Intent and PendingIntent objects only if your app
- *    // needs to be notified that the user allowed the shortcut to be pinned.
- *    // Use a boolean value, such as "appNeedsNotifying", to define this behavior.
- *    if (appNeedsNotifying) {
- *        // We assume here the app has a manifest-declared receiver "MyReceiver".
- *        Intent pinnedShortcutCallbackIntent = new Intent(context, MyReceiver.class);
- *
- *        // Configure the intent so that your app's broadcast receiver gets
- *        // the callback successfully.
- *        PendingIntent successCallback = PendingIntent.createBroadcast(context, 0,
- *                pinnedShortcutCallbackIntent);
- *
- *        resultPendingIntent = successCallback.getIntentSender();
- *    }
- *
- *    mShortcutManager.requestPinShortcut(pinShortcutInfo, resultPendingIntent);
- *}
- * 
- * - *

Note: As you add logic in your app to make requests to pin - * shortcuts, keep in mind that not all launchers support pinning of shortcuts. To determine whether - * your app can complete this process on a particular device, check the return value of - * {@link #isRequestPinShortcutSupported()}. Based on this return value, you might decide to hide - * the option in your app that allows users to pin a shortcut. - * - *

Note: See also the support library APIs - * {@link android.support.v4.content.pm.ShortcutManagerCompat#isRequestPinShortcutSupported( - * Context)} and - * {@link android.support.v4.content.pm.ShortcutManagerCompat#requestPinShortcut( - * Context, ShortcutInfoCompat, IntentSender)}, which works on Android versions lower than - * {@link VERSION_CODES#O} by falling back to the deprecated private intent - * {@code com.android.launcher.action.INSTALL_SHORTCUT}. - * - *

Custom Activity for Pinning Shortcuts

- * - *

You can also create a specialized activity that helps users create shortcuts, complete with - * custom options and a confirmation button. In your app's manifest file, add - * {@link Intent#ACTION_CREATE_SHORTCUT} to the activity's <intent-filter> - * element, as shown in the following snippet: - * - *

- *<manifest>
- *    ...
- *    <application>
- *        <activity android:name="com.example.MyCustomPromptToPinShortcut" ... >
- *            <intent-filter
- *                    action android:name="android.intent.action.ACTION_CREATE_SHORTCUT">
- *            ...
- *            </intent-filter>
- *        </activity>
- *        ...
- *    </application>
- *</manifest>
- * 
- * - *

When you use this specialized activity in your app, the following sequence of steps takes - * place:

+ *

Updating shortcuts

* + *

As an example, suppose {@link #getMaxShortcutCountPerActivity()} is 5: *

    - *
  1. The user attempts to create a shortcut, triggering the system to start the specialized - * activity.
  2. - *
  3. The user sets options for the shortcut.
  4. - *
  5. The user selects the confirmation button, allowing your app to create the shortcut using - * the {@link #createShortcutResultIntent(ShortcutInfo)} method. This method returns an - * {@link Intent}, which your app relays back to the previously-executing activity using - * {@link Activity#setResult(int)}.
  6. - *
  7. Your app calls {@link Activity#finish()} on the activity used for creating the customized - * shortcut.
  8. + *
  9. A chat app publishes 5 dynamic shortcuts for the 5 most recent + * conversations (c1, c2, ..., c5). + * + *
  10. The user pins all 5 of the shortcuts. + * + *
  11. Later, the user has started 3 additional conversations (c6, c7, and c8), + * so the publisher app + * re-publishes its dynamic shortcuts. The new dynamic shortcut list is: + * c4, c5, ..., c8. + * The publisher app has to remove c1, c2, and c3 because it can't have more than + * 5 dynamic shortcuts. + * + *
  12. However, even though c1, c2, and c3 are no longer dynamic shortcuts, the pinned + * shortcuts for these conversations are still available and launchable. + * + *
  13. At this point, the user can access a total of 8 shortcuts that link to activities in + * the publisher app, including the 3 pinned shortcuts, even though an app can have at most 5 + * dynamic shortcuts. + * + *
  14. The app can use {@link #updateShortcuts(List)} to update any of the existing + * 8 shortcuts, when, for example, the chat peers' icons have changed. + *

    The {@link #addDynamicShortcuts(List)} and {@link #setDynamicShortcuts(List)} methods + * can also be used to update existing shortcuts with the same IDs, but they cannot be + * used for updating non-dynamic, pinned shortcuts because these 2 methods try to convert the + * given lists of shortcuts to dynamic shortcuts. *

* - *

Shortcut Intents

+ *

Shortcut intents

+ * *

* Dynamic shortcuts can be published with any set of {@link Intent#addFlags Intent} flags. * Typically, {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} is specified, possibly along with other * flags; otherwise, if the app is already running, the app is simply brought to * the foreground, and the target activity may not appear. * - *

The {@link ShortcutInfo.Builder#setIntents(Intent[])} method can be used instead of - * {@link ShortcutInfo.Builder#setIntent(Intent)} with {@link android.app.TaskStackBuilder} - * in order to launch an activity with other activities in the back stack. - * When the user selects a shortcut to load an activity with a back stack, - * then presses the back key, a parent activity from the same app will be shown - * instead of the user being navigated back to the launcher. - * - *

Static shortcuts can also have multiple intents to achieve the same effect. - * In order to associate multiple {@link Intent} objects with a shortcut, simply list multiple - * <intent> elements within a single <shortcut> element. - * The last intent specifies what the user sees when they launch a shortcut. - * *

Static shortcuts cannot have custom intent flags. * The first intent of a static shortcut will always have {@link Intent#FLAG_ACTIVITY_NEW_TASK} - * and {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} set. - * This means, when the app is already running, all the existing activities will be - * destroyed when a static shortcut is launched. - * If this behavior is not desirable, you can use a trampoline activity, - * or an invisible activity that starts another activity in {@link Activity#onCreate}, - * then calls {@link Activity#finish()}. - * The first activity should include an attribute setting - * of {@code android:taskAffinity=""} in the app's AndroidManifest.xml - * file, and the intent within the static shortcut should point at this first activity. + * and {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} set. This means, when the app is already running, all + * the existing activities in your app will be destroyed when a static shortcut is launched. + * If this behavior is not desirable, you can use a trampoline activity, or an invisible + * activity that starts another activity in {@link Activity#onCreate}, then calls + * {@link Activity#finish()}: + *

    + *
  1. In the AndroidManifest.xml file, the trampoline activity should include the + * attribute assignment {@code android:taskAffinity=""}. + *
  2. In the shortcuts resource file, the intent within the static shortcut should point at + * the trampoline activity. + *
* + *

Handling system locale changes

* - *

Showing New Information in a Shortcut

- *

- * In order to avoid confusion, you should not use {@link #updateShortcuts(List)} to update - * a shortcut so that it contains conceptually different information. + *

Apps should update dynamic and pinned shortcuts when the system locale changes using the + * {@link Intent#ACTION_LOCALE_CHANGED} broadcast. When the system locale changes, + * rate limiting is reset, so even + * background apps can add and update dynamic shortcuts until the rate limit is reached again. * - *

For example, a phone app may publish the most frequently called contact as a dynamic - * shortcut. Over time, this contact may change. When it does, the app should - * represent the changed contact with a new shortcut that contains a different ID, using either - * {@link #setDynamicShortcuts(List)} or {@link #addDynamicShortcuts(List)}, rather than updating - * the existing shortcut with {@link #updateShortcuts(List)}. - * This is because when the shortcut is pinned, changing - * it to reference a different contact will likely confuse the user. + *

Shortcut limits

* - *

On the other hand, when the - * contact's information has changed, such as the name or picture, the app should - * use {@link #updateShortcuts(List)} so that the pinned shortcut is updated too. + *

Only main activities—activities that handle the {@code MAIN} action and the + * {@code LAUNCHER} category—can have shortcuts. If an app has multiple main activities, you + * need to define the set of shortcuts for each activity. * + *

Each launcher icon can have at most {@link #getMaxShortcutCountPerActivity()} number of + * static and dynamic shortcuts combined. There is no limit to the number of pinned shortcuts that + * an app can create. * - *

Shortcut Display Order

- * When the launcher displays the shortcuts that are associated with a particular launcher icon, - * the shortcuts should appear in the following order: - * - *

Shortcut ranks are non-negative, sequential integers - * that determine the order in which shortcuts appear, assuming that the shortcuts are all in - * the same category. - * Ranks of existing shortcuts can be updated with - * {@link #updateShortcuts(List)}. You can also use {@link #addDynamicShortcuts(List)} and - * {@link #setDynamicShortcuts(List)}. + *

When a dynamic shortcut is pinned, even when the publisher removes it as a dynamic shortcut, + * the pinned shortcut is still visible and launchable. This allows an app to have more than + * {@link #getMaxShortcutCountPerActivity()} number of shortcuts. * - *

Ranks are auto-adjusted so that they're unique for each target activity in each category - * (static or dynamic). For example, if there are 3 dynamic shortcuts with ranks 0, 1 and 2, - * adding another dynamic shortcut with a rank of 1 represents a request to place this shortcut at - * the second position. - * In response, the third and fourth shortcuts move closer to the bottom of the shortcut list, - * with their ranks changing to 2 and 3, respectively. + *

Rate limiting

* - *

Rate Limiting

+ *

When rate limiting is active, + * {@link #isRateLimitingActive()} returns {@code true}. * - *

- * Calls to {@link #setDynamicShortcuts(List)}, {@link #addDynamicShortcuts(List)}, and - * {@link #updateShortcuts(List)} may be rate-limited when called by background apps, or - * apps with no foreground activity or service. When you attempt to call these methods - * from a background app after exceeding the rate limit, these APIs return {@code false}. - * - *

Apps with a foreground activity or service are not rate-limited. - * - *

Rate-limiting is reset upon certain events, so that even background apps - * can call these APIs until the rate limit is reached again. - * These events include the following: + *

Rate limiting is reset upon certain events, so even background apps can call these APIs until + * the rate limit is reached again. These events include the following: *

- * - *

When rate-limiting is active, {@link #isRateLimitingActive()} returns {@code true}. - * - *

Resetting rate-limiting for testing

- * - *

- * If your app is rate-limited during development or testing, you can use the - * Reset ShortcutManager rate-limiting development option or - * the following {@code adb} command to reset it: - *

- *$ adb shell cmd shortcut reset-throttling [ --user USER-ID ]
- * 
- * - *

Handling System Locale Changes

- * - *

- * Apps should update dynamic and pinned shortcuts when the system locale changes - * using the {@link Intent#ACTION_LOCALE_CHANGED} broadcast. - * - *

When the system locale changes, rate-limiting is reset, so even background apps - * can add and update dynamic shortcuts until the rate limit is reached again. - * - * - *

Backup and Restore

- * - *

- * When an app has the {@code android:allowBackup="true"} attribute assignment included - * in its AndroidManifest.xml file, pinned shortcuts are - * backed up automatically and are restored when the user sets up a new device. - * - *

Categories of shortcuts that are backed up

- * - * - * - *

Because dynamic shortcuts are not restored, it is recommended that apps check - * currently-published dynamic shortcuts using {@link #getDynamicShortcuts()} - * each time they are launched, and they should re-publish - * dynamic shortcuts when necessary. - * - *

- *public class MainActivity extends Activity {
- *    public void onCreate(Bundle savedInstanceState) {
- *        super.onCreate(savedInstanceState);
- *        ShortcutManager shortcutManager =
- *                getSystemService(ShortcutManager.class);
- *
- *        if (shortcutManager.getDynamicShortcuts().size() == 0) {
- *            // Application restored. Need to re-publish dynamic shortcuts.
- *            if (shortcutManager.getPinnedShortcuts().size() > 0) {
- *                // Pinned shortcuts have been restored. Use
- *                // updateShortcuts() to make sure they contain
- *                // up-to-date information.
- *            }
- *        }
- *    }
- *    // ...
- *}
- * 
- * - * - *

Backup/restore and shortcut IDs

- *

- * Because pinned shortcuts are backed up and restored on new devices, shortcut IDs - * should contain either stable, constant strings or server-side identifiers, - * rather than identifiers generated locally that might not make sense on other devices. - * - * - *

Report Shortcut Usage and Prediction

- *

- * Launcher apps may be capable of predicting which shortcuts will most likely be - * used at a given time by examining the shortcut usage history data. - * - *

In order to provide launchers with such data, publisher apps should - * report the shortcuts that are used with {@link #reportShortcutUsed(String)} - * when a shortcut is selected, - * or when an action equivalent to a shortcut is taken by the user even if it wasn't started - * with the shortcut. - * - *

For example, suppose a navigation app supports "navigate to work" as a shortcut. - * It should then report when the user selects this shortcut and when the user chooses - * to navigate to work within the app itself. - * This helps the launcher app - * learn that the user wants to navigate to work at a certain time every - * weekday, and it can then show this shortcut in a suggestion list at the right time. - * - *

Launcher API

- * - * The {@link LauncherApps} class provides APIs for launcher apps to access shortcuts. - * - * - *

Direct Boot and Shortcuts

- * - * All shortcut information is stored in credential encrypted storage, so no shortcuts can be - * accessed when the user is locked. */ @SystemService(Context.SHORTCUT_SERVICE) public class ShortcutManager {