Search code examples
androidandroid-jetpackandroid-architecture-navigationandroid-deep-linkandroid-shortcut

How to create pinned shortcut with navigation components?


So I was following the article by Chet Haase.

Article: https://medium.com/androiddevelopers/navigating-with-deep-links-910a4a6588c

In this, he explains how to work with deep links with navigation components. The pinned shortcut builder needs an Intent but the findNavController helper method returns an object of PendingIntent.

The method from the article to get the pendingIntent.

 val pendingIntent = navController
        .createDeepLink()
        .setDestination(R.id.donutEntryDialogFragment)
        .setArguments(arg)
        .createPendingIntent()

The ShortcutInfoBuilder method

val pinShortcutBuilder = ShortcutInfo.Builder(
                              requireContext(),
                              "id"
                              )
pinShortcutBuilder
     .setShortLabel("someLabel")
     .setIntent(intent)  // takes an object of Intent

So, how to create the pinned shortcut?


Solution

  • We create the deep links using URIs, and one of the parameters of the Intent constructor is URI. We can directly pass the URI to the constructor and set the activity as the MainActity(because of the single activity paradigm).

    val intent = Intent(
                          Intent.ACTION_VIEW,
                          "myapp://navdonutcreator.com/donutcreator".toUri(),
                          requireContext(),
                          MainActivity::class.java
                        )
    

    Now use the same URI in the fragment which you want to open.

    <fragment
        android:id="@+id/targetFragment"
        android:name="com.example.myapp.ui.TargetFragment"
        tools:layout="@layout/fragment_target">
        <deepLink
            android:id="@+id/deepLink"
            app:uri="myapp://navdonutcreator.com/donutcreator" />
    </fragment>
    

    Now stitching everything up,

     val shortcutManager = ContextCompat.getSystemService(
                            requireContext(),
                            ShortcutManager::class.java
                        )
    
                        if (shortcutManager != null && shortcutManager.isRequestPinShortcutSupported) {
    
                            val intent = Intent(
                                Intent.ACTION_VIEW,
                                "myapp://navdonutcreator.com/donutcreator".toUri(),
                                requireContext(),
                                MainActivity::class.java
                            )
    
                            val pinShortcutBuilder =
                                ShortcutInfo.Builder(
                                    requireContext(),
                                    "someId"
                                )
                            pinShortcutBuilder.setShortLabel("someLabel)
                                .setIntent(intent)
    
                            val pinShortcutInfo = pinShortcutBuilder.build()
    
                            // Create the PendingIntent object only if your app needs to be notified
                            // that the user allowed the shortcut to be pinned. Note that, if the
                            // pinning operation fails, your app isn't notified. We assume here that the
                            // app has implemented a method called createShortcutResultIntent() that
                            // returns a broadcast intent.
                            val pinnedShortcutCallbackIntent =
                                shortcutManager.createShortcutResultIntent(pinShortcutInfo)
    
                            // Configure the intent so that your app's broadcast receiver gets
                            // the callback successfully.For details, see PendingIntent.getBroadcast().
                            val successCallback = PendingIntent.getBroadcast(
                                requireContext(), 0,
                                pinnedShortcutCallbackIntent, 0
                            )
    
                            shortcutManager.requestPinShortcut(
                                pinShortcutInfo,
                                successCallback.intentSender
                            )
                        }
    

    EDIT

    Android shortcut documentation: https://developer.android.com/guide/topics/ui/shortcuts/creating-shortcuts