Cài đặt & cấu hình Adapty Kotlin Multiplatform SDK
Adapty SDK bao gồm hai module chính để tích hợp liền mạch vào ứng dụng của bạn:
- Core Adapty: SDK cốt lõi bắt buộc để Adapty hoạt động trong ứng dụng của bạn.
- AdaptyUI (
io.adapty:adapty-kmp-ui): Module này cần thiết nếu bạn dùng Adapty Paywall Builder với lớp render Compose Multiplatform (view.present()). Nếu dự án của bạn không dùng Compose Multiplatform, bạn có thể sử dụngcreateNativePaywallViewvàcreateNativeOnboardingViewtừ module core thay thế.
Muốn xem ví dụ thực tế về cách tích hợp Adapty SDK vào ứng dụng? Hãy xem ứng dụng mẫu của chúng tôi, minh họa toàn bộ quá trình cài đặt bao gồm hiển thị paywall, thực hiện mua hàng và các chức năng cơ bản khác.
Bạn cũng có thể xem video hướng dẫn triển khai đầy đủ:
Yêu cầu
Adapty Kotlin Multiplatform SDK tương thích với Xcode 16.2 trở lên.
Bắt đầu từ SDK v3.17, Adapty SDK sử dụng Google Play Billing Library v8.0.0 theo mặc định.
Cài đặt SDK là bước 5 trong quá trình thiết lập Adapty. Trước khi các giao dịch mua hàng hoạt động trong ứng dụng, bạn cần kết nối ứng dụng với các cửa hàng, sau đó tạo sản phẩm, paywall và placement trong Adapty Dashboard. Hướng dẫn quickstart sẽ hướng dẫn bạn qua tất cả các bước cần thiết.
Cài đặt Adapty SDK qua Gradle
Việc cài đặt Adapty SDK bằng Gradle là bắt buộc cho cả ứng dụng Android và iOS.
Chọn phương thức thiết lập dependency:
- Gradle thông thường: Thêm dependency vào file
build.gradlecấp module - Nếu dự án dùng file
.gradle.kts, thêm dependency vào filebuild.gradle.ktscấp module - Nếu bạn dùng version catalog, thêm dependency vào file
libs.versions.tomlrồi tham chiếu trongbuild.gradle.kts
Nếu bạn gặp lỗi liên quan đến Maven, hãy đảm bảo rằng bạn đã có mavenCentral() trong Gradle scripts.
Hướng dẫn cách thêm
Nếu dự án của bạn không có dependencyResolutionManagement trong settings.gradle, hãy thêm đoạn sau vào build.gradle cấp cao nhất ở cuối phần repositories:
allprojects {
repositories {
...
mavenCentral()
}
}Ngược lại, hãy thêm đoạn sau vào settings.gradle trong phần repositories của dependencyResolutionManagement:
dependencyResolutionManagement {
...
repositories {
...
google()
mavenCentral()
}
}Kích hoạt Adapty SDK
Cài đặt cơ bản
Thêm đoạn khởi tạo sớm nhất có thể — thường là trong code Kotlin dùng chung cho cả hai nền tảng.
Adapty SDK chỉ cần được kích hoạt một lần trong ứng dụng của bạn.
val config = AdaptyConfig
.Builder("PUBLIC_SDK_KEY")
.build()
Adapty.activate(configuration = config)
.onSuccess {
Log.d("Adapty", "SDK initialised")
}
.onError { error ->
Log.e("Adapty", "Adapty init error: ${error.message}")
}
Hãy đợi activate hoàn tất trước khi gọi bất kỳ phương thức nào khác của Adapty SDK. Xem Thứ tự gọi trong Kotlin Multiplatform SDK để biết toàn bộ trình tự.
Để lấy Public SDK Key:
- Vào Adapty Dashboard và điều hướng đến App settings → General.
- Trong phần Api keys, sao chép Public SDK Key (KHÔNG phải Secret Key).
- Thay thế
"YOUR_PUBLIC_SDK_KEY"trong code.
- Đảm bảo bạn dùng Public SDK key để khởi tạo Adapty, Secret key chỉ dùng cho server-side API.
- SDK key là duy nhất cho mỗi ứng dụng, vì vậy nếu bạn có nhiều ứng dụng hãy chắc chắn chọn đúng key.
Tiếp theo, thiết lập paywall trong ứng dụng của bạn:
- Nếu bạn dùng Adapty Paywall Builder, trước tiên hãy kích hoạt module AdaptyUI bên dưới, sau đó làm theo hướng dẫn nhanh về Paywall Builder.
- Nếu bạn tự xây dựng giao diện paywall, xem hướng dẫn nhanh cho paywall tùy chỉnh.
Kích hoạt module AdaptyUI của Adapty SDK
Nếu bạn muốn kích hoạt module AdaptyUI để dùng Adapty Paywall Builder, hãy đặt .withActivateUI(true) trong cấu hình.
important Trong code của bạn, bạn phải kích hoạt module Adapty core trước khi kích hoạt AdaptyUI.
val config = AdaptyConfig
.Builder("PUBLIC_SDK_KEY")
.withActivateUI(true) // true for activating the AdaptyUI module
.build()
Adapty.activate(configuration = config)
.onSuccess {
Log.d("Adapty", "SDK initialised")
}
.onError { error ->
Log.e("Adapty", "Adapty init error: ${error.message}")
}
Cấu hình Proguard (Android)
Trước khi ra mắt ứng dụng trên production, bạn có thể cần thêm -keep class com.adapty.** { *; } vào cấu hình Proguard.
Cài đặt tùy chọn
Logging
Thiết lập hệ thống logging
Adapty ghi log các lỗi và thông tin quan trọng để giúp bạn hiểu những gì đang xảy ra. Các cấp độ log có sẵn như sau:
| Cấp độ | Mô tả |
|---|---|
AdaptyLogLevel.ERROR | Chỉ ghi log các lỗi. |
AdaptyLogLevel.WARN | Ghi log các lỗi và các thông báo từ SDK không gây ra lỗi nghiêm trọng nhưng đáng chú ý. |
AdaptyLogLevel.INFO | Ghi log các lỗi, cảnh báo và các thông báo thông tin khác nhau. Giá trị mặc định. |
AdaptyLogLevel.VERBOSE | Ghi log mọi thông tin bổ sung có thể hữu ích khi debug, chẳng hạn như các lời gọi hàm, API query, v.v. |
AdaptyLogLevel.DEBUG | Ghi log thông tin chi tiết nhất, bao gồm cả dữ liệu debug nội bộ. |
Bạn có thể đặt cấp độ log trong ứng dụng trước khi cấu hình Adapty:
val config = AdaptyConfig
.Builder("PUBLIC_SDK_KEY")
.withLogLevel(AdaptyLogLevel.VERBOSE) // recommended for development
.build()
Chính sách dữ liệu
Tắt thu thập và chia sẻ địa chỉ IP
Khi kích hoạt module Adapty, đặt ipAddressCollectionDisabled thành true để tắt việc thu thập và chia sẻ địa chỉ IP của người dùng. Giá trị mặc định là false.
Dùng tham số này để tăng cường quyền riêng tư người dùng, tuân thủ các quy định bảo vệ dữ liệu khu vực (như GDPR hoặc CCPA), hoặc giảm thu thập dữ liệu không cần thiết khi các tính năng dựa trên IP không bắt buộc cho ứng dụng của bạn.
val config = AdaptyConfig
.Builder("PUBLIC_SDK_KEY")
.withIpAddressCollectionDisabled(true)
.build()
Tắt thu thập và chia sẻ advertising ID
Khi kích hoạt module Adapty, đặt appleIdfaCollectionDisabled (iOS) hoặc googleAdvertisingIdCollectionDisabled (Android) thành true để tắt việc thu thập advertising identifier. Giá trị mặc định là false.
Dùng tham số này để tuân thủ chính sách App Store/Play Store, tránh kích hoạt lời nhắc App Tracking Transparency, hoặc nếu ứng dụng của bạn không cần attribution quảng cáo hay analytics dựa trên advertising ID.
val config = AdaptyConfig
.Builder("PUBLIC_SDK_KEY")
.withGoogleAdvertisingIdCollectionDisabled(true) // Android only
.withAppleIdfaCollectionDisabled(true) // iOS only
.build()
Thiết lập cấu hình media cache cho AdaptyUI
Theo mặc định, AdaptyUI lưu cache media (như hình ảnh và video) để cải thiện hiệu suất và giảm sử dụng băng thông mạng. Bạn có thể tùy chỉnh cài đặt cache bằng cách cung cấp cấu hình riêng.
Dùng mediaCache để ghi đè cài đặt cache mặc định:
val config = AdaptyConfig
.Builder("PUBLIC_SDK_KEY")
.withMediaCacheConfiguration(
AdaptyConfig.MediaCacheConfiguration(
memoryStorageTotalCostLimit = 200 * 1024 * 1024, // 200 MB
memoryStorageCountLimit = Int.MAX_VALUE,
diskStorageSizeLimit = 200 * 1024 * 1024 // 200 MB
)
)
.build()
Bật local access levels (Android)
Theo mặc định, local access levels bị tắt cho Android. Để bật chúng, đặt withLocalAccessLevelAllowed thành true:
val config = AdaptyConfig
.Builder("PUBLIC_SDK_KEY")
.withGoogleLocalAccessLevelAllowed(true)
.build()
Xóa dữ liệu khi khôi phục backup
Khi withAppleClearDataOnBackup được đặt thành true, SDK sẽ phát hiện khi ứng dụng được khôi phục từ backup iCloud và xóa toàn bộ dữ liệu SDK được lưu trữ cục bộ, bao gồm thông tin hồ sơ người dùng được cache, chi tiết sản phẩm và paywall. SDK sau đó khởi tạo với trạng thái sạch. Giá trị mặc định là false.
Chỉ xóa cache SDK cục bộ. Lịch sử giao dịch với Apple và dữ liệu người dùng trên máy chủ Adapty vẫn không thay đổi.
val config = AdaptyConfig
.Builder("PUBLIC_SDK_KEY")
.withAppleClearDataOnBackup(true)
.build()
Xử lý sự cố
Quy tắc Android backup (Cấu hình Auto Backup)
Một số SDK (bao gồm Adapty) đi kèm với cấu hình Android Auto Backup riêng. Nếu bạn sử dụng nhiều SDK có định nghĩa backup rules, quá trình merge Android manifest có thể thất bại với lỗi liên quan đến android:fullBackupContent, android:dataExtractionRules, hoặc android:allowBackup.
Triệu chứng lỗi thường gặp: Manifest merger failed: Attribute application@dataExtractionRules value=(@xml/your_data_extraction_rules) is also present at [com.other.sdk:library:1.0.0] value=(@xml/other_sdk_data_extraction_rules)
Những thay đổi này cần được thực hiện trong thư mục platform Android của bạn (thường nằm trong thư mục android/ của dự án).
Để khắc phục, bạn cần:
-
Yêu cầu manifest merger sử dụng các giá trị của ứng dụng cho các thuộc tính liên quan đến backup.
-
Tạo các file backup rule kết hợp rules của Adapty với rules từ các SDK khác.
1. Thêm namespace tools vào manifest
Trong file AndroidManifest.xml, hãy đảm bảo thẻ gốc <manifest> có chứa tools:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.app">
...
</manifest>
2. Ghi đè các thuộc tính backup trong <application>
Trong cùng file AndroidManifest.xml, cập nhật thẻ <application> để ứng dụng của bạn cung cấp các giá trị cuối cùng và yêu cầu manifest merger thay thế các giá trị từ thư viện:
<application
android:name=".App"
android:allowBackup="true"
android:fullBackupContent="@xml/sample_backup_rules"
android:dataExtractionRules="@xml/sample_data_extraction_rules"
tools:replace="android:fullBackupContent,android:dataExtractionRules">
...
</application>
Nếu có SDK nào cũng đặt android:allowBackup, hãy thêm nó vào tools:replace:
tools:replace="android:allowBackup,android:fullBackupContent,android:dataExtractionRules"
3. Tạo các file backup rules đã merge
Tạo các file XML trong thư mục res/xml/ của dự án Android, kết hợp rules của Adapty với rules từ các SDK khác. Android sử dụng các định dạng backup rule khác nhau tùy theo phiên bản OS, vì vậy việc tạo cả hai file đảm bảo tương thích với tất cả các phiên bản Android mà ứng dụng hỗ trợ.
Các ví dụ dưới đây sử dụng AppsFlyer làm SDK bên thứ ba mẫu. Hãy thay thế hoặc bổ sung rules cho các SDK khác mà bạn đang dùng trong ứng dụng.
Dành cho Android 12 trở lên (sử dụng định dạng data extraction rules mới):
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
<cloud-backup>
<exclude domain="sharedpref" path="appsflyer-data"/>
<exclude domain="sharedpref" path="appsflyer-purchase-data"/>
<exclude domain="database" path="afpurchases.db"/>
<exclude domain="sharedpref" path="AdaptySDKPrefs.xml"/>
</cloud-backup>
<device-transfer>
<exclude domain="sharedpref" path="appsflyer-data"/>
<exclude domain="sharedpref" path="appsflyer-purchase-data"/>
<exclude domain="database" path="afpurchases.db"/>
<exclude domain="sharedpref" path="AdaptySDKPrefs.xml"/>
</device-transfer>
</data-extraction-rules>
Dành cho Android 11 trở xuống (sử dụng định dạng full backup content cũ):
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<exclude domain="sharedpref" path="appsflyer-data"/>
<exclude domain="sharedpref" path="AdaptySDKPrefs.xml"/>
Trong dự án Kotlin Multiplatform, áp dụng các thay đổi này trong Android application module (module tạo ra APK/AAB), ví dụ androidApp hoặc app:
- Manifest:
androidApp/src/main/AndroidManifest.xml - Backup rules XML:
androidApp/src/main/res/xml/
Mua hàng thất bại sau khi quay lại từ ứng dụng khác trên Android
Nếu Activity khởi động flow mua hàng sử dụng launchMode không phải mặc định, Android có thể tạo lại hoặc tái sử dụng nó không đúng cách khi người dùng quay lại từ Google Play, ứng dụng ngân hàng hoặc trình duyệt. Điều này có thể khiến kết quả mua hàng bị mất hoặc bị coi là đã hủy.
Để đảm bảo mua hàng hoạt động đúng, chỉ sử dụng chế độ launch standard hoặc singleTop cho Activity khởi động flow mua hàng, và tránh các chế độ khác.
Trong AndroidManifest.xml, đảm bảo Activity khởi động flow mua hàng được đặt thành standard hoặc singleTop:
<activity
android:name=".MainActivity"
android:launchMode="standard" />