# Örnek-7: Navigation Komponenti ile Deep Links Kullanımı

Kullanılabilecek iki tip deep links türü vardır, Explicit (Açık) ve Implicit (Üstü Kapalı). Deep Links'in özelliği ise kullanıldığında sizi doğrudan bir uygulamadaki belirli bir hedefe götüren bir bağlantı olmasıdır. Bu kavramları zaten Android Developer'lar intent konusundan yakınen tanıyorlar. Bu yüzden ne olduklarını açıklamaktan öte, Navigation ile kullanımının nasıl olduğunu inceleyeceğiz.

Kullanılabilecek iki tip deep links türü vardır.

Kullanılabilecek iki tip **deep links** türü vardır, **Explicit (Açık)** ve **Implicit (Üstü Kapalı)**. **Deep Links**'in özelliği ise kullanıldığında sizi doğrudan bir uygulamadaki belirli bir hedefe götüren bir bağlantı olmasıdır. Bu kavramları zaten **Android Developer**'lar **intent** konusundan yakınen tanıyorlar. Bu yüzden ne olduklarını açıklamaktan öte, **Navigation** ile kullanımının nasıl olduğunu inceleyeceğiz.

## **Explicit (Açık) deep link**

**Explicit (Açık) intent**, kullanımları arasında en popülerleri olanları uygulama **widget**'ları ve **notification**'lar (bildirimler) dır. Biz de **Explicit deep link** örneğimizde bildirimlerden faydalanacağız.&#x20;

Öncelikle senaryomuzu belirtelim. Biliyorsunuz devam eden örneğimizde **blankFragment4** içerisinde **nameField** isimli bir argüman alıyoruz. Bu argümanı da **blankFragment** içerisinden bulunan **EditText'**&#x69; doldurup, parametre olarak **blankFragment4**'te görüntülüyorduk.

Şimdi ise direkt olarak **blankFragment4** sayfasını açıp, o sayfaya yerleştirmiş olduğumuz butona tıklayıp bir **notification** çıkmasını sağlayacağız. Bu notification'a tıklandığında ise tekrar **blankFragment4** sayfasını açacağız ama argümanımız ile birlikte.

İlk olarak **blankFragment4**'e ait **fragment\_blank\_fragment4.xml** dosyasını açıp, içerisini aşağıdaki gibi düzenliyoruz.

```markup
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tvMessage"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/hello_blank_fragment4" />

    <Button
        android:id="@+id/btnSendNotificationButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send Notification"
        tools:ignore="HardcodedText"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvMessage" />

</androidx.constraintlayout.widget.ConstraintLayout>
```

Buna göre görüntümüz de şu şekilde oluşmuş oldu.

