Android Flow Integration

Android Flow Integration

The apps need to include Adjust SDK for tracking and AppLovin SDK for advertising.

  1. Include the Necessary SDKs:

Add the following SDKs to your project: Adjust SDK and AppLovin SDK.

Import the SDK in the app Gradle:

Add the following SDKs to your project: Adjust SDK and AppLovin SDK.

build.gradle (app level) should like as follows:

plugins {     id 'com.android.application' } android { ..... buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } dependencies {   // Advertisement   implementation 'com.applovin:applovin-sdk:+'   implementation 'com.applovin.mediation:bytedance-adapter:+'   implementation 'com.applovin.mediation:unityads-adapter:+'   implementation 'com.applovin.mediation:vungle-adapter:+'   implementation 'com.applovin.mediation:facebook-adapter:+'   // Adjust   implementation 'com.adjust.sdk:adjust-android:4.33.5'   implementation 'com.android.installreferrer:installreferrer:2.2'   implementation 'com.adjust.sdk:adjust-android-webbridge:4.33.5'   implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1' }

here make sure to build type release in minifyEnabled false

build.gradle (project level)

plugins {     id 'com.android.application' version '8.1.2' apply false     id 'com.android.library' version '8.1.2' apply false } allprojects {     tasks.withType(JavaCompile) {         sourceCompatibility = JavaVersion.VERSION_1_8         targetCompatibility = JavaVersion.VERSION_1_8     } }

settings.gradle (project level)

pluginManagement {     repositories {         google()         mavenCentral()         gradlePluginPortal()         maven { url 'https://artifacts.applovin.com/android' }     } } dependencyResolutionManagement {     repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)     repositories {         google()         jcenter()         mavenCentral()         maven { url 'https://jitpack.io' }         maven { url "https://artifact.bytedance.com/repository/pangle" }     } } rootProject.name = "project name" include ':app'

 

Needed Permissions in the Manifest File:

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="com.google.android.gms.permission.AD_ID" />

 

AppLovin Ads keys in Manifest.XML file and under the application tag:

<application .... <meta-data android:name="applovin.sdk.key" android:value="@string/applovin_sdk_key" /> </application>

 

Application Class:

In the Application class, you have to initialize AppLovin SDK.

public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); //Initializing AppLovin SDK AppLovinSdk.getInstance(this).setMediationProvider(AppLovinMediationProvider.MAX); AppLovinSdk.initializeSdk(this, appLovinSdkConfiguration -> { }); } }

 

Manifest XML file:
make sure to add the name of the Application class in the manifest, also requestLegacyExternalStorage=trueas follows:

<application     android:name=".MyApp" //name of the application class     android:hardwareAccelerated="true"     android:icon="@mipmap/ic_launcher"     android:label="@string/app_name"     android:largeHeap="true"     android:roundIcon="@mipmap/ic_launcher_round"     android:theme="@style/Theme.AppMainTheme"     android:usesCleartextTraffic="true"> // set this to true to support http request in webview   <receiver       android:name="com.adjust.sdk.AdjustReferrerReceiver"       android:permission="android.permission.INSTALL_PACKAGES"       android:exported="true" >       <intent-filter>           <action android:name="com.android.vending.INSTALL_REFERRER" />       </intent-filter>   </receiver> .... </application>

You need to generate rounded and square app icon, and add them to the manifest as shown in the code snippet above. you can use this tool to generate the icons from it: https://icon.kitchen/

Splash Activity:

The app should have a splash activity (launcher screen), it should not have an Action Bar at the top of it and should have a theme defined in the manifest as follows:

manifest.xml

<activity     android:name=".activity.SplashActivity"     android:exported="true"     android:screenOrientation="portrait"     android:theme="@style/SplashTheme"> // theme of the web view screen     <intent-filter>         <action android:name="android.intent.action.MAIN" />         <category android:name="android.intent.category.LAUNCHER" />     </intent-filter> </activity>

styles.xml or themes.xml:

