> For the complete documentation index, see [llms.txt](https://documentation.pushly.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.pushly.com/integration/implementation-steps/android/sdk-kotlin-java/deep-linking.md).

# Deep Linking

Overview of how the SDK handles deep links and how to perform custom navigation within your application

The PushSDK handles opening of a notification in the following ways:

* By default, the SDK will automatically create a new `ACTION_VIEW` intent using the landing URL attached to the notification.
* If you implement the `onPushSDKDidReceiveNotificationDestination` lifecycle callback you can perform any custom logic needed when the notification is opened.

## Implementing URL Handling Callbacks

The PushSDK provides callbacks that will be called when a subscriber interacts with a notification. These callbacks should be implemented so that the subscriber is automatically navigated to the proper activity after opening the notification.

{% hint style="danger" %}
We recommend putting all SDK callbacks within your application's main `onCreate` method to ensure proper handling of all notification events.
{% endhint %}

When the SDK receives a notification open event it will attempt to call one of the below callbacks with parameters that you can use to navigate the subscriber to the appropriate activity within your app.

In order to implement these callbacks you must have a class that calls the SDK's `registerNotificationLifecycleCallbacks` method and implements the callback(s) within it.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
PushSDK.registerNotificationLifecycleCallbacks(object : PNNotificationLifecycleCallbacks {
    // Add function overrides here
})
```

{% endtab %}

{% tab title="Java" %}

```java
PushSDK.registerNotificationLifecycleCallbacks(new PNNotificationLifecycleCallbacks() {
    // Add function overrides here
});
```

{% endtab %}
{% endtabs %}

For example, if a landing URL was attached to the notification and you implemented the callback to handle subscriber navigation within your `onCreate` method the code may look like this:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
import com.pushly.android.PushSDK
import com.pushly.android.PushSDK.PNNotificationLifecycleCallbacks
import com.pushly.android.PushSDK.PNNotificationInteraction

class MainApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        PushSDK.logLevel = PNLogLevel.INFO
        PushSDK.setConfiguration(appKey = "YOUR_APP_KEY", context = this)

        PushSDK.PushNotifications.showPermissionPrompt(completion = { granted, response, error ->
            error?.let {
                println("Error encountered in permission request: $error")
                return@showNativeNotificationPermissionPrompt
            }

            println("Permissions granted: $granted, response: $response")
        })

        PushSDK.registerNotificationLifecycleCallbacks(object : PNNotificationLifecycleCallbacks {
            override fun onPushSDKDidReceiveNotificationDestination(
                destination: String,
                interaction: PNNotificationInteraction
            ): Boolean {
                // Open the activity for the destination (the Landing URL). It opens in your
                // app's own task; FLAG_ACTIVITY_NEW_TASK is optional from interaction.context.
                interaction.context.startActivity(
                    Intent(interaction.context, ArticleActivity::class.java)
                        .setData(Uri.parse(destination))
                )

                // Return true to inform the SDK that it should not navigate
                return true
            }
        })
    }

}
```

{% endtab %}

{% tab title="Java" %}

```java
import com.pushly.android.PushSDK;
import com.pushly.android.PushSDK.PNNotificationLifecycleCallbacks;
import com.pushly.android.PushSDK.PNNotificationInteraction;

class MainApplication extends Application {

    @Override()
    public void onCreate() {
        super.onCreate();

        PushSDK.setLogLevel(PNLogLevel.INFO);
        PushSDK.setConfiguration("YOUR_APP_KEY", this);

        PushSDK.PushNotifications.showPermissionPrompt((granted, response, error) -> {
            if (error != null) {
                System.out.printf("Error encountered in permission request: %s", error);
            } else {
                System.out.printf("Permissions granted: %b, response: %s" ,granted, response);
            }
            
            return null;
        });

        PushSDK.registerNotificationLifecycleCallbacks(new PNNotificationLifecycleCallbacks() {
            @Override
            public boolean onPushSDKDidReceiveNotificationDestination(@NonNull String destination, @NonNull PNNotificationInteraction interaction) {
                // Open the activity for the destination (the Landing URL). It opens in your
                // app's own task; FLAG_ACTIVITY_NEW_TASK is optional from interaction.getContext().
                Intent intent = new Intent(interaction.getContext(), ArticleActivity.class)
                        .setData(Uri.parse(destination));
                interaction.getContext().startActivity(intent);

                // Return true to inform the SDK that it should not navigate
                return true;
            }
        });
    }

}
```

{% endtab %}
{% endtabs %}

## Notification Interaction Callbacks

### Notification Opened With URI/URL Destination

{% hint style="info" %}
Use this callback when you need to perform custom parsing and/or modification of the attached landing URL that wouldn't be properly handled by opening the URL directly.
{% endhint %}

This callback is invoked when a notification is opened that has destination landing URL attached. The subscriber should be navigated to the view that represents the provided landing URL.

This method expects a Boolean response. If the response is `true` then the SDK will not navigate: your app routes the subscriber, and the SDK only makes sure your app is on screen. If the response is `false` then the SDK will attempt to navigate the subscriber to the destination URL.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
override fun onPushSDKDidReceiveNotificationDestination(
    destination: String,
    interaction: PNNotificationInteraction
): Boolean {
    // Navigate to a activity within your application using the destination (the Landing URL)

    // Return true to inform the SDK that it should not navigate
    return true
}
```

{% endtab %}

{% tab title="Java" %}

```java
@Override
public boolean onPushSDKDidReceiveNotificationDestination(@NonNull String destination, @NonNull PNNotificationInteraction pnNotificationInteraction) {
    // Navigate to a activity within your application using the destination (the Landing URL)

    // Return true to inform the SDK that it should not navigate
    return true;
}
```

{% endtab %}
{% endtabs %}

### Routing a notification yourself

When you return `true`, route the subscriber the way your app normally navigates:

* **If your app opens its own activity** for the destination, start it from within the callback, either from `interaction.context` or from your application context with `Intent.FLAG_ACTIVITY_NEW_TASK`. The activity opens in your app's own task, so Back returns to your app.
* **If your app changes screens inside an activity that is already running** - a single-activity app, or one that routes through Jetpack Compose navigation - navigate as you would for any in-app event. The SDK brings your app forward.

{% hint style="warning" %}
`interaction.context` is only valid while the callback runs. Do not keep it to start an activity later (for example after an asynchronous lookup): start later navigation from your application context with `Intent.FLAG_ACTIVITY_NEW_TASK`.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://documentation.pushly.com/integration/implementation-steps/android/sdk-kotlin-java/deep-linking.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