![BlankFragment4](https://2300662549-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M-9we-f91sgtHSNx_N3%2F-M0vo-Ojrgj3pnVAjgMr%2F-M0voqsVx-5MeFnEOOO5%2F041.jpeg?alt=media\&token=a8ad1f59-6993-4ac9-a5ab-7813c11cd09b)

Senaryomuza göre "**Send Notification**" butonuna tıkladığımızda bir notification çıkmasını istiyoruz. Bunun için de **BlankFragment4.kt** dosyamızı aşağıdaki gibi düzenliyorum.

```kotlin
override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    tvMessage.text = "Diğer sayfadan gelen veri: " + arguments?.getString("nameField")

    val notificationButton = view?.findViewById<Button>(R.id.btnSendNotificationButton)
    notificationButton?.setOnClickListener {
        val args = Bundle()
        args.putString("nameField", "Egemen")

        val deeplink = findNavController().createDeepLink()
            .setDestination(R.id.blankFragment4)
            .setArguments(args)
            .createPendingIntent()

        val notificationManager =
            context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationManager.createNotificationChannel(
                NotificationChannel(
                "deeplink", "Navigation ile Deep Link", NotificationManager.IMPORTANCE_HIGH)
            )
        }

        val builder = NotificationCompat.Builder(
            context!!, "deeplink")
            .setContentTitle("Navigation Component")
            .setContentText("Bildirimden Android uygulamasına Deep link için tıklayın.")
            .setSmallIcon(android.R.drawable.ic_dialog_alert)
            .setContentIntent(deeplink)
            .setAutoCancel(true)
        notificationManager.notify(0, builder.build())
    }
}
```

Kodumuzu biraz anlatalım. Biliyorsunuz yukarıda da bahsetmiştik. **blankFragment4** için **nameField** isimli bir argümanımız var. **Notification** üzerindeki **deep link** ile bu alanı dolduracağız. Bu sebeble **nameField** ismi ile bir **Bundle** oluşturduk ve içerisine **Egemen** değerini verdik.

**Satır 11**'den itibaren **NavController**'a ait **createDeepLink** metodunu kullanarak hedefimizi **blankFragment4** olarak belirleyip, argüman alanına da oluşturduğumuz **Bundle**'ı almasını sağladık.

Sonrasında standart notification kodlarımızı hazırladıktan sonra **30. Satır**daki **setContentIntent**'ine hazırladığımız **deeplink** isimli **intent**i atadık. Artık "**Send Notification**" butonuna tıklayarak **notification**'ı aşağıdaki gibi gönderebiliriz.

![Notification Görüntüsü](https://2300662549-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M-9we-f91sgtHSNx_N3%2F-M0vo-Ojrgj3pnVAjgMr%2F-M0vpSwhlNLp3xDn2Mr9%2F042.jpeg?alt=media\&token=e40b9960-2817-40cd-9909-11a9bc3156fc)

**Notification**'a tıkladığınızda ise uygulamamızda **BlankFragment4** sayfası açılacak ve **Bundle** içerisinde verdiğimiz **Egemen** değeri sayfa içerisinde aşağıdaki gibi görüntülenecektir.

![BlankFragment4](https://2300662549-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M-9we-f91sgtHSNx_N3%2F-M0vo-Ojrgj3pnVAjgMr%2F-M0vppuI3EFEAWarxvmd%2F043.jpeg?alt=media\&token=22fd15dc-2093-4913-9a16-9fc043ec4e34)

Yukarıdaki örneğimizdeki **Explicit (Açık) deep link** kullanımını **notification**lar aracılığı ile yapmış olduk.

Aynı kullanım şeklini istersek **widget**'lar ile de yapabiliriz. Bunun için birkaç yeni dosyaya da ihtiyacımız olacak. Şimdi hızlıca onları hazırlayalım.

Hazırlayacağımız **widget**'a ait sınıfı oluşturmak için aşağıdaki **DeepLinkAppWidget.kt** class'ı hazırlıyoruz.

```kotlin
class DeepLinkAppWidget : AppWidgetProvider() {
    override fun onUpdate(
        context: Context?,
        appWidgetManager: AppWidgetManager?,
        appWidgetIds: IntArray?
    ) {
        val remoteViews = RemoteViews(
            context?.packageName,
            R.layout.deep_link_appwidget
        )

        val args = Bundle()
        args.putString("nameField", "Widget'tan gelen veri")

        val pendingIntent = NavDeepLinkBuilder(context!!)
                .setGraph(R.navigation.nav_graph)
                .setDestination(R.id.blankFragment4)
                .setArguments(args)
                .createPendingIntent()

        remoteViews.setOnClickPendingIntent(R.id.btnDeepLinkButton, pendingIntent)

        appWidgetManager?.updateAppWidget(appWidgetIds, remoteViews)
    }
}
```

Burada görüntülenecek olan **widget**'ın taşıyacağı değer, nereye tıklanacağı ve hedefin ne olduğu aynı **notification** örneğimizde olduğu gibi burada hazırlanıyor. Şimdi hazırladığımız bu class'ı **AndroidManifest.xml** dosyasında application etiketlerinin arasında tanımlayalım.

```kotlin
<receiver android:name=".DeepLinkAppWidget">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>

    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/deep_link_appwidget_info" />
</receiver>
```

Dikkat ettiyseniz **@xml/deep\_link\_appwidget\_info** altında bir resource dosyamız bulunuyor. Bunun için **res** klasörü altında bir **xml** klasörü oluşturup, içerisinde de **deep\_link\_appwidget\_info.xml** dosyasını aşağıdaki gibi oluşturalım.

```kotlin
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="120dp"
    android:minHeight="60dp"
    android:updatePeriodMillis="0"
    android:initialLayout="@layout/deep_link_appwidget"/>
```

Burada da **appwidget**'ımızı oluşturacak **initialLayout**'u için **@layout/deep\_link\_appwidget** dosyasını aşağıdaki gibi oluşturalım.

```kotlin
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/btnDeepLinkButton"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Deep Link Button" />
```

Böylelikle **widget**'ımız da hazır durumda. Artık uygulamamız için olan widget'ınızı ekranınıza aşağıdaki gibi ekleyebilirsiniz.

![Telefonumuzun ekranına eklediğimiz uygulama widget'ı](https://2300662549-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M-9we-f91sgtHSNx_N3%2F-M0vsM--Ur-oj5KlVn3Y%2F-M0vyXg0tW1TxN4JkMiA%2F044.jpeg?alt=media\&token=0c0fde26-f444-48d3-ab29-7fcc1819ce82)

**Widget**'a tıkladığımızda ise aynen **notification**'da olduğu gibi hedef olarak belirlediğimiz **BlankFragment4** sayfasını açacak ve **Bundle** içerisinde belirttiğimiz veriyi de ekranda gösterecektir.

![BlankFragment4 üzerinde Widget'tan gelen veri görüntülenir](https://2300662549-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M-9we-f91sgtHSNx_N3%2F-M0vsM--Ur-oj5KlVn3Y%2F-M0vysyLtQFki2U26C55%2F045.jpeg?alt=media\&token=7aaacaa5-159a-4b89-8c35-bc5370a3469b)

Buraya kadar olan bölümde hem **notification**'larla hem de **widget**'larla  **Explicit (Açık) deep link** kullanımını örneklemiş olduk.

Şimdiki örneğimiz ise **Implicit (Üstü Kapalı) deep link** kullanımına yönelik olacak.

## **Implicit (Üstü Kapalı) deep link**

**Implicit deep link**'ler **web url**'leri ve **özel uri şema**larını içerir.

Hemen örneğimizi yapmak için hazırlıklara başlayalım. İlk olarak **nav\_graph.xml** içerisinde **blankFragment4** içerisinde aşağıdaki bir **deep link** ekleyelim.

```kotlin
<fragment
    android:id="@+id/blankFragment4"
    android:name="com.etiya.jpnavigation1.BlankFragment4"
    android:label="fragment_blank_fragment4"
    tools:layout="@layout/fragment_blank_fragment4">
    <action
        android:id="@+id/action_blankFragment4_to_blankFragment5"
        app:destination="@id/blankFragment5" />
    <argument
        android:name="nameField"
        app:argType="string" />
    <deepLink
        android:id="@+id/blankFragment4WebDeepLink"
        app:uri="https://www.testurladresim.com/{nameField}" />
</fragment>
```

> Ben ekleme işlemini XML yani kod üzerinden gerçekleştirdim. Ancak önceki örneklerimizden de bildiğiniz gibi bunu nav\_graph üzerindeki design bölümünden de yapabilirsiniz. Hangisi kolayınıza geliyorsa..

Bu arada **AndroidManifest.xml** dosyası içerisinde aşağıdaki gibi **nav\_graph**'ı eklemeyi de unutmayalım. Aksi durumda **deeplink**'i eklediğimiz bölüm **uygulama** ve **işletim sistemi** tarafından tanınmayacaktır.

```kotlin
<activity android:name=".MainActivity" android:theme="@style/AppTheme.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <nav-graph android:value="@navigation/nav_graph" />
</activity>
```

Bu işlemi de gerçekleştirdiğimize göre aşağıdaki gibi test edebiliriz.&#x20;

**nav\_graph**'ta tanımladığımız gibi bir URL'yi&#x20;

```kotlin
https://www.testurladresim.com/{nameField}
```

**WhatsApp** üzerinden arkadaşımıza aşağıdaki gibi gönderdiğimizi farzedelim.&#x20;

![](https://2300662549-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M-9we-f91sgtHSNx_N3%2F-M1-YLUOls4zJ1U_LuSx%2F-M1-jvJcLRVdEoKZHrj-%2F046.jpeg?alt=media\&token=8a26a241-38c6-4399-8f7a-05d40332390a)

Arkadaşımız bu linke tıkladığında işletim sistemi, aşağıdaki gibi bu bir URL olduğundan dolayı bir tarayıcı ile mi? yoksa uygulamamızla mı açmak istediğinizi soracaktır.

![](https://2300662549-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M-9we-f91sgtHSNx_N3%2F-M1-YLUOls4zJ1U_LuSx%2F-M1-kADf-rzA3gftyWQh%2F047.jpeg?alt=media\&token=3c2f279f-c69d-4670-9adb-73d64f949b08)

Uygulamayı seçtiğinizde ise aşağıdaki gibi linkte bulunan parametre uygulamamız tarafından alınacaktır.

![](https://2300662549-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M-9we-f91sgtHSNx_N3%2F-M1-YLUOls4zJ1U_LuSx%2F-M1-kJM_SW6NpWu2m7ct%2F048.jpeg?alt=media\&token=273e90b3-590c-4dbb-973d-4297ba5cf47b)

Yine aynı şekilde bu işlemi bir **URI** şeması şeklinde de gerçekleştirebiliriz.

Bunun için **nav\_graph.xml** dosyasını tekrar açıp aşağıdaki gibi URI şemasını kullanacak deeplink'i ekliyorum.

```kotlin
<fragment
    android:id="@+id/blankFragment4"
    android:name="com.etiya.jpnavigation1.BlankFragment4"
    android:label="fragment_blank_fragment4"
    tools:layout="@layout/fragment_blank_fragment4">
    <action
        android:id="@+id/action_blankFragment4_to_blankFragment5"
        app:destination="@id/blankFragment5" />
    <argument
        android:name="nameField"
        app:argType="string" />
    <deepLink
        android:id="@+id/blankFragment4WebDeepLink"
        app:uri="https://www.testurladresim.com/{nameField}" />
    <deepLink
        android:id="@+id/blankFragment4DeepLink"
        app:uri="exampleapp://name/{nameField}" />
</fragment>
```

Gördüğünüz üzere URI şemamız aşağıdaki gibi tanımladık.

```kotlin
exampleapp://name/{nameField}
```

Test edebilmek için de [Google'ın önerdiği](https://developer.android.com/training/app-links/deep-linking) gibi Terminal'i kullanarak yapacağız.

Bunun için **terminal**'i açıp aşağıdaki komut satırını giriyorum.

```kotlin
adb shell am start -W -a android.intent.action.VIEW -d "exampleapp://name/egemen" com.etiya.jpnavigation1
```

![Terminal'den üstteki komut satırını çalıştırdım](https://2300662549-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M-9we-f91sgtHSNx_N3%2F-M1-YLUOls4zJ1U_LuSx%2F-M1-mNHgNGGftRL5MQO_%2F049.png?alt=media\&token=67176679-02a5-4f56-b4d8-d01cfb2927cc)

İşlem gerçekleştiğinde bilgisayarıma bağlı olan cep telefonumda uygulamamız kapalı olduğu halde açıldı ve aşağıdaki gibi deeplink'te belirttiğimiz sayfamıza gönderdiğimiz argüman ile gelmiş oldu.

![](https://2300662549-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M-9we-f91sgtHSNx_N3%2F-M1-YLUOls4zJ1U_LuSx%2F-M1-kJM_SW6NpWu2m7ct%2F048.jpeg?alt=media\&token=273e90b3-590c-4dbb-973d-4297ba5cf47b)