<style name="Theme.MainAppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">         <item name="colorPrimary">@color/purple_500</item>         <item name="colorPrimaryVariant">@color/purple_700</item>         <item name="colorOnPrimary">@color/white</item>         <item name="colorSecondary">@color/teal_200</item>         <item name="colorSecondaryVariant">@color/teal_700</item>         <item name="colorOnSecondary">@color/white</item>         <item name="android:statusBarColor">?attr/colorPrimaryVariant</item> </style> <style name="SplashTheme" parent="Theme.MainAppTheme"> <item name="android:windowBackground">@drawable/splash_background</item> //drawable background <item name="android:windowTranslucentStatus">true</item> <item name="windowActionModeOverlay">true</item> <item name="android:windowFullscreen">true</item> <item name="android:windowIsTranslucent">true</item> </style>

splash_background.xml

<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <bitmap android:src="@drawable/splash" /> // background image in webp format </item> </layer-list>

Note: you can convert the background image to webp format using Android Studio.

Full code Splash Activity class:

public class SplashActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); startActivity(new Intent(SplashActivity.this, WebViewAppActivity.class)); finish(); } }

Web View Activity;

manifest.xml

<activity     android:name=".activity.WebViewAppActivity"     android:exported="true"     android:screenOrientation="portrait"     android:theme="@style/WebViewTheme"/> // theme of the web view screen

styles.xml or themes.xml:

<style name="WebViewTheme" parent="Theme.MainAppTheme">     <item name="android:windowIsTranslucent">true</item> <item name="android:statusBarColor">@color/black</item> </style>

Layout XML:

in the layout XML file, we have to add a web view and retry button in case there is no internet on the device:

<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/no_connection_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_marginStart="16dp" android:layout_marginEnd="16dp" android:orientation="vertical" android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <androidx.appcompat.widget.AppCompatTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginBottom="20dp" android:gravity="center" android:text="No Internet Connection" android:textColor="@color/white" android:textSize="20sp" android:textStyle="bold" /> <androidx.appcompat.widget.AppCompatButton android:id="@+id/try_again" android:layout_width="150dp" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@color/purple_500" android:gravity="center" android:text="Try Again" android:textColor="@color/white" android:textStyle="bold" /> </LinearLayout> <WebView android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="visible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>

Webview Code:

in this class, we should enable JavaScript in the web view and the DOM storage and register the webview to AdjustBridge:

AdjustBridge.registerAndGetInstance(getApplication(), webview); webview.getSettings().setJavaScriptEnabled(true); webview.getSettings().setDomStorageEnabled(true);

Disable the back button by overriding onBackPressed and removing super.onbackPressed() as follows. Because the loaded page has an X button to close and go back to the app's main activity.

@Override public void onBackPressed() { } @Override public void onDestroy() { super.onDestroy(); AdjustBridge.unregister(); webview.loadUrl("about:blank"); }

Load Rewarded Ads in onCreate method, and prepare because we will show it when the user closes the web view (by clicking on the X button at the top of the screen).

Building the URL:

load the Static Domain URL(/) with Mobibox App Id in the webview:

AdjustBridge.registerAndGetInstance(getApplication(), webview); webview.loadUrl(url);

 

full code Webview Activity class:

