# Android

{% hint style="warning" %}
React Native環境におけるIMQA SDKを適用する方法を提供します。

[IMQA MPMインストールガイド](https://docs.imqa.io/imqa-guide/jpn/installation/android/mpm-sdk-install)により、IMQA agentコードを適用した後、この文書の内容を追加で適用してください。
{% endhint %}

## 1. 共通

### MPM Module install&#x20;

React native環境においてIMQA SDKを適用するために、下記のコマンドでパッケージをインストールする必要があります。.&#x20;

{% code title="npmコマンドを使う時" %}

```
// npm install imqa-react-native-agent --save 
```

{% endcode %}

{% code title="yarnコマンドを使う時" %}

```
yarn add imqa-react-native-agent
```

{% endcode %}

## 2. Gradle Pluginインストール&#x20;

「app.gradle」ファイルで「buildscript」内の「dependencies」ブロックに「imqa-mpm-injector」と上段に「plugin」を追加してください。一般的に「\<project\_dir>/app/build.gradle」にあります。

{% hint style="warning" %}
ファイルをアップデート後にGradleファイルを同期させる必要があります。
{% endhint %}

{% code title="app.gradle(project root)" %}

```java
/// Add Build script dependencies 
buildscript { 
    repositories { 
        mavenCentral()
    } 
    
    dependencies {
    // Add dependencies.
        classpath 'io.imqa:imqa-mpm-injector:2.25.6' ... 
    } 
} 
```

{% endcode %}

* java

{% code title="app.gradle(app module) -> java" %}

```java
...
    dependencies {
    // Add dependencies.
       implementation 'io.imqa:imqa-core:2.27.3'
       implementation 'io.imqa:imqa-mpm-client:2.27.7'
       implementation 'io.imqa:imqa-crash-client:2.27.2'
    } 
} 

io.imqa.IMQAPlugin imqaPlugin = new io.imqa.IMQAPlugin()
imqaPlugin.init(project)
new io.imqa.injector.GJavacAction(project.name).setConfiguration(project)
android.applicationVariants.all { variant ->
    variant.javaCompile.doLast { task ->
        new io.imqa.injector.CompileAction(
                io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacClasses,
                project.name,
                io.imqa.injector.GJavacAction.convertBuildType(variant.getBuildType()),
                io.imqa.injector.GJavacAction.makeFlavor(variant.getBuildType().name,
                        variant)
        ).execute(task)
    }

```

{% endcode %}

* kotlin

{% code title="app.gradle(app module) -> kotlin" %}

```kotlin
...
    dependencies {
    // dependencies 추가
       implementation 'io.imqa:imqa-core:2.27.3'
       implementation 'io.imqa:imqa-mpm-client:2.27.7'
       implementation 'io.imqa:imqa-crash-client:2.27.2'
    } 
} 

io.imqa.IMQAPlugin imqaPlugin = new io.imqa.IMQAPlugin()
imqaPlugin.init(project)
new io.imqa.injector.GJavacAction(project.name).setConfiguration(project)
android.applicationVariants.all { variant ->
    variant.javaCompile.doLast { task ->
        new io.imqa.injector.CompileAction(
                io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.kotlin,
                project.name,
                io.imqa.injector.GJavacAction.convertBuildType(variant.getBuildType()),
                io.imqa.injector.GJavacAction.makeFlavor(variant.getBuildType().name,
                        variant)
        ).execute(task)
    }
}
```

{% endcode %}

* java + kotlin

{% code title="app.gradle(app module) -> java + kotlin" %}

```java
...

    dependencies {
    // Add dependencies.
       implementation 'io.imqa:imqa-core:2.27.3'
       implementation 'io.imqa:imqa-mpm-client:2.27.7'
       implementation 'io.imqa:imqa-crash-client:2.27.2'
    } 
} 

io.imqa.IMQAPlugin imqaPlugin = new io.imqa.IMQAPlugin()
imqaPlugin.init(project)
new io.imqa.injector.GJavacAction(project.name).setConfiguration(project)
android.applicationVariants.all { variant ->
    variant.javaCompile.doLast { task -> {
        new io.imqa.injector.CompileAction(
                io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.kotlin,
                project.name,
                io.imqa.injector.GJavacAction.convertBuildType(variant.getBuildType()),
                io.imqa.injector.GJavacAction.makeFlavor(variant.getBuildType().name,
                        variant)
        ).execute(task)

        new io.imqa.injector.CompileAction(
                io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacClasses,
                project.name,
                io.imqa.injector.GJavacAction.convertBuildType(variant.getBuildType()),
                io.imqa.injector.GJavacAction.makeFlavor(variant.getBuildType().name,
                        variant)
        ).execute(task)
    }
    }
}
```

{% endcode %}

{% code title="gradle.properties" %}

```
...

project.home=프로젝트의 경로 (ex:/user/workspace/project1)
#Add only Kotlin project
project.kotlin.path=$PROJECT_HOME/app/build/tmp/kotlin-classes 
#Add only Java project
project.java.path=$PROJECT_HOME/app/build/intermediates/javac/debug/classes
#Path to built manifest file
project.manifest.path=$PROJECT_HOME/app/build/intermediates/merged_manifest/debug/AndroidManifest.xml
#gradle action
project.task.execute=:assemble

```

{% endcode %}

## 3.Android Manifestに権限追加&#x20;

AndroidManifest.xmlに発生したクラッシュ情報をアップロードするため、インターネット権限を与える必要があります。

{% code title="AndroidManifest.xml" %}

```xml
<uses-permission android:name="android.permission.INTERNET"/>
```

{% endcode %}

## 4. ソースコードにIMQA初期化コード挿入

### IMQA開始コード作成

{% hint style="warning" %}
ActivityではなくApplicationクラスに挿入する必要があります。

このとき、「PROJECT\_KEY」部分にコピーした「Project Key」の値を挿入してください。
{% endhint %}

{% code title="MyApplication.java" %}

```java
...
@Override
public void onCreate() {
    super.onCreate();
    io.imqa.core.IMQAOption imqaOption = new io.imqa.core.IMQAOption();
    imqaOption.setBuildType(false);
    imqaOption.setUploadPeriod(true);
    imqaOption.setKeepFileAtUploadFail(false);
    imqaOption.setDumpInterval(10000);
    imqaOption.setFileInterval(5);
    imqaOption.setHttpTracing(true);
    imqaOption.setRemoteControl(true);

    io.imqa.mpm.IMQAMpmAgent.getInstance()
        .setOption(imqaOption) // Sets an option to decide the MPM operation method.
        .setContext(this, BuildConfig.FLAVOR) 
        // Initializes the application context. (Insert an empty string if there is no flavor)
        .setProjectKey("PROJECT_KEY") 
        // Sets the project key of the IMQA MPM client.
        .init(); 
        // Initializes and executes the registered option.
    ...
}
...
```

{% endcode %}

{% code title="MyApplication.kt" %}

```kotlin
...
override fun onCreate() {
    super.onCreate()
    val imqaOption : IMQAOption = io.imqa.core.IMQAOption()
    imqaOption.setBuildType(false)
    imqaOption.setUploadPeriod(true)
    imqaOption.setKeepFileAtUploadFail(false)
    imqaOption.setDumpInterval(10000)
    imqaOption.setFileInterval(5)
    imqaOption.setHttpTracing(true)
    imqaOption.setRemoteConfig(true)

    io.imqa.mpm.IMQAMpmAgent.getInstance()
        .setOption(imqaOption) 
        // Sets an option to decide the MPM operation method.
        .setContext(this, BuildConfig.FLAVOR) 
        // Initializes the application context. (Insert an empty string if there is no flavor)
        .setProjectKey("PROJECT_KEY") 
         // Sets the project key of the IMQA MPM client.
        .init(); 
         // Initializes and executes the registered option.
    ...
}
...
```

{% endcode %}

### MPM Mode Option

IMQA MPM実行オプションをパラメータやOptionを利用して変更することができます。Android MPM Configuration Optionsで実行オプションを確認してください。

### 短縮モード <a href="#shorten" id="shorten"></a>

短縮モードを利用すると、IMQA MPMを初期化することができます。

{% code title="MyApplication.java" %}

```java
...
override fun onCreate() {
    super.onCreate()

    io.imqa.mpm.IMQAMpmAgent.getInstance()
        .setContext(this, BuildConfig.FLAVOR) // Initializes the application context. (Insert an empty string if there is no flavor)
        .setProjectKey("PROJECT_KEY") // Sets the project key of the IMQA MPM client.
        .init() // Initializes and executes the registered option.
    ...
}
...
```

{% endcode %}

{% code title="MyApplication.kt" %}

```kotlin
...
override fun onCreate() {
    super.onCreate()

    io.imqa.mpm.IMQAMpmAgent.getInstance()
        .setContext(this, BuildConfig.FLAVOR) // Initializes the application context. (Insert an empty string if there is no flavor)
        .setProjectKey("PROJECT_KEY") // Sets the project key of the IMQA MPM client.
        .init() // Initializes and executes the registered option.
    ...
}
...
```

{% endcode %}

### ⚠️**HTTPS (API level > 27)**

Android API 28から強化されたネットワークセキュリティポリシーにより、HTTPSリクエストが必要となりました。 これを解決するためには、以下の措置を講じる必要があります。

1. **認証されたHTTPSリクエスト**\
   IMQAサーバーで認証されたHTTPSのリクエストを行って正常に収集してください。

{% code title="MyApplication.java or MyApplication.kt" %}

```kotlin
...
imqaOption.setServerUrl('https://collector.imqa.io');
...
```

{% endcode %}

2. &#x20;**強制HTTPリクエスト**\
   このflagを設定すると、すべてのcleartextトラフィックに対して許可処理を実行できます。

{% code title="AndroidManifest.xml" %}

```xml
...
<application
    ...
    android:usesCleartextTraffic="true"
    />
...
```

{% endcode %}

### Zstandard圧縮アルゴリズムの使用

一般的なgzipではなく、安全で圧縮効率の高いZstandard圧縮アルゴリズムを使用できます。 これを使用するには、次の設定が必要です。

**MPM Mode Optionの設定**\
IMQA開始コードを挿入するときに設定でzstdを使用するかどうかを設定できます。

{% code title="MyApplication.java or MyApplication.kt" %}

```
...
imqaOption.setCompressZstd(true);
...
```

{% endcode %}

**Zstdライブラリの追加**\
「app.gradle」ファイルの「buildscript」内の「dependencies」ブロックに「zstd-jni」aarライブラリを追加します。

{% code title="app.gradle(app module)" %}

```
...
    dependencies {
    // Add dependencies.
       ...
       implementation 'com.github.luben:zstd-jni:1.5.2-3@aar'
       ...
    } 
} 
```

{% endcode %}

## 5. ⚠️現在のバージョンで発生する可能性のある不具合

### ASM <a href="#asm" id="asm"></a>

ASMを使用するライブラリと衝突が発生することがあります。<br>

### APK Repackaging <a href="#apk" id="apk"></a>

APK Repackaging中にソースのライン情報が消えます。ライン情報を含めたい場合は、自動挿入機能をCompile中に実行する必要があります。<br>

### Library情報収集 <a href="#library" id="library"></a>

Libraryに追加されたclassファイルは、自動挿入機能が実行されません。Libraryで実行される情報も収集したい場合は、自動挿入機能をAPK Repackaging中に実行してください。

## 6. インストール型顧客の必須設定事項&#x20;

IMQAインストール型をご利用される顧客会社の場合、必ず収集サーバーを設定してください。

{% code title="MyApplication.java" %}

```java
...
@Override
public void onCreate() {
    super.onCreate();
    io.imqa.core.IMQAOption imqaOption = new io.imqa.core.IMQAOption();

    /*
     * Default value: 'https://collector.imqa.io'
     * Sets the MPM server URL.
     * String: Server information
     */
    imqaOption.setServerUrl('https://(IPAddress)');

    io.imqa.mpm.IMQAMpmAgent.getInstance()
        .setOption(imqaOption) // Sets the option to decide the MPM operation method.
        .setContext(this, BuildConfig.FLAVOR) // Initializes the application context. (Insert an empty string if there is no flavor)
        .setProjectKey("PROJECT_KEY") // Sets the project key of the IMQA MPM client.
        .init() // Initializes and executes the registered option.
    ...
}
...
```

{% endcode %}
