App Shortcuts functionality is used to access the particular actions inside your application directly from the launcher icon, you can check the shortcuts by long pressing on your app icon. The user can also pin the shortcut to access the actions quickly.
There are different types of shortcuts:
Static shortcuts: These are defined in a resource file that is packaged into an APK or app bundle.
Dynamic shortcuts: These shortcuts are applied at runtime using the ShortcutManager API. You can add, update, and remove shortcuts when using the dynamic shortcuts.
Pinned shortcuts (Android 8.0 =API level 26): These are added with the help ShortcutManager API at runtime.
Note: Users can also create pinned shortcuts themselves by copying your app’s static and dynamic shortcuts onto the launcher.
limitations of Shortcut
you can add shortcuts up to five times, static and dynamic shortcuts combined at a time on your app.
There is no limit to the number of pinned shortcuts for your application. Even though your app cannot remove pinned shortcuts, it can still disable them.
Note: Although other apps can’t access the metadata within your shortcuts, the launcher itself can access this data. Therefore, these metadata should conceal sensitive user information.
Let’s start with the coding part. Let’s start with MainActivity.kt
1 2 3 4 5 6 7 8 |
class MainActivity : AppCompatActivity() { lateinit var mContentViewBinding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mContentViewBinding = DataBindingUtil.setContentView(this, R.layout.activity_main) mContentViewBinding.handler = MainActivityHandler(this) } } |
Now adding the Handler class having the button click event methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
class MainActivityHandler(private val mContext:MainActivity){ fun onClickAddDynamicShortcutsBtn(view: View?) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { addDynamicShortcuts() } } @TargetApi(Build.VERSION_CODES.N_MR1) @RequiresApi(api = Build.VERSION_CODES.M) private fun addDynamicShortcuts() { val shortcutManager: ShortcutManager = mContext.getSystemService(ShortcutManager::class.java) val intent= Intent(mContext,DestinationActivity::class.java) intent.action= Intent.ACTION_VIEW val openDestinationPage = ShortcutInfo.Builder(mContext, "open_destinationPage") // Id has to be unique .setShortLabel(mContext.getString(R.string.open_destination_page)) //set short label .setLongLabel(mContext.getString(R.string.open_destination_page)) //set long label .setDisabledMessage(mContext.getString(R.string.not_accessible)) //Shortcut disabled message. .setIcon(Icon.createWithResource(mContext,android.R.drawable.star_big_on)) //set icon .setIntent(intent) .build() if (shortcutManager != null) shortcutManager.dynamicShortcuts = listOf( openDestinationPage ) //You can add multiple shortcuts on the list } //The method is used to delete/remove dynamic shortcuts @TargetApi(Build.VERSION_CODES.N_MR1) @RequiresApi(api = Build.VERSION_CODES.M) fun onDeleteDynamicShortcutBtn(view: View?) { val shortcutManager: ShortcutManager = mContext.getSystemService(ShortcutManager::class.java) if (shortcutManager != null) { //NOTE : Remove multiple or single shortcuts then uncomment the below line //shortcutManager.removeDynamicShortcuts(Arrays.asList("open_destinationPage"));// you provide shortcut IDs that you have created and remove them using their unique id //To remove all shortcuts shortcutManager.removeAllDynamicShortcuts() Toast.makeText(mContext, "Shortcut deleted.", Toast.LENGTH_SHORT).show() } } @TargetApi(Build.VERSION_CODES.N_MR1) @RequiresApi(api = Build.VERSION_CODES.M) fun onClickPinnedShortcutBtn(view: View?) { val mShortcutManager: ShortcutManager = mContext.getSystemService(ShortcutManager::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //check if device supports Pin Shortcut or not if (mShortcutManager != null && mShortcutManager.isRequestPinShortcutSupported) { // I am using the dynamic shortcut ID "open_destinationPage" to create pinned shortcut. The added shortcut ID must be added. val pinShortcutInfo = ShortcutInfo.Builder(mContext, "open_destinationPage").build() /* *** Let's create the PendingIntent object for the app to be notified that the user allowed the shortcut to be pinned. The app will not notified if the pinning operation fails, here suppose if app has implemented a method called createShortcutResultIntent() that will return a broadcast intent. ****/ val pinnedShortcutCallbackIntent = mShortcutManager.createShortcutResultIntent(pinShortcutInfo) // Configure the intent so that your app's broadcast receiver gets // the callback successfully. val successCallback = PendingIntent.getBroadcast( mContext, 101, pinnedShortcutCallbackIntent, 0) //Ask the user to add the shortcut to home screen mShortcutManager.requestPinShortcut( pinShortcutInfo, successCallback.intentSender ) } } } |
NOTE:
1. Pinned Shortcuts only work in Android 8.0 and above.
2. Before the pinned shortcuts can be used you must have to create at least 1 or more static or dynamic shortcuts.
3. The pinned shortcuts can be added multiple times.
The layout code for the main activity.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
<?xml version="1.0" encoding="utf-8"?> <layout> <data> <variable name="handler" type="com.example.myapplication.MainActivityHandler" /> </data> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp" > <androidx.appcompat.widget.AppCompatTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/dynamic_shortcut" android:padding="10dp" android:gravity="center" android:textColor="@color/teal_200" android:textSize="14sp" /> <androidx.appcompat.widget.AppCompatButton android:id="@+id/add_dynamic_shortcuts" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@android:color/white" android:background="@color/purple_200" android:textSize="15sp" android:onClick="@{(v)->handler.onClickAddDynamicShortcutsBtn(v)}" android:text="@string/add_dynamic_shortcuts" /> <androidx.appcompat.widget.AppCompatButton android:id="@+id/delete_dynamic_shortcuts" android:layout_width="match_parent" android:textSize="15sp" android:layout_height="wrap_content" android:textColor="@android:color/white" android:background="@color/purple_200" android:layout_marginTop="10dp" android:onClick="@{(v)->handler.onDeleteDynamicShortcutBtn(v)}" android:text="@string/delete_dynamic_shortcuts" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/pinned_shortcut" android:padding="10dp" android:layout_marginTop="10dp" android:textColor="@color/teal_200" android:textSize="14sp" /> <androidx.appcompat.widget.AppCompatButton android:id="@+id/add_pinned_shortcuts" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="15sp" android:textColor="@android:color/white" android:background="@color/purple_200" android:onClick="@{(v)->handler.onClickPinnedShortcutBtn(v)}" android:text="@string/add_pinned_shortcuts" /> </LinearLayout> </layout> |
For the static shortcuts, we have to create a shortcuts.xml file under the directory of res->xml(create resource directory if not created.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <shortcut android:enabled="true" android:icon="@drawable/star" android:shortcutDisabledMessage="@string/access_disabled" android:shortcutId="open_destination_page" android:shortcutLongLabel="@string/open_destination_page_static" android:shortcutShortLabel="@string/open_destination_page_static" tools:targetApi="n_mr1"> <intent android:action="android.intent.action.VIEW" android:targetClass="com.example.myapplication.MainActivity" android:targetPackage="com.example.myapplication" /> <intent android:action="android.intent.action.VIEW" android:targetClass="com.example.myapplication.DestinationActivity" android:targetPackage="com.example.myapplication" /> </shortcut> </shortcuts> |
String resources used for the application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<resources> <string name="app_name">My Application</string> <string name="add_dynamic_shortcuts">Add Dynamic Shortcuts</string> <string name="delete_dynamic_shortcuts">Delete Dynamic Shortcuts</string> <string name="add_pinned_shortcuts">Add Pinned Shortcuts</string> <string name="dynamic_shortcut">Dynamic Shortcut</string> <string name="pinned_shortcut">Pinned Shortcut</string> <string name="destination_page">Destination Page</string> <string name="open_destination_page">Open Destination Page</string> <string name="open_destination_page_static">Open Destination Page Static</string> <string name="not_accessible">The destination page is not accessible</string> <string name="access_disabled">The destination page is disabled.</string> </resources> |
To instantiate the activity and meta-data of shortcuts on the manifest file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication"> <activity android:name=".DestinationActivity" android:label="@string/destination_page" android:parentActivityName=".MainActivity"> <!-- Parent activity meta-data to support 4.0 and lower --> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity" /> </activity> <activity android:name=".MainActivity"> <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> |
Finally, the application shortcuts will be shown like this:
. . . . . . . . . .
Thank you for reading till now, you can also check our other blogs: Click here and you can also check the official blog for app shortcuts: Click here