📖 PrzeglądOverview

Moduł DeepLinks pozwala na łatwą obsługę deep linków w aplikacji Android. Obsługuje wzorce URL z parametrami, walidację scheme i hostów oraz automatyczneSupports URL patterns with parameters, scheme and host validation, and automatic wyciąganie parametrów z ścieżki i query string.The DeepLinks module enables easy deep link handling in your Android app. Supports URL patterns with parameters, scheme and host validation, and automatic parameter extraction from path and query string.

Szybki przykładQuick Example
// Rejestracja handlera
ADict.DeepLinks.register("product/{id}") { params ->
    val productId = params["id"]
    openProduct(productId)
}

// W Activity.onCreate
ADict.DeepLinks.handle(intent)

⚙️ KonfiguracjaConfiguration

configure(schemes, hosts)

SkonfigurujConfigure dozwolone schematy URI i hosty.

ParametryParameters:

  • schemes: List<String> - Lista dozwolonych schematów (domyślnie: ["https", "http"])List of allowed schemes (default: ["https", "http"])
  • hosts: List<String> - Lista dozwolonych hostów (pusta = wszystkie)List of allowed hosts (empty = all)
PrzykładExample konfiguracji
// Konfiguracja dla aplikacji
ADict.DeepLinks.configure(
    schemes = listOf("https", "http", "myapp"),
    hosts = listOf("myapp.com", "www.myapp.com")
)

// Własny scheme (np. myapp://product/123)
ADict.DeepLinks.configure(
    schemes = listOf("myapp"),
    hosts = emptyList() // Wszystkie hosty
)
⚠️ Uwaga: Jeśli skonfigurujesz hosty, linki z innych hostów będą odrzucane.If you configure hosts, links from other hosts will be rejected. Pusta lista hostów oznacza akceptację wszystkich.An empty host list means accepting all.

📝 Rejestracja handlerówHandler Registration

register(pattern, handler)

Zarejestruj handler dla wzorca URL.Register handler for URL pattern.

ParametryParameters:

  • pattern: String - WzorzecPattern URL z parametrami w nawiasach klamrowychURL pattern with parameters in curly braces
  • handler: (Map<String, String>) -> Unit - Callback z mapą parametrówCallback with parameter map

Składnia wzorcówPattern Syntax

WzorzecPattern PrzykładExampleowy URL ParametryParameters
product/{id} /product/123 {"id": "123"}
user/{userId}/post/{postId} /user/42/post/99 {"userId": "42", "postId": "99"}
search?q={query} /search?q=kotlin {"query": "kotlin"}
category/{cat}/item/{id} /category/electronics/item/456 {"cat": "electronics", "id": "456"}
Rejestracja wielu handlerówRegistering Multiple Handlers
// Strona produktu
ADict.DeepLinks.register("product/{id}") { params ->
    val productId = params["id"] ?: return@register
    navigateToProduct(productId)
}

// Profil użytkownika
ADict.DeepLinks.register("user/{userId}") { params ->
    val userId = params["userId"] ?: return@register
    navigateToProfile(userId)
}

// Post użytkownika
ADict.DeepLinks.register("user/{userId}/post/{postId}") { params ->
    val userId = params["userId"]
    val postId = params["postId"]
    navigateToPost(userId, postId)
}

// Wyszukiwanie z query params
ADict.DeepLinks.register("search") { params ->
    val query = params["q"] ?: ""
    val category = params["category"]
    searchProducts(query, category)
}

// Domyślny handler dla niedopasowanych linków
ADict.DeepLinks.setDefaultHandler { uri ->
    Log.d("DeepLinks", "Nieobsługiwany link: $uri")
    openWebView(uri.toString())
    true // true = obsłużono, false = nie obsłużono
}

unregister(pattern)

Usuń zarejestrowany handler.Remove registered handler.

ParametryParameters:

  • pattern: String - WzorzecPattern do usunięciaPattern to remove

clear()

Wyczyść wszystkie zarejestrowane handlery i domyślny handler.Clear all registered handlers and default handler.

🔄 Obsługa linkówLink Handling

handle(intent: Intent?): DeepLinkResult

Obsłuż Intent zawierający deep link.Handle Intent containing a deep link.

ParametryParameters:

  • intent: Intent? - Intent z ActivityIntent from Activity

ZwracaReturns:

DeepLinkResult - Wynik obsługi linkuLink handling result

handle(uri: Uri): DeepLinkResult

Obsłuż URI bezpośrednio.Handle URI directly.

