# Android

{% hint style="warning" %}
IMQA SDK Installation Guide\_Cordova provides instructions for applying IMQA SDK in the Cordova environment.

After applying the IMQA agent code with reference to the IMQA MPM Installation Guide, please follow further the instructions of this document.
{% endhint %}

## 1. Installing Gradle plugin&#x20;

In the “app.gradle” file, add “imqa-mpm-injector” to the “dependencies” block in the "buildscript" followed by “plugin” at the top. This is typically located in “\<project\_dir>/app/build.gradle”.

{% hint style="warning" %}
The gradle file should be synchronized after updating the file.
{% 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.5'
       implementation 'io.imqa:imqa-mpm-client:2.27.9'
       implementation 'io.imqa:imqa-crash-client:2.27.5'
    } 
} 

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 {
    // Add dependencies.
       implementation 'io.imqa:imqa-core:2.27.5'
       implementation 'io.imqa:imqa-mpm-client:2.27.9'
       implementation 'io.imqa:imqa-crash-client:2.27.5'
    } 
} 

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.5'
       implementation 'io.imqa:imqa-mpm-client:2.27.9'
       implementation 'io.imqa:imqa-crash-client:2.27.5'
    } 
} 

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=Path of project (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 %}

## 2. Adding authority to the Android Manifest

You have to grant Internet authority to upload occurred crash information to AndroidManifest.xml.

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

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

{% endcode %}

## 3. Setting Cordova Library

{% hint style="warning" %}
How to add IMQABridge may vary depending on development using Cordova.
{% endhint %}

### 3.1. WebView HTTP request

#### Setting the web server

If you want to collect WebView data, you need to embed the IMQA WebView JavaScript library into a web page that supports WebView. You can download the file and serve it directly from your web server. (We recommend importing it directly to avoid CORS issues.)

{% code title="Inserting a WebView file" %}

```
<!-- IMQA Webview Agent(ver. 1.1.3 earlier) -->
<script type="text/javascript" src="https://imqawebviewagent.blob.core.windows.net/agent/webview-agent-1.1.2.js"
crossorigin></script>

// If you want to apply it as a min file:
<script type="text/javascript" src="https://imqawebviewagent.blob.core.windows.net/agent/webview-agent-1.1.2.min.js"
crossorigin></script>
```

{% endcode %}

{% code title="index.html" %}

```html
<!-- IMQA Webview Agent (ver. 1.1.3 later) -->
<script type="text/javascript" src="https://cdn.imqa.io/agent/webview-agent-1.1.3.js"
crossorigin></script>

<script>
    ((w, c, _wv, _w, _wk, _mh, _b) => {        
       w[_wv](w); // Webview Agent Execution Function
    })(window, 'imqaClientConfig', 'IMQAWebviewMain', 'IMQAWebMain', 'webkit', 'messageHandlers', 'ImqaBridge')
</script>
```

{% endcode %}

#### Gradle( build.gradle ) Set up

You need to add IMQA SDK so that the IMQA code can be declared inside the Cordova library.

{% code title="build.gradle ( Cordova Library ) " %}

```gradle
dependencies {
    ...
    Implementation 'androidx.appcompat:appcompat:1.3.0'

    //Add the Latest IMQA SDK
       implementation 'io.imqa:imqa-core:2.27.5'
       implementation 'io.imqa:imqa-mpm-client:2.27.9'
       implementation 'io.imqa:imqa-crash-client:2.27.5'
		
}
```

{% endcode %}

#### Android Agent Setup

MPM collects pages and requests related to WebView. To enable the collection, you need to set up options and add MPMWebviewInterface.

{% code title="org/apache/cordova/CordovaActivity.java" %}

```java

..

protected void init() {
   appView = makeWebView();
   createViews();
   if (!appView.isInitialized()) {
       appView.init(cordovaInterface, pluginEntries, preferences);
   }
   cordovaInterface.onCordovaInit(appView.getPluginManager());

   // Inserting WebView Interface (ImqaBridge required)
   WebView wV = (WebView) appView.getEngine().getView();
   wV.addJavascriptInterface(new     io.imqa.mpm.network.webview.WebviewInterface(),"ImqaBridge");
   // Wire the hardware volume controls to control media if desired.

   String volumePref = preferences.getString("DefaultVolumeStream", "");
   if ("media".equals(volumePref.toLowerCase(Locale.ENGLISH))) {
       setVolumeControlStream(AudioManager.STREAM_MUSIC);
   }
}
```

{% endcode %}

{% code title="org/apache/cordova/engine/SystemWebviewEngine.java" %}

```

..

private static void exposeJsInterface(WebView webView, CordovaBridge bridge) {
   if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)) {
       LOG.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old.");
       // Bug being that Java Strings do not get converted to JS strings automatically.
       // This isn't hard to work-around on the JS side, but it's easier to just
       // use the prompt bridge instead.
       return;
   }
   SystemExposedJsApi exposedJsApi = new SystemExposedJsApi(bridge);

   // Inserting WebView Interface (ImqaBridge required)
   webView.addJavascriptInterface(new io.imqa.mpm.network.webview.WebviewInterface(),"ImqaBridge");

   webView.addJavascriptInterface(exposedJsApi, "_cordovaNative");
}

```

{% endcode %}