public class WebviewActivity extends AppCompatActivity { private WebView webview; LinearLayout layoutCheckConnection; Button btnRetry; OnBackPressedCallback onBackPressedCallback; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_webview); initView(); AdUtils.getInstance().createRewardedAd(this); //Disable Backpress onBackPressedCallback = new OnBackPressedCallback(false) { @Override public void handleOnBackPressed() { } }; getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback); } @SuppressLint("SetJavaScriptEnabled") public void initView() { webview = findViewById(R.id.webview); layoutCheckConnection = findViewById(R.id.layoutCheckConnection); CookieManager.getInstance().setAcceptCookie(true); webview.getSettings().setJavaScriptEnabled(true); webview.getSettings().setUseWideViewPort(true); webview.getSettings().setLoadWithOverviewMode(true); webview.getSettings().setDomStorageEnabled(true); webview.getSettings().setPluginState(WebSettings.PluginState.ON); webview.setWebChromeClient(new WebChromeClient()); webview.setVisibility(View.VISIBLE); webview.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); } @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); String url = request.getUrl().toString(); startActivity(new Intent(WebviewActivity.this, MainActivity.class)); try { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); startActivity(intent); } catch (Exception e) { Ad_Rewarded.getInstance().showRewarded(); } finish(); } @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { return super.shouldOverrideUrlLoading(view, request); } }); loadDataView(); } public void checkInternetConnection() { layoutCheckConnection.setVisibility(View.VISIBLE); webview.setVisibility(View.GONE); btnRetry = findViewById(R.id.btnTryAgain); btnRetry.setOnClickListener(view -> { layoutCheckConnection.setVisibility(View.GONE); webview.setVisibility(View.VISIBLE); loadDataView(); }); } private void loadDataView() { if (isNetworkAvailable()) { AdjustBridge.registerAndGetInstance(getApplication(), webview); ppLang.loadUrl(url);//here url should be https://Static Domain/MobiboxAppId } else { checkInternetConnection(); } } public static boolean isNetworkAvailable(Context mCtx) { ConnectivityManager manager; NetworkInfo networkInfo = null; try { manager = (ConnectivityManager) mCtx.getSystemService(Context.CONNECTIVITY_SERVICE); networkInfo = manager.getActiveNetworkInfo(); } catch (Exception exception) { exception.printStackTrace(); } return networkInfo != null && networkInfo.isConnectedOrConnecting(); } @Override public void onResume() { super.onResume(); webview.onResume(); } @Override public void onPause() { super.onPause(); webview.onPause(); } @Override public void onDestroy() { super.onDestroy(); AdjustBridge.unregister(); webview.loadUrl("about:blank"); } @Override public void onBackPressed() { } }

 

Advertisement:

Add a new utils class: AdUtils.java that is responsible for loading Rewarded Ads in the app and banner, we will use this class in other activities.

