> ## Documentation Index
> Fetch the complete documentation index at: https://help.airbridge.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 트러블 슈팅 - 안드로이드 SDK (Deprecated)

<AccordionGroup>
  <Accordion title="BillingClient Dependency">
    에어브릿지 SDK를 직접 설치할 경우, `BillingClient` 의존성 문제로 인해 컴파일 오류가 발생할 수 있습니다.

    에어브릿지 SDK v2.26.1부터 In-App 구매 내역을 수집하는 기능이 추가되었습니다. 에어브릿지  SDK는 In-App 구매 라이브러리에 대한 의존성을 `compileOnly`로 설정하고 있어, Gradle 빌드 시에는 문제가 없지만 직접 설치할 경우 의존성 문제로 인해 컴파일 오류가 발생할 수 있습니다.

    이 문제를 해결하려면 아래 내용을 참고해 주세요.

    ```groovy lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    dependencies {
        api fileTree(dir: 'libs', include: ['billingClient.aar'])
    }
    ```
  </Accordion>

  <Accordion title="Ad ID permission">
    ###### LAT(LimitAdTracking)를 비활성화한 상태에서 GAID가 00000000-0000-0000-0000-000000000000으로 잡히는 이슈

    1. AndroidManifest.xml 파일을 열어주세요.
    2. `com.google.android.gms.permission.AD_ID` 권한을 다음과 같이 추가해 주세요.

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <manifest ...>
      ...
      <uses-permission android:name="com.google.android.gms.permission.AD_ID" />
      ...
    </manifest>
    ```

    더 자세한 내용은 [구글 가이드](https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info#public-string-getid)를 참고해 주세요.
  </Accordion>

  <Accordion title="Braze push notification">
    `Braze SDK` 를 사용하여 push notification 을 통해 deeplink 를 open 할 시 airbridge 에서 event 가 `DEEPLINK OPEN` 이 안잡히고 `OPEN` 이 발생합니다.

    `Airbridge SDK` 는 event 확인을 위해서 activity 의 action 과 intent 의 dataString 으로 전달 되는 값을 통해 `DEEPLINK OPEN` ,`OPEN` 등을 판별 하고 있습니다. 그러나 `Braze SDK` 에 push notification 을 생성시 `Braze SDK` 에 정의 된 `NotificationTrampolineActivity` 을 통해서 open 되는데 해당 activity Action 과 intent 에서 dataString 값을 확인 할 수 없어서 발생하게 됩니다.

    `airbridge android SDK v2.21.5` 에서 추가된 아래 interface 를 통해 해당 내용을 해결 할 수 있습니다.

    <CodeGroup>
      ```java Java lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      AirbridgeConfig config = new AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
          .setLifecycleIntegration(new AirbridgeLifecycleIntegration() {
          @Nullable
          @Override
          public String getDataString(@NotNull Activity activity) {
            if (activity.getClass().getName().equals("com.braze.push.NotificationTrampolineActivity")
                && activity.getIntent() != null
                && activity.getIntent().getExtras() != null) {
              return activity.getIntent().getExtras().getString("uri");
            }
            return null;
          }
        })
          .build();
      Airbridge.init(this, config)
      ```

      ```kotlin Kotlin lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      val config = AirbridgeConfig.Builder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN")
          .setLifecycleIntegration {
            it.takeIf { it.javaClass.name == "com.braze.push.NotificationTrampolineActivity" }
            ?.run { intent?.extras?.getString("uri") }
        }
          .build()
      Airbridge.init(this, config)
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="`deeplink.page`">
    `deeplink.page` 는 `airbridge android SDK v2.21.1` 버전에서 `deprecated` 되었습니다. 그렇지만 내부 동작을 통해 여전히 지원 및 동작은 되고 있습니다.

    `airbridge android SDK v2.21.0` 이하 버전을 사용중이라면 하단에 명시된 절차에 따라서 Intent Filter를 설정해 주세요.

    1. AndroidManifest.xml 파일을 열어주세요.
    2. 딥링크를 처리할 Activity에 Intent Filter를 다음과 같이 추가해 주세요

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <activity ...>
        ...
        <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="http" android:host="YOUR_APP_NAME.deeplink.page" />
            <data android:scheme="https" android:host="YOUR_APP_NAME.deeplink.page" />
        </intent-filter>
        <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="http" android:host="YOUR_APP_NAME.airbridge.io" />
            <data android:scheme="https" android:host="YOUR_APP_NAME.airbridge.io" />
        </intent-filter>
        <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="YOUR_APP_URI_SCHEME" />
        </intent-filter>
    </activity>
    ```
  </Accordion>

  <Accordion title="Dependencies">
    #### `java.lang.NoClassDefFoundError: kotlin/coroutines/AbstractCoroutineContextKey` 문제

    ```html Text lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    java.lang.NoClassDefFoundError: kotlin/coroutines/AbstractCoroutineContextKey
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
      ...
    ```

    * 참조 : [https://github.com/Kotlin/kotlinx.coroutines/issues/1879](https://github.com/Kotlin/kotlinx.coroutines/issues/1879)

    [@qwwdfsad](https://github.com/Kotlin/kotlinx.coroutines/issues/1913#issuecomment-612916683)에 따르면 `kotlinx-coroutines-core` 라이브러리 `1.3.5` 이상의 버전을 사용 시 반드시 `kotlin-stdlib` 라이브러리 버전 `1.3.70` 이상을 사용하도록 강제하고 있습니다.

    `gradlew dependencies` 커멘드를 통해 현재 포함된 `kotlinx-coroutines-core` 라이브러리 버전이 `1.3.5` 이상인 경우 `kotlin-stdlib` 라이브러리 버전이 `1.3.70` 이상인지 확인해 주세요.
  </Accordion>

  <Accordion title="Auto Backup">
    * 참조 : [https://developer.android.com/guide/topics/data/autobackup](https://developer.android.com/guide/topics/data/autobackup)

    에어브릿지 SDK의 `AndroidManifest.xml`에는 공유 환경 설정 데이터 백업을 옵트아웃하는 규칙이 포함되어 있습니다. 이는 재설치 중에 동일한 에어브릿지 설정 값들을 유지하지 않도록 하여 새로운 설치 또는 재설치를 정확하게 감지하도록 하기 위해 수행됩니다.

    에어브릿지 SDK 백업 규칙과 앱 백업 규칙의 병합 과정에서 충돌을 방지하려면 각 사용 사례에 대해 다음 지침을 수행하세요.

    에어브릿지 SDK에서 정의하는 옵트아웃하는 규칙은 다음과 같습니다.

    <CodeGroup>
      ```xml Backup on Android 12 or later lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      <?xml version="1.0" encoding="utf-8"?>
      <data-extraction-rules>
          <cloud-backup>
              <exclude domain="sharedpref" path="airbridge-internal" />
              <exclude domain="sharedpref" path="airbridge-install" />
              <exclude domain="sharedpref" path="airbridge-user-info" />
              <exclude domain="sharedpref" path="airbridge-user-alias" />
              <exclude domain="sharedpref" path="airbridge-user-attributes" />
              <exclude domain="sharedpref" path="airbridge-device-alias" />
              <exclude domain="database" path="airbridge.db" />
          </cloud-backup>
          <device-transfer>
              <exclude domain="sharedpref" path="airbridge-internal" />
              <exclude domain="sharedpref" path="airbridge-install" />
              <exclude domain="sharedpref" path="airbridge-user-info" />
              <exclude domain="sharedpref" path="airbridge-user-alias" />
              <exclude domain="sharedpref" path="airbridge-user-attributes" />
              <exclude domain="sharedpref" path="airbridge-device-alias" />
              <exclude domain="database" path="airbridge.db" />
          </device-transfer>
      </data-extraction-rules>
      ```

      ```xml Backup on Android 11 and earlier lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      <?xml version="1.0" encoding="utf-8"?>
      <full-backup-content>
          <exclude domain="sharedpref" path="airbridge-internal" />
          <exclude domain="sharedpref" path="airbridge-install" />
          <exclude domain="sharedpref" path="airbridge-user-info" />
          <exclude domain="sharedpref" path="airbridge-user-alias" />
          <exclude domain="sharedpref" path="airbridge-user-attributes" />
          <exclude domain="sharedpref" path="airbridge-device-alias" />
          <exclude domain="database" path="airbridge.db" />
      </full-backup-content>
      ```
    </CodeGroup>

    <AccordionGroup>
      <Accordion title="fullBackupContent=&#x22;string&#x22;과의 충돌 방지">
        `android:fullBackupContent="string"`를  `AndroidManifest.xml`에 추가하면 다음과 같은 오류가 발생할 수 있습니다.

        ```html Build Output lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        Manifest merger failed : Attribute application@fullBackupContent value=(string) from AndroidManifest.xml
        ```

        위 오류를 해결하려면 `AndroidManifest.xml` 파일의  `<application>` 태그에  `tools:replace="android:fullBackupContent"`를 추가 해주세요.
      </Accordion>

      <Accordion title="dataExtractionRules=&#x22;string resource&#x22;과의 충돌 방지">
        `android:dataExtractionRules="string resource"`를  `AndroidManifest.xml`에 추가하면 다음과 같은 오류가 발생할 수 있습니다.

        ```html Build Output lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        Manifest merger failed : Attribute application@dataExtractionRules value=(string resource) from AndroidManifest.xml
        ```

        위 오류를 해결하려면 `AndroidManifest.xml` 파일의  `<application>` 태그에  `tools:replace="android:dataExtractionRules"`를 추가 해주세요.
      </Accordion>

      <Accordion title="allowBackup=&#x22;false&#x22;과의 충돌 방지">
        `android:allowBackup="false"`를  `AndroidManifest.xml`에 추가하면 다음과 같은 오류가 발생할 수 있습니다.

        ```html Build Output lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        Manifest merger failed : Attribute application@allowBackup value=(false) from AndroidManifest.xml:32:9-36
            is also present at [:airbridge] AndroidManifest.xml:27:9-35 value=(true).
            Suggestion: add 'tools:replace="android:allowBackup"' to <application> element at AndroidManifest.xml:30:5-250:19 to override.
        ```

        위 오류를 해결하려면 `AndroidManifest.xml` 파일의  `<application>` 태그에  `tools:replace="android:allowBackup"`를 추가 해주세요.
      </Accordion>

      <Accordion title="compileSdkVersion이 31 미만일 경우">
        `android:dataExtractionRules` 기능이 API Level 31 부터 추가되었기 때문에 compileSdkVersion이 31 미만일 경우, 다음과 같은 오류가 발생할 수 있습니다.

        ```html Build Output lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        AndroidManifest.xml: AAPT: error: attribute android:dataExtractionRules not found.
        ```

        위 오류를 해결하려면 `AndroidManifest.xml` 파일의  `<application>` 태그에  `tools:remove="android:dataExtractionRules"`를 추가 해주세요.
      </Accordion>
    </AccordionGroup>
  </Accordion>

  <Accordion title="에어브릿지 SDK 백업 규칙 병합 충돌 문제">
    에어브릿지 SDK 백업 규칙과 서드파티 SDK 백업 규칙 중복 적용으로 인해 빌드 에러가 발생하는 경우 해결 방법은 아래를 참고해주세요.

    예) 에어브릿지 SDK 백업 규칙과 Appsflyer SDK 백업 규칙이 중복 적용되는 경우 아래와 같은 빌드 에러가 표시됩니다.

    ```html lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    Attribute application@fullBackupContent value=(@xml/appsflyer_backup_rules) from [com.appsflyer:af-android-sdk:6.6.1] AndroidManifest.xml:14:18-73
    is also present at [io.airbridge:sdk-android:2.14.0] AndroidManifest.xml:27:18-78 value=(@xml/airbridge_auto_backup_rules).
    Suggestion: add 'tools:replace="android:fullBackupContent"' to <application> element at AndroidManifest.xml:7:5-13:19 to override.
    ```

    이 문제를 해결하기 위해서는 아래와 같이 설정해주세요.

    <AccordionGroup>
      <Accordion title="backup_rules.xml 설정">
        1. `src/main/res/xml` 폴더를 생성해주세요.
        2. 생성된 xml 폴더 내부에 (e.g. `custom_backup_rules.xml`) 파일을 생성해주세요.
        3. 에어브릿지 SDK에서 정의하는 데이터 백업 규칙을 다음과 같이 추가해 주세요.

        ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        <?xml version="1.0" encoding="utf-8"?>
        <full-backup-content>
            <!-- Airbridge Backup Rules -->
            <exclude domain="sharedpref" path="airbridge-internal" />
            <exclude domain="sharedpref" path="airbridge-install" />
            <exclude domain="sharedpref" path="airbridge-user-info" />
            <exclude domain="sharedpref" path="airbridge-user-alias" />
            <exclude domain="sharedpref" path="airbridge-user-attributes" />
            <exclude domain="sharedpref" path="airbridge-device-alias" />
            <exclude domain="database" path="airbridge.db" />

            <!-- Appsflyer Backup Rules -->
            <exclude domain="sharedpref" path="appsflyer-data"/>

            <!-- Your Custom Backup Rules -->
        </full-backup-content>
        ```
      </Accordion>

      <Accordion title="data_extraction_rules.xml 설정">
        <Info>
          **알립니다**

          data\_extraction\_rules.xml 설정은 Airbridge Android SDK v2.27.1 이상부터 필요로 합니다.
        </Info>

        1. 생성된 xml 폴더 내부에 (e.g. `custom_data_extraction_rule.xml`) 파일을 생성해주세요.
        2. 에어브릿지 SDK에서 정의하는 데이터 백업 규칙을 다음과 같이 추가해 주세요.

        ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        <?xml version="1.0" encoding="utf-8"?>
        <data-extraction-rules>
            <cloud-backup>
                <!-- Airbridge Backup Rules -->
                <exclude domain="sharedpref" path="airbridge-internal" />
                <exclude domain="sharedpref" path="airbridge-install" />
                <exclude domain="sharedpref" path="airbridge-user-info" />
                <exclude domain="sharedpref" path="airbridge-user-alias" />
                <exclude domain="sharedpref" path="airbridge-user-attributes" />
                <exclude domain="sharedpref" path="airbridge-device-alias" />
                <exclude domain="database" path="airbridge.db" />

                <!-- Appsflyer Backup Rules -->
                <exclude domain="sharedpref" path="appsflyer-data"/>

                <!-- Your Custom Backup Rules -->
            </cloud-backup>
            <device-transfer>
                <!-- Airbridge Backup Rules -->
                <exclude domain="sharedpref" path="airbridge-internal" />
                <exclude domain="sharedpref" path="airbridge-install" />
                <exclude domain="sharedpref" path="airbridge-user-info" />
                <exclude domain="sharedpref" path="airbridge-user-alias" />
                <exclude domain="sharedpref" path="airbridge-user-attributes" />
                <exclude domain="sharedpref" path="airbridge-device-alias" />
                <exclude domain="database" path="airbridge.db" />

                <!-- Appsflyer Backup Rules -->
                <exclude domain="sharedpref" path="appsflyer-data"/>

                <!-- Your Custom Backup Rules -->
            </device-transfer>
        </data-extraction-rules>
        ```
      </Accordion>

      <Accordion title="AndroidManifest.xml 설정">
        ###### Airbridge Android SDK v2.27.1 이상

        ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        <manifest
            ...
            xmlns:tools="http://schemas.android.com/tools">

            <application
                ...
                android:allowBackup="true"
                android:fullBackupContent="@xml/custom_backup_rules"
                android:dataExtractionRules="@xml/custom_data_extraction_rules"
                tools:replace="android:fullBackupContent,android:dataExtractionRules">
        ```

        ###### Airbridge Android SDK v2.27.1 미만

        ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        <manifest
            ...
            xmlns:tools="http://schemas.android.com/tools">

            <application
                ...
                android:allowBackup="true"
                android:fullBackupContent="@xml/custom_backup_rules"
                tools:replace="android:fullBackupContent">
        ```
      </Accordion>
    </AccordionGroup>
  </Accordion>

  <Accordion title="Double brace initialization issue">
    ```java lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    HashMap<String, Object> semanticAttributes = new HashMap();
    semanticAttributes.put("products", Arrays.asList(
            // double brace initialization issue
            new HashMap<String, Object>() {{
                put("name", "MacBook Pro");
                put("price", 1548200);
                put("position", 1);
                put("brandID", 23);
                put("brandName", "apple");
            }},
            new HashMap<String, Object>() {{
                put("name", "MacBook Air");
                put("price", 1500000);
                put("position", 2);
                put("brandID", 23);
                put("brandName", "apple");
            }}
        )
    );

    HashMap<String, Object> customAttributes = new HashMap();
    customAttributes.put("customKey", "customValue");

    Airbridge.trackEvent(
        "purchase",
        "action",
        "label",
        3048200,
        customAttributes,
        semanticAttributes
    );
    ```

    Android SDK는 Google의 GSON 라이브러리를 사용중이며, 해당 라이브러리에 [Double Brace Initialization 관련 Known Issue](https://github.com/google/gson/issues/346)가 존재합니다. 하여 위 Java 코드와 같이 Products 객체를 만들때 Double Brace Initialization를 사용하면 products 데이터가 누락될 수 있기 때문에, [결제 완료](/ko/developers/deprecated-android-sdk-v2#결제-완료)의 예시 코드처럼 직접 Product 객체를 만들어 사용하시는 것을 권장드립니다.
  </Accordion>
</AccordionGroup>