handle(url: String): DeepLinkResult

Obsłuż string URL.Handle string URL.

Obsługa w ActivityHandling in Activity
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Obsługa deep linka z onCreate
        handleDeepLink(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // Obsługa deep linka gdy Activity jest już uruchomione
        intent?.let { handleDeepLink(it) }
    }

    private fun handleDeepLink(intent: Intent) {
        val result = ADict.DeepLinks.handle(intent)

        when {
            result.matched -> {
                Log.d("DeepLinks", "Dopasowano wzorzec: ${result.pattern}")
                Log.d("DeepLinks", "Parametry: ${result.params}")
            }
            result.uri != null -> {
                Log.d("DeepLinks", "Niedopasowany link: ${result.uri}")
            }
            else -> {
                Log.d("DeepLinks", "Brak deep linka w Intent")
            }
        }
    }
}

🧪 TestowanieTesting

test(uri: Uri): DeepLinkResult

Testuj dopasowanie URL bez wykonywania handlera.

ParametryParameters:

  • uri: Uri - URI do przetestowania

ZwracaReturns:

DeepLinkResult - Wynik testu (bez wywołania handlera)DeepLinkResult - Test result (without calling handler)

test(url: String): DeepLinkResult

Testuj dopasowanie string URL.

Testowanie dopasowańTesting Matches
// Testowanie bez wykonywania akcji
val result1 = ADict.DeepLinks.test("https://myapp.com/product/123")
println("Matched: ${result1.matched}")          // true
println("Pattern: ${result1.pattern}")          // "product/{id}"
println("Params: ${result1.params}")            // {id=123}

val result2 = ADict.DeepLinks.test("https://myapp.com/unknown/path")
println("Matched: ${result2.matched}")          // false

// Przydatne do unit testów
@Test
fun testProductDeepLink() {
    ADict.DeepLinks.register("product/{id}") { }

    val result = ADict.DeepLinks.test("https://myapp.com/product/456")

    assertTrue(result.matched)
    assertEquals("product/{id}", result.pattern)
    assertEquals("456", result.params["id"])
}

🔧 Budowanie URL

build(pattern, params, scheme, host): String

Wygeneruj deep link URL z wzorca i parametrów.

ParametryParameters:

  • pattern: String - WzorzecPattern URL
  • params: Map<String, String> - Mapa parametrów
  • scheme: String - Schemat URLURL scheme (domyślnie: "https")
  • host: String - Host URLURL host (domyślnie: "")

ZwracaReturns:

String - Wygenerowany URL

Budowanie URL
// Budowanie URL produktu
val productUrl = ADict.DeepLinks.build(
    pattern = "/product/{id}",
    params = mapOf("id" to "123"),
    scheme = "https",
    host = "myapp.com"
)
// Wynik: https://myapp.com/product/123

// Budowanie URL z wieloma parametrami
val postUrl = ADict.DeepLinks.build(
    pattern = "/user/{userId}/post/{postId}",
    params = mapOf("userId" to "42", "postId" to "99"),
    scheme = "myapp",
    host = ""
)
// Wynik: myapp:///user/42/post/99

// Bez hosta (relatywny URL)
val relativeUrl = ADict.DeepLinks.build(
    pattern = "/search?q={query}",
    params = mapOf("query" to "kotlin android")
)
// Wynik: /search?q=kotlin%20android

getRegisteredPatterns(): List<String>

Pobierz listę wszystkich zarejestrowanych wzorców.Get list of all registered patterns.

ZwracaReturns:

List<String> - Lista wzorców

📦 Klasy danychData Classes

data class DeepLinkResult

Wynik parsowania deep linka.

  • matched Boolean Czy link został dopasowany do wzorcaWhether link was matched to a pattern
  • pattern String? Dopasowany wzorzec (null jeśli nie dopasowano)Matched pattern (null if not matched)
  • params Map<String, String> Mapa wyciągniętych parametrówMap of extracted parameters
  • uri Uri? Oryginalny URI

data class DeepLinkHandler

Wewnętrzna klasa reprezentująca zarejestrowany handler.Internal class representing a registered handler.

  • pattern String Oryginalny wzorzec
  • regex Pattern Skompilowany regex
  • paramNames List<String> Lista nazw parametrów
  • callback (Map<String, String>) -> Unit Funkcja callback

💡 PrzykładyExamples praktyczne

E-commerce App

