Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deep linking with splash screen and login state

I use Navigation Component. I have app with 2 main parts: 1 splash activity with it's nav_graph 2 main activity with bottom navigation where every menu item has its own nav_graph. The problem is that i cant figure out how to do navigation when notification pops up.

So when notification arrived and user clicked on it, i need: - check if app is open and what screen is open now - if app is closed or in background, through deep link, check at splash activity: if user is logged in - move to main activity (if not provide auth screen) keep navigation on deep link to fragment I need.

Splash graph and one of three memu items graphs

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/splash_graph"
            app:startDestination="@id/splashFragment">

    <fragment android:id="@+id/splashFragment"
              android:name="com.app.app.ui.navigation.fragment.SplashFragment"
              android:label="SplashFragment">

        <action android:id="@+id/action_splashFragment_to_authFragment"
                app:popUpTo="@+id/authFragment"
                app:popUpToInclusive="true"
                app:destination="@id/authFragment"/>

        <action android:id="@+id/action_splashFragment_to_mainActivity"
                app:popUpTo="@+id/mainActivity"
                app:popUpToInclusive="true"
                app:destination="@id/mainActivity" app:launchSingleTop="true"/>
    </fragment>

    <fragment android:id="@+id/authFragment"
              android:name="com.app.app.ui.navigation.fragment.AuthFragment"
              android:label="AuthFragment">

        <action android:id="@+id/action_authFragment_to_mainActivity"
                app:popUpTo="@+id/mainActivity"
                app:popUpToInclusive="true"
                app:destination="@id/mainActivity" app:launchSingleTop="true"/>
    </fragment>

    <activity android:id="@+id/mainActivity"
              android:name="com.app.app.ui.navigation.activity.MainActivity"
              android:label="MainActivity">
        <deepLink android:id="@+id/deepLinkMain" app:uri="com.app.app/"/>
    </activity>


</navigation>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
            android:id="@+id/nextFragment"
            app:startDestination="@id/nxtFragment">

    <fragment android:id="@+id/nxtFragment"
              android:name="com.app.app.ui.navigation.fragment.NextFragment"
              android:label="Next">
        <deepLink
                android:id="@+id/deepLink"
                app:uri="com.app.app/nextFragment{id}"
                android:autoVerify="true"/>
        <argument
                android:name="id"
                app:argType="string"/>
    </fragment>
</navigation>
like image 569
Віталій Шимко Avatar asked Apr 24 '19 13:04

Віталій Шимко


People also ask

What is linking and deep linking?

Deep linking does this by specifying a custom URL scheme (iOS Universal Links) or an intent URL (on Android devices) that opens your app if it's already installed. Deep links can also be set to direct users to specific events or pages, which could tie into campaigns that you may want to run.

What is deep linking example?

A deep link is a URL link that is generated, when anyone clicks on that link our app will be open with a specific activity or a screen. Using this URL we can send a message to our app with parameters. In WhatsApp, we can generate a deep link to send a message to a phone number with some message in it.

What does Added by deep link mean on Snapchat?

From today, media partners will be able to promote their channels on Snapchat via deep links - which means publishers will be able to link to their Snapchat content direct from one app to another, making it easier to promote, share and (at least in some regard) measure the performance of Snapchat content.


1 Answers

You can do it using pending intent, suppose you get data payload like below :

{
      "title":"Title",
      "message":"message test",
      "data":{
             "meta":{
                "notificationType":"1",
                 "name":"Rjz"
                    }
             }
}

and as per notificationType you have to open specific screen then you can do following :

sendNotification("msg","title",remoteMessage.data)

private fun sendNotification(messageBody: String,title: String?,data: MutableMap<String, String>) {

    val intent = Intent(this, SplashActivity::class.java)
    intent.putExtra("meta", data["meta"])
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
    val pendingIntent = PendingIntent.getActivity(
        this, 0 /* Request code */, intent,
        PendingIntent.FLAG_ONE_SHOT
    )

    val channelId = getString(R.string.default_notification_channel_id)
    val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
    val notificationBuilder = NotificationCompat.Builder(this, channelId)

    notificationBuilder.setSmallIcon(R.drawable.ic_app_logo)
        .setContentTitle(title)
        .setContentText(messageBody)
        .setAutoCancel(true)
        .setStyle(NotificationCompat.BigTextStyle())
        .setSound(defaultSoundUri)
        .setContentIntent(pendingIntent)

    val notificationManager =
        getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

    // Since android Oreo notification channel is needed.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channel = NotificationChannel(
            channelId,
            "Channel human readable title",
            NotificationManager.IMPORTANCE_DEFAULT
        )
        notificationManager.createNotificationChannel(channel)
    }

    notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
}

and in splash screen you can check that pending intent data , like this :

val metaString: String? = if (intent.hasExtra("meta")) {
                intent.extras.get("meta").toString()
            } else {
                null
            }
    var gson = Gson()   
    var pushData = gson.fromJson(
                    metaString,
                    YourModel::class.java
                )       
    if(pushData.notificationType==1){
    NavDeepLinkBuilder(this@SplashActivity)
            .setComponentName(MainActivity::class.java)
            .setGraph(R.navigation.name_of_nav_graph)
            .setDestination(R.id.your_dstination_fragment)
            .setArguments(bundleOf(
                         "name" to pushData.name)
                         ).createTaskStackBuilder().startActivities()
    }

You can also pass argument if you want to pass.

its an easy way to do in such cases. let me know if you stuck anywhere. enjoy..!!

like image 62
Rjz Satvara Avatar answered Oct 01 '22 01:10

Rjz Satvara