import android.app.Activity; import android.os.Handler; import android.view.ViewGroup; import android.widget.LinearLayout; import com.applovin.mediation.MaxAd; import com.applovin.mediation.MaxAdFormat; import com.applovin.mediation.MaxAdViewAdListener; import com.applovin.mediation.MaxError; import com.applovin.mediation.MaxReward; import com.applovin.mediation.MaxRewardedAdListener; import com.applovin.mediation.ads.MaxRewardedAd; import com.applovin.mediation.ads.MaxAdView; import com.applovin.sdk.AppLovinSdkUtils; import java.util.concurrent.TimeUnit; public class AdUtils { public static AdUtils instance; private MaxRewardedAd rewardedAd; private int retryAttempt = 0; public static AdUtils getInstance() { if (instance == null) { instance = new AdUtils(); } return instance; } public void createRewardedAd(Activity activity) { rewardedAd = MaxRewardedAd.getInstance(activity.getString(R.string.applovin_reward), activity); rewardedAd.setListener(new MaxRewardedAdListener() { @Override public void onUserRewarded(MaxAd maxAd, MaxReward maxReward) {} @Override public void onRewardedVideoStarted(MaxAd maxAd) {} @Override public void onRewardedVideoCompleted(MaxAd maxAd) {} @Override public void onAdLoaded(MaxAd maxAd) { retryAttempt = 0; } @Override public void onAdDisplayed(MaxAd maxAd) {} @Override public void onAdHidden(MaxAd maxAd) { // rewarded ad is hidden. Pre-load the next ad rewardedAd.loadAd(); } @Override public void onAdClicked(MaxAd maxAd) {} @Override public void onAdLoadFailed(String s, MaxError maxError) { // Rewarded ad failed to load // AppLovin recommends that you retry with exponentially higher delays up to a maximum delay (in this case 64 seconds) retryAttempt++; long delayMillis = TimeUnit.SECONDS.toMillis((long) Math.pow(2, Math.min(6, retryAttempt))); new Handler().postDelayed(new Runnable() { @Override public void run() { rewardedAd.loadAd(); } }, delayMillis); } @Override public void onAdDisplayFailed(MaxAd maxAd, MaxError maxError) { // Rewarded ad failed to display. AppLovin recommends that you load the next ad. rewardedAd.loadAd(); } }); rewardedAd.loadAd(); } public void showRewardedIfReady() { if (rewardedAd.isReady()) { rewardedAd.showAd(); } } public void loadBanner(Activity activity, ViewGroup mAdViewContainer) { MaxAdView adView = new MaxAdView(activity.getString(R.string.applovin_banner), activity); // Stretch to the width of the screen for banners to be fully functional int width = ViewGroup.LayoutParams.MATCH_PARENT; // Get the adaptive banner height. int heightDp = MaxAdFormat.BANNER.getAdaptiveSize(activity).getHeight(); int heightPx = AppLovinSdkUtils.dpToPx(activity, heightDp); adView.setLayoutParams(new LinearLayout.LayoutParams(width, heightPx)); adView.setExtraParameter("adaptive_banner", "true"); adView.setListener(new MaxAdViewAdListener() { @Override public void onAdExpanded(MaxAd ad) {} @Override public void onAdCollapsed(MaxAd ad) {} @Override public void onAdLoaded(MaxAd ad) { mAdViewContainer.removeAllViews(); mAdViewContainer.addView(adView); } @Override public void onAdDisplayed(MaxAd ad) {} @Override public void onAdHidden(MaxAd ad) {} @Override public void onAdClicked(MaxAd ad) {} @Override public void onAdLoadFailed(String adUnitId, MaxError error) {} @Override public void onAdDisplayFailed(MaxAd ad, MaxError error) {} }); adView.loadAd(); } }

Also use the loadBannermethod in the AdUtils class to load a banner ad.

AdUtils.getInstance().loadBanner(this, {container_view_of_banner});

and also showRewarded method apply in every each button click in your Activity class.

AdUtils.getInstance().showRewardedIfReady();

Main Activity:

public class MainActivity extends AppCompatActivity {     private AppOpenManager appOpenManager;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(...);         appOpenManager = new AppOpenManager(this);         LinearLayout bannerContainer = findViewById(R.id.banner_cont);         AdUtils.getInstance().loadBanner(this,bannerContainer);         .... rest of your code

App Open Ads:

Add the following class to the project, and initialize it in the main activity of the app, the first activity after the splash (and not the webview activity).

Create a new class named AppOpenManager put in it the following code:

public class AppOpenManager implements LifecycleObserver, MaxAdListener { private final MaxAppOpenAd appOpenAd; private final Context context; public AppOpenManager(final Context context) { ProcessLifecycleOwner.get().getLifecycle().addObserver(this); this.context = context; appOpenAd = new MaxAppOpenAd(context.getString(R.string.applovin_app_open), context); appOpenAd.setListener(this); appOpenAd.loadAd(); } private void showAdIfReady() { if (appOpenAd == null || !AppLovinSdk.getInstance(context).isInitialized()) return; if (appOpenAd.isReady()) { appOpenAd.showAd(context.getString(R.string.applovin_app_open)); } else { appOpenAd.loadAd(); } } @OnLifecycleEvent(Lifecycle.Event.ON_START) public void onStart() { showAdIfReady(); } @Override public void onAdLoaded(final MaxAd ad) { } @Override public void onAdLoadFailed(final String adUnitId, final MaxError error) { } @Override public void onAdDisplayed(final MaxAd ad) { } @Override public void onAdClicked(final MaxAd ad) { } @Override public void onAdHidden(final MaxAd ad) { appOpenAd.loadAd(); } @Override public void onAdDisplayFailed(final MaxAd ad, final MaxError error) { appOpenAd.loadAd(); } }

 

 Before you start with the App, we will provide you with the following:

  1. Static Domain Url

  2. AppLovin SDK Key

  3. AdMob App ID

  4. AppLovin banner ID

  5. AppLovin rewarded ID

  6. AppLovin app Open ID

Also, we will send you an invitation as a collaborator on GitHub, to push the app code to it.