Pełna konfiguracjaFull Configuration dla sklepu
class ShopApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        ADict.init(this, BuildConfig.DEBUG)
        setupDeepLinks()
    }

    private fun setupDeepLinks() {
        ADict.DeepLinks.configure(
            schemes = listOf("https", "myshop"),
            hosts = listOf("myshop.com", "www.myshop.com")
        )

        // Produkt
        ADict.DeepLinks.register("product/{productId}") { params ->
            val productId = params["productId"] ?: return@register
            Navigator.navigateToProduct(productId)

            // Analytics
            ADict.Analytics.log("deep_link_product", mapOf(
                "product_id" to productId
            ))
        }

        // Kategoria
        ADict.DeepLinks.register("category/{categoryId}") { params ->
            val categoryId = params["categoryId"] ?: return@register
            Navigator.navigateToCategory(categoryId)
        }

        // Wyszukiwanie
        ADict.DeepLinks.register("search") { params ->
            val query = params["q"] ?: ""
            val category = params["category"]
            val sort = params["sort"] ?: "relevance"
            Navigator.navigateToSearch(query, category, sort)
        }

        // Koszyk
        ADict.DeepLinks.register("cart") { _ ->
            Navigator.navigateToCart()
        }

        // Promocja
        ADict.DeepLinks.register("promo/{code}") { params ->
            val promoCode = params["code"] ?: return@register
            applyPromoCode(promoCode)
            Navigator.navigateToCart()
        }

        // Domyślny handler
        ADict.DeepLinks.setDefaultHandler { uri ->
            // Otwórz w WebView dla nieznanych linków
            Navigator.navigateToWebView(uri.toString())
            true
        }
    }
}

Social Media App

KonfiguracjaConfiguration dla social media
private fun setupDeepLinks() {
    ADict.DeepLinks.configure(
        schemes = listOf("https", "socialapp"),
        hosts = listOf("socialapp.io")
    )

    // Profil użytkownika
    ADict.DeepLinks.register("user/{username}") { params ->
        val username = params["username"] ?: return@register
        viewModel.loadUserProfile(username)
    }

    // Profil po ID
    ADict.DeepLinks.register("users/{userId}") { params ->
        val userId = params["userId"] ?: return@register
        viewModel.loadUserProfileById(userId)
    }

    // Post
    ADict.DeepLinks.register("post/{postId}") { params ->
        val postId = params["postId"] ?: return@register
        viewModel.loadPost(postId)
    }

    // Post użytkownika
    ADict.DeepLinks.register("user/{username}/post/{postId}") { params ->
        val username = params["username"]
        val postId = params["postId"] ?: return@register
        viewModel.loadPost(postId)
    }

    // Hashtag
    ADict.DeepLinks.register("hashtag/{tag}") { params ->
        val tag = params["tag"] ?: return@register
        viewModel.searchByHashtag(tag)
    }

    // Wiadomość bezpośrednia
    ADict.DeepLinks.register("dm/{conversationId}") { params ->
        val conversationId = params["conversationId"] ?: return@register
        if (isLoggedIn()) {
            viewModel.openConversation(conversationId)
        } else {
            saveDeepLinkForAfterLogin()
            showLoginScreen()
        }
    }
}

IntegracjaIntegration z AndroidManifest

AndroidManifest.xml
<activity
    android:name=".MainActivity"
    android:launchMode="singleTask"
    android:exported="true">

    <!-- Standard launcher intent -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <!-- HTTP/HTTPS deep links -->
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data android:scheme="https" />
        <data android:scheme="http" />
        <data android:host="myapp.com" />
        <data android:host="www.myapp.com" />
    </intent-filter>

    <!-- Custom scheme -->
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data android:scheme="myapp" />
    </intent-filter>
</activity>

📚 API Reference

MetodaMethod OpisDescription ZwracaReturns
configure(schemes, hosts) Konfiguruj dozwolone schematy i hosty Unit
register(pattern, handler) Zarejestruj handler dla wzorca Unit
unregister(pattern) Usuń handlerRemove handler Unit
setDefaultHandler(handler) Ustaw domyślny handlerSet default handler Unit
clear() Wyczyść wszystkie handleryClear all handlers Unit
handle(intent) Obsłuż IntentHandle Intent DeepLinkResult
handle(uri) Obsłuż URIHandle URI DeepLinkResult
handle(url) Obsłuż string URLHandle string URL DeepLinkResult
test(uri) Testuj bez wykonywania DeepLinkResult
build(pattern, params, ...) Wygeneruj URL String
getRegisteredPatterns() Pobierz listę wzorcówGet list of patterns List<String>