---
title: "Cài đặt & cấu hình Android SDK"
description: "Hướng dẫn từng bước cài đặt Adapty SDK trên Android cho các ứng dụng dựa trên gói đăng ký."
---

SDK Adapty bao gồm hai module chính để tích hợp liền mạch vào ứng dụng di động của bạn:

- **Core Adapty**: Đây là SDK bắt buộc để Adapty hoạt động đúng trong ứng dụng của bạn.
- **AdaptyUI**: Module này cần thiết nếu bạn sử dụng [Adapty Paywall Builder](adapty-paywall-builder) — công cụ no-code thân thiện với người dùng để tạo paywall đa nền tảng một cách dễ dàng. AdaptyUI được tự động kích hoạt cùng với module core.
:::tip
Bạn muốn xem ví dụ thực tế về cách tích hợp Adapty SDK vào ứng dụng di động? Hãy xem [ứng dụng mẫu](https://github.com/adaptyteam/AdaptySDK-Android/tree/master/app) của chúng tôi, minh họa toàn bộ quá trình thiết lập, 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.
:::
## Yêu cầu \{#requirements\}

Yêu cầu SDK tối thiểu: `minSdkVersion 21`

:::info
Adapty tương thích với Google Play Billing Library lên đến phiên bản 8.x. Mặc định, Adapty sử dụng Google Play Billing Library v7.0.0, nhưng nếu bạn muốn dùng phiên bản mới hơn, bạn có thể tự [thêm dependency](https://developer.android.com/google/play/billing/integrate#dependency).
:::

---
no_index: true
---
import Callout from '../../../components/Callout.astro';

<Callout type="info">
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](quickstart) sẽ hướng dẫn bạn qua tất cả các bước cần thiết.
</Callout>

## Cài đặt Adapty SDK \{#install-adapty-sdk\}

Chọn phương thức thiết lập dependency của bạn:
- Gradle tiêu chuẩn: Thêm dependency vào file `build.gradle` ở **cấp module**
- Nếu dự án của bạn dùng file `.gradle.kts`, thêm dependency vào file `build.gradle.kts` cấp module
- Nếu bạn dùng version catalog, thêm dependency vào file `libs.versions.toml`, sau đó tham chiếu nó trong `build.gradle.kts`

[![Release](https://img.shields.io/github/v/release/adaptyteam/AdaptySDK-Android.svg?style=flat&logo=android)](https://github.com/adaptyteam/AdaptySDK-Android/releases)
<Tabs>
<TabItem value="module-level build.gradle" label="module-level build.gradle" default>

```groovy showLineNumbers
dependencies {
    ...
    implementation platform('io.adapty:adapty-bom:<the latest SDK version>')
    implementation 'io.adapty:android-sdk'
    
    // Only add this line if you plan to use Paywall Builder
    implementation 'io.adapty:android-ui'
}
```

</TabItem>
<TabItem value="module-level build.gradle.kts" label="module-level build.gradle.kts" default>
```kotlin showLineNumbers
dependencies {
    ...
    implementation(platform("io.adapty:adapty-bom:<the latest SDK version>"))
    implementation("io.adapty:android-sdk")
    
    // Chỉ thêm dòng này nếu bạn có kế hoạch sử dụng Paywall Builder:
    implementation("io.adapty:android-ui")
}
```

</TabItem>
<TabItem value="version catalog" label="version catalog" default>
```toml showLineNumbers
//libs.versions.toml

[versions]
..
adaptyBom = "<the latest SDK version>"

[libraries]
..
adapty-bom = { module = "io.adapty:adapty-bom", version.ref = "adaptyBom" }
adapty = { module = "io.adapty:android-sdk" }

// Only add this line if you plan to use Paywall Builder:
adapty-ui = { module = "io.adapty:android-ui" }

//module-level build.gradle.kts

dependencies {
    ...
    implementation(platform(libs.adapty.bom))
    implementation(libs.adapty)
    
    // Only add this line if you plan to use Paywall Builder:
    implementation(libs.adapty.ui)
}
```

</TabItem>
</Tabs>

Nếu dependency không được resolve, hãy đảm bảo rằng bạn đã có `mavenCentral()` trong Gradle scripts.

<details>
   <summary>Hướng dẫn cách thêm</summary>

   Nếu project 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:

```groovy showLineNumbers title="top-level build.gradle"
allprojects {
    repositories {
        ...
        mavenCentral()
    }
}
```
Nếu không, hãy thêm đoạn sau vào `settings.gradle` trong phần `repositories` của `dependencyResolutionManagement`:

```groovy showLineNumbers title="settings.gradle"
dependencyResolutionManagement {
    ...
    repositories {
        ...
        mavenCentral()
    }
}
```

</details>
:::important
Adapty Android SDK 4.0 là phiên bản pre-release. Gradle không tự động chọn các phiên bản pre-release thông qua dải phiên bản động (như `+` hay `latest.release`), vì vậy bạn phải chỉ định chính xác phiên bản. Đặt phiên bản `adapty-bom` thành phiên bản pre-release 4.0 — ví dụ `io.adapty:adapty-bom:4.0.0-beta.1`, hoặc `adaptyBom = "4.0.0-beta.1"` trong `libs.versions.toml`. BOM sẽ tự động xác định các phiên bản `android-sdk` và `android-ui` tương ứng cho bạn. Xem [Migrate Adapty Android SDK sang v4](migration-to-android-sdk-v4).
:::
## Kích hoạt module Adapty của Adapty SDK \{#activate-adapty-module-of-adapty-sdk\}

### Thiết lập cơ bản \{#basic-setup\}

Kích hoạt Adapty SDK trong code của ứng dụng.

:::note
Adapty SDK chỉ cần được kích hoạt một lần trong ứng dụng của bạn.
:::

Để lấy **Public SDK Key**:

1. Truy cập Adapty Dashboard và điều hướng đến [**App settings → General**](https://app.adapty.io/settings/general).
2. Trong phần **Api keys**, sao chép **Public SDK Key** (KHÔNG phải Secret Key).
3. Thay thế `"YOUR_PUBLIC_SDK_KEY"` trong code.

Hoặc lấy theo cách lập trình, sử dụng [Adapty CLI](developer-cli):

```
npm install -g adapty
adapty auth login
adapty apps list
```

Hoặc, trực tiếp:

```
npx adapty auth login
adapty apps list
```

- Đảm bảo bạn sử dụng **Public SDK key** để khởi tạo Adapty, **Secret key** chỉ nên dùng cho [server-side API](getting-started-with-server-side-api).
- **SDK keys** 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 đảm bảo chọn đúng key.

<Tabs groupId="current-os" queryString>
<TabItem value="kotlin" label="Kotlin" default>
```kotlin showLineNumbers
// In your Application class

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Adapty.activate(
            applicationContext,
            AdaptyConfig.Builder("PUBLIC_SDK_KEY")
                .build()
        )
    }
}
```

</TabItem>
<TabItem value="java" label="Java" default>
```java showLineNumbers
// In your Application class

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Adapty.activate(
            getApplicationContext(),
            new AdaptyConfig.Builder("PUBLIC_SDK_KEY")
                .build()
        );
    }
}
```

</TabItem>
</Tabs>
:::important
Hãy chờ `Adapty.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 Android SDK](android-sdk-call-order) để biết toàn bộ trình tự.
:::

Bây giờ hãy thiết lập paywall trong ứng dụng của bạn:

- Nếu bạn dùng [Adapty Paywall Builder](adapty-paywall-builder), hãy làm theo [hướng dẫn nhanh về Paywall Builder](android-quickstart-paywalls).
- Nếu bạn tự xây dựng giao diện paywall, hãy xem [hướng dẫn nhanh cho paywall tùy chỉnh](android-quickstart-manual).
## Kích hoạt module AdaptyUI của Adapty SDK \{#activate-adaptyui-module-of-adapty-sdk\}

Nếu bạn có kế hoạch sử dụng [Paywall Builder](adapty-paywall-builder), bạn cần module AdaptyUI. Module này được kích hoạt tự động khi bạn kích hoạt module cốt lõi; bạn không cần thực hiện thêm bất cứ điều gì.

## Cấu hình Proguard \{#configure-proguard\}

Trước khi phát hành ứng dụng lên production, hãy thêm `-keep class com.adapty.** { *; }` vào cấu hình Proguard của bạn.

## Thiết lập tùy chọn \{#optional-setup\}

### Ghi log \{#logging\}

#### Thiết lập hệ thống ghi log \{#set-up-the-logging-system\}

Adapty ghi lại các lỗi và thông tin quan trọng khác để giúp bạn hiểu chuyện gì đang xảy ra. Có các cấp độ log sau:
| Cấp độ                   | Mô tả                                                                                                                                        |
| :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- |
| `AdaptyLogLevel.NONE`    | Không có gì được ghi log. Giá trị mặc định                                                                                                   |
| `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.                                                                              |
| `AdaptyLogLevel.VERBOSE` | Ghi log mọi thông tin bổ sung có thể hữu ích trong quá trình debug, chẳng hạn như các lệnh gọi hàm, truy vấn API, v.v. |
Bạn có thể thiết lập mức độ log trong ứng dụng trước khi cấu hình Adapty.

<Tabs>
<TabItem value="kotlin" label="Kotlin" default>
```kotlin showLineNumbers

Adapty.logLevel = AdaptyLogLevel.VERBOSE 
//recommended for development and the first production release
```
</TabItem>
<TabItem value="java" label="Java" default>
```java showLineNumbers

Adapty.setLogLevel(AdaptyLogLevel.VERBOSE);
//recommended for development and the first production release
```
</TabItem>
</Tabs>
#### Chuyển hướng thông báo từ hệ thống logging \{#redirect-the-logging-system-messages\}

Nếu vì lý do nào đó bạn cần gửi thông báo từ Adapty đến hệ thống của mình hoặc lưu vào file, bạn có thể ghi đè hành vi mặc định:
<Tabs>
<TabItem value="kotlin" label="Kotlin" default>
```kotlin showLineNumbers

Adapty.setLogHandler { level, message ->
    //handle the log
}
```
</TabItem>
<TabItem value="java" label="Java" default>
```java showLineNumbers

Adapty.setLogHandler((level, message) -> {
    //handle the log
});
```
</TabItem>
</Tabs>
### Chính sách dữ liệu \{#data-policies\}

Adapty không lưu trữ dữ liệu cá nhân của người dùng trừ khi bạn tự gửi lên, nhưng bạn có thể áp dụng thêm các chính sách bảo mật dữ liệu để tuân thủ các quy định của cửa hàng hoặc từng quốc gia.

#### Tắt thu thập và chia sẻ địa chỉ IP \{#disable-ip-address-collection-and-sharing\}

Khi kích hoạt module Adapty, đặt `ipAddressCollectionDisabled` thành `true` để tắt tính năng thu thập và chia sẻ địa chỉ IP của người dùng. Giá trị mặc định là `false`.
Sử dụng tham số này để tăng cường quyền riêng tư của người dùng, tuân thủ các quy định bảo vệ dữ liệu theo khu vực (như GDPR hoặc CCPA), hoặc giảm thiểu việc thu thập dữ liệu không cần thiết khi ứng dụng của bạn không yêu cầu các tính năng dựa trên IP.

<Tabs>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers

AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withIpAddressCollectionDisabled(true)
    .build()
```
</TabItem>
<TabItem value="java" label="Java" default>
```java showLineNumbers

new AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withIpAddressCollectionDisabled(true)
    .build();
```
</TabItem>
</Tabs>

#### Vô hiệu hóa thu thập và chia sẻ advertising ID (Ad ID) \{#disable-advertising-id-ad-id-collection-and-sharing\}

Khi kích hoạt module Adapty, đặt `adIdCollectionDisabled` thành `true` để tắt tính năng thu thập [advertising ID](https://support.google.com/googleplay/android-developer/answer/6048248) của người dùng. Giá trị mặc định là `false`.
Sử dụng tham số này để tuân thủ chính sách của Play Store, tránh kích hoạt lời nhắc cấp quyền advertising ID, hoặc nếu ứng dụng của bạn không cần attribution quảng cáo hay phân tích dựa trên Ad ID.

<Tabs>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers

AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withAdIdCollectionDisabled(true)
    .build()
```
</TabItem>
<TabItem value="java" label="Java" default>
```java showLineNumbers

new AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withAdIdCollectionDisabled(true)
    .build();
```
</TabItem>
</Tabs>

#### Thiết lập cấu hình cache media cho AdaptyUI \{#set-up-media-cache-configuration-for-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 lưu lượng mạng. Bạn có thể tùy chỉnh cài đặt cache bằng cách cung cấp một cấu hình tùy chỉnh.
Sử dụng `AdaptyUI.configureMediaCache` để ghi đè kích thước cache mặc định và thời gian hiệu lực. Đây là tùy chọn không bắt buộc—nếu bạn không gọi phương thức này, các giá trị mặc định sẽ được sử dụng (dung lượng đĩa 100MB, hiệu lực 7 ngày).

<Tabs>
<TabItem value="kotlin" label="Kotlin" default>
```kotlin showLineNumbers

val cacheConfig = MediaCacheConfiguration.Builder()
    .overrideDiskStorageSizeLimit(200L * 1024 * 1024) // 200 MB
    .overrideDiskCacheValidityTime(3.days)
    .build()

AdaptyUI.configureMediaCache(cacheConfig)
```
</TabItem>
<TabItem value="java" label="Java" default>
```java showLineNumbers

MediaCacheConfiguration cacheConfig = new MediaCacheConfiguration.Builder()
    .overrideDiskStorageSizeLimit(200L * 1024 * 1024) // 200 MB
    .overrideDiskCacheValidityTime(TimeInterval.days(3))
    .build();

AdaptyUI.configureMediaCache(cacheConfig);
```
</TabItem>
</Tabs>

**Tham số:**
| Tham số                  | Bắt buộc | Mô tả                                                                       |
|-------------------------|----------|-----------------------------------------------------------------------------|
| diskStorageSizeLimit    | tùy chọn | Tổng dung lượng cache trên đĩa tính bằng byte. Mặc định là 100 MB.          |
| diskCacheValidityTime   | tùy chọn | Thời gian các file được cache vẫn còn hiệu lực. Mặc định là 7 ngày.         |
:::tip
Bạn có thể xóa bộ nhớ đệm media tại runtime bằng cách sử dụng `AdaptyUI.clearMediaCache(strategy)`, trong đó `strategy` có thể là `CLEAR_ALL` hoặc `CLEAR_EXPIRED_ONLY`.
:::
### Đặt obfuscated account ID \{#set-obfuscated-account-ids\}

Google Play yêu cầu obfuscated account ID cho một số trường hợp sử dụng nhất định nhằm tăng cường quyền riêng tư và bảo mật cho người dùng. Các ID này giúp Google Play xác định các giao dịch mua trong khi vẫn giữ thông tin người dùng ẩn danh — điều này đặc biệt quan trọng để phòng chống gian lận và phân tích dữ liệu.

Bạn có thể cần đặt các ID này nếu ứng dụng của bạn xử lý dữ liệu người dùng nhạy cảm hoặc nếu bạn phải tuân thủ các quy định về quyền riêng tư cụ thể. Obfuscated ID cho phép Google Play theo dõi các giao dịch mua mà không lộ định danh người dùng thực.
<Tabs groupId="current-os" queryString>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers

AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withObfuscatedAccountId("YOUR_OBFUSCATED_ACCOUNT_ID")
    .build()
```

</TabItem>
<TabItem value="java" label="Java" default>

```java showLineNumbers

new AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withObfuscatedAccountId("YOUR_OBFUSCATED_ACCOUNT_ID")
    .build();
```

</TabItem>
</Tabs>
### Chạy Adapty trong một tiến trình tùy chỉnh \{#run-adapty-in-a-custom-process\}

Theo mặc định, Adapty chỉ có thể chạy trong tiến trình chính của ứng dụng.
Nếu ứng dụng của bạn sử dụng nhiều tiến trình, hãy khởi tạo Adapty chỉ một lần; nếu không, có thể xảy ra hành vi không mong muốn.

Nếu bạn cần chạy Adapty trong một tiến trình khác, hãy chỉ định nó trong cấu hình:

<Tabs>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers

AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withProcessName(":custom")
    .build()
```
</TabItem>
<TabItem value="java" label="Java" default>
```java showLineNumbers

new AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withProcessName(":custom")
    .build();
```
</TabItem>
</Tabs>

Nếu bạn cố kích hoạt Adapty trong một process khác mà không thiết lập giá trị này, SDK sẽ ghi log cảnh báo và bỏ qua việc kích hoạt.
### Bật mức độ truy cập cục bộ \{#enable-local-access-levels\}

Theo mặc định, [mức độ truy cập cục bộ](local-access-levels) bị tắt trên Android. Để bật chúng, hãy đặt `withLocalAccessLevelAllowed` thành `true`:

<Tabs>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers

AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withLocalAccessLevelAllowed(true)
    .build()
```
</TabItem>
<TabItem value="java" label="Java" default>
```java showLineNumbers

new AdaptyConfig.Builder("PUBLIC_SDK_KEY")
    .withLocalAccessLevelAllowed(true)
    .build();
```
</TabItem>
</Tabs>
## Khắc phục sự cố \{#troubleshooting\}

#### Quy tắc sao lưu Android (cấu hình Auto Backup) \{#android-backup-rules-auto-backup-configuration\}

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 đều định nghĩa quy tắc sao lưu, 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`.

Dấu hiệu lỗi thường gặp: `Manifest merger failed: Attribute application@dataExtractionRules value=(@xml/sample_data_extraction_rules)
is also present at [com.other.sdk:library:1.0.0] value=(@xml/other_sdk_data_extraction_rules)`
Để giải quyết vấn đề này, bạn cần:

- Yêu cầu manifest merger sử dụng giá trị của ứng dụng cho các thuộc tính liên quan đến backup.

- Gộp các quy tắc backup từ Adapty và các SDK khác vào một file XML duy nhất (hoặc một cặp file cho Android 12+).

#### 1. Thêm namespace `tools` vào manifest của bạn \{#1-add-the-tools-namespace-to-your-manifest\}

Nếu chưa có, hãy thêm namespace `tools` vào thẻ gốc `<manifest>`:

```xml
<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>` \{#2-override-backup-attributes-in-application\}
Trong file `AndroidManifest.xml` của ứng dụng, hãy 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:

```xml
<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 SDK nào đó cũng thiết lập `android:allowBackup`, hãy thêm nó vào `tools:replace`:
```xml
tools:replace="android:allowBackup,android:fullBackupContent,android:dataExtractionRules"
```

#### 3. Tạo các file quy tắc backup đã hợp nhất \{#3-create-merged-backup-rules-files\}

Tạo các file XML trong thư mục `app/src/main/res/xml/` để kết hợp các quy tắc của Adapty với quy tắc từ các SDK khác. Android sử dụng các định dạng quy tắc backup khác nhau tùy theo phiên bản hệ điều hành, vì vậy việc tạo cả hai file đảm bảo khả năng tương thích trên tất cả các phiên bản Android mà ứng dụng của bạn hỗ trợ.

:::note
Các ví dụ dưới đây sử dụng AppsFlyer như một SDK bên thứ ba mẫu. Hãy thay thế hoặc thêm các quy tắc cho bất kỳ SDK nào khác mà bạn đang dùng trong ứng dụng.
:::
**Đối với Android 12 trở lên** (sử dụng định dạng quy tắc trích xuất dữ liệu mới):
```xml title="sample_data_extraction_rules.xml"
<?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>
```

**Đối với Android 11 trở xuống** (sử dụng định dạng nội dung full backup cũ):

```xml title="sample_backup_rules.xml"
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
    
    <exclude domain="sharedpref" path="appsflyer-data"/>

    
    <exclude domain="sharedpref" path="AdaptySDKPrefs.xml"/>

    
    
</full-backup-content>
```

Với cấu hình này:

- Các mục loại trừ backup của Adapty (`AdaptySDKPrefs.xml`) được giữ nguyên.

- Các mục loại trừ của SDK khác (ví dụ: `appsflyer-data`) cũng được áp dụng.
- Manifest merger sử dụng cấu hình ứng dụng của bạn và không còn báo lỗi về các thuộc tính backup xung đột nữa.

#### Giao dịch mua thất bại sau khi quay lại từ ứng dụng khác \{#purchases-fail-after-returning-from-another-app\}

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 Activity đó 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ả giao dịch bị mất hoặc bị xử lý như đã hủy.

Để đảm bảo giao dịch mua hoạt động đúng, chỉ sử dụng chế độ khởi chạy `standard` hoặc `singleTop` cho Activity khởi động flow mua hàng, và tránh các chế độ khác.
Trong `AndroidManifest.xml` của bạn, hãy đảm bảo Activity khởi động flow mua hàng được đặt thành `standard` hoặc `singleTop`:

```xml
<activity
    android:name=".MainActivity"
    android:launchMode="standard" />
```