Skip to content

How to use "deeplink" to land user to a particular app page?

Alexander Boldyrev edited this page Oct 30, 2024 · 4 revisions

This page describes one of the approaches of handling deep links in your app when user taps on a notification.

How to send deep link within the message

First you will need to identify the schema for your deep link, usually it is reverse DNS notation: com.infobip.mobilemessaging://deeplink/. And also define screens that you want to open as part of deep link such as redScreen, greenScreen, blueScreen. And then it will be possible to send deep link with message and to handle notificationTapped or notificationActionTapped event.

To send message with deeplink parameter via Broadcast or Flow choose "Mobile Push" channel and specify action button properties:

  • Action: Open Page in Mobile App
  • Deep Link: com.infobip.mobilemessaging://deeplink/redScreen/greenScreen/blueScreen

Also, you can provide deeplink for push or Mirror In-App message using API by specifying notificationOptions.primaryButtonAction as follows:

"notificationOptions": {
    "primaryButtonAction": {
        "resource": "com.infobip.mobilemessaging://deeplink/redScreen/greenScreen/blueScreen",
        "type": "DEEP_LINK"
    }
}

Example of the code implementation

  1. Let's create a simple activity that will receive Message together with intent and display message text in the middle of the screen. With following layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl_screen"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Text"
        android:textAppearance="@style/TextAppearance.AppCompat.Headline"/>

</RelativeLayout>

And following activity class:

class RedScreenActivity : AppCompatActivity() {
    public override fun onCreate(@Nullable savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_colored_screen)
        val layout: View = findViewById(R.id.rl_screen)
        layout.setBackgroundColor(Color.RED)
        val message = Message.createFrom(intent.extras)
        val tv: TextView = findViewById<View>(R.id.tv_text) as TextView
        if (message != null) {
            tv.text = message.body
        } else {
            tv.text = R.string.no_message_provided
        }
    }

    protected abstract val backgroundColor: Int
}
expand to see Java code

class RedScreenActivity extends AppCompatActivity {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_colored_screen);

        View layout = findViewById(R.id.rl_screen);
        layout.setBackgroundColor(Color.RED);

        Message message = Message.createFrom(getIntent().getExtras());
        TextView tv = (TextView) findViewById(R.id.tv_text);
        if (message != null) {
            tv.setText(message.getBody());
        } else {
            tv.setText(R.string.no_message_provided);
        }

    }

    protected abstract int getBackgroundColor();
}
  1. Then we will create a list of such screens and assign appropriate identifiers for the screens
val activityMap: Map<String, Class<out Activity>> = object: HashMap<String, Class<out Activity>>() {
    init {
        UIManager.put("redScreen", RedScreenActivity::class.java)
        UIManager.put("greenScreen", GreenScreenActivity::class.java)
        UIManager.put("blueScreen", BlueScreenActivity::class.java)
    }
}
expand to see Java code

final Map<String, Class<? extends Activity>> activityMap = new HashMap<String, Class<? extends Activity>>() {{
    put("redScreen", RedScreenActivity.class);
    put("greenScreen", GreenScreenActivity.class);
    put("blueScreen", BlueScreenActivity.class);
}};
where `RedScreenActivity.class`, `GreenScreenActivity.class`, `BlueScreenActivity.class` are simple activity screens that vary only by background color.
  1. Now let's register deep link in the manifest so that your application can handle it. Make sure to register your proprietary deep link in your activity, com.infobip.mobilemessaging://deeplink is here just as an example.
<activity
    android:name=".screens.DeepLinkLandingActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- Accepts URIs that begin with "com.infobip.mobilemessaging://deeplink" -->
        <data
            android:host="deeplink"
            android:scheme="com.infobip.mobilemessaging" />
    </intent-filter>
</activity>

And then we can process our deep link and create a stack of activities:

class DeepLinkLandingActivity : AppCompatActivity() {
    // ...
    override fun onCreate(@Nullable savedInstanceState: Bundle?) {
        // ...
        processDeepLink()
    }

    private fun processDeepLink() {
        val intent: Intent = intent
        val stackBuilder: TaskStackBuilder = TaskStackBuilder.create(this)
        for (segment in intent.data?.pathSegments!!) {
            if (activityMap.containsKey(segment)) {
                val nextIntent: Intent = Intent(this, activityMap.get(segment)).putExtras(intent)
                stackBuilder.addNextIntent(nextIntent)
            }
        }
        stackBuilder.startActivities()
    }
}
expand to see Java code

public class DeepLinkLandingActivity extends AppCompatActivity {

    // ...

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    	// ...
        processDeepLink();
    }

    private void processDeepLink() {
        Intent intent = getIntent();
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        for (String segment : intent.getData().getPathSegments()) {
            if (activityMap.containsKey(segment)) {
                Intent nextIntent = new Intent(this, activityMap.get(segment)).putExtras(intent);
                stackBuilder.addNextIntent(nextIntent);
            }
        }
        stackBuilder.startActivities();
    }
}

After that DeepLinkLandingActivity will be able to process deep links and to create stack of screens that we registered earlier.

  1. Let's implement notificationTapped event handling and initiate processing of a deep link (for handling action button tap actionTappedevent needs to be handled instead):
val notificationTappedReceiver: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent) {
            val message: Message = Message.createFrom(intent.extras) ?: return
            val deepLink: String = message.deeplink
            if (deepLink.isEmpty()) return
            
            val deepLinkIntent = Intent(Intent.ACTION_VIEW)
            deepLinkIntent.data = Uri.parse(deepLink)
            deepLinkIntent.putExtras(messageToBundle(message))
            if (deepLinkIntent.resolveActivity(packageManager) != null) {
                startActivity(deepLinkIntent)
            }
        }
    }
expand to see Java code

final BroadcastReceiver notificationTappedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Message message = Message.createFrom(intent.getExtras());
            if (message == null) return;
            String deepLink = message.getDeeplink();
            if (deepLink.isEmpty()) return;

            Intent deepLinkIntent = new Intent(Intent.ACTION_VIEW);
            deepLinkIntent.setData(Uri.parse(deepLink));
            deepLinkIntent.putExtras(messageToBundle(message));
            if (deepLinkIntent.resolveActivity(getPackageManager()) != null) {
                startActivity(deepLinkIntent);
            }
        }
    };
The only thing left is to create deep link and send it. When `notificationTapped` event will be processed, several activities will be opened one on top of another accordingly to the sequence of screens in the deep link.

Full source code can be found in Firebase example application and Huawei example application.

Notice:

From version 12.x onwards, HTTP is disabled by default for security reasons, see migration guide for more information.

Clone this wiki locally