newsmemory-android-sdk/README.md

13 KiB

Android SDK

Table of Contents

Import

You must use git to download the sdk from repository

  1. The repository is private, to clone it you must generate an ssh key, see the guide
  2. Once the key is generate you must send to Tecnavia the public key and wait a confirmation that you are enabled
  3. Inside root folder run the following command, replace TAG with the latest release, see the list on releases
git clone --depth 1 --brach TAG git@github.com:tecnaviapress/newsmemory-android-sdk.git
  1. if you already has the module you could update to another release by the following commands
cd newsmemory-android-sdk
git checkout tags/TAG

Installation

Project Gradle

  1. check main gradle repositories and dependencies
buildscript {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }

    dependencies {
        classpath "com.android.tools.build:gradle:4.2.2"
        classpath "com.google.gms:google-services:4.3.4"
        //add crashlytics only if the aar file is included
        classpath "com.google.firebase:firebase-crashlytics-gradle:2.3.0"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0"

    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        mavenLocal()
        gradlePluginPortal()
        maven {
            url "https://jitpack.io"
        }

        //If photodraweeview:1.1.3 for some reason is not available from Maven force this version
        configurations.all {
            resolutionStrategy {
                force "me.relex:photodraweeview:2.1.0"
            }
        }
    }
}
  1. if you are using sdk for amazon and it is built for it add the following maven repository
maven { 
    url "https://s3.amazonaws.com/android-listener/mvn-repo" 
}
  1. you could customize all dependencies version by updating the following variables, !pay attention, because the sdk may not starts or works properly add these variables to ext object in main gradle file, see below example.
variable default Description
compileSdk 33
targetSdk 33
minSdk 24
frescoVersion 2.5.0 used by react native to display some images
soLoaderVersion 0.10.1 used to load needed system native libraries
okHttpVersion 4.9.2
glideVersion 4.12.0
kotlinGradleVersion 1.5.0
kotlinVersion 1.4.0
webkitVersion 1.4.0
androidxVersion 1.5.0
androidxWorkRuntimeVersion 1.5.0
androidxAnnotationVersion 1.4.0
androidxViewpager2Version 1.0.0
androidxFragmentVersion 1.4.1
androidxBrowserVersion 1.4.0
androidxTransitionVersion 1.1.0
androidxCoordinatorlayoutVersion 1.1.0
androidxSwiperefreshlayoutVersion 1.0.0
androidxAppcompatVersion 1.0.2
androidxLegacySupportVersion 1.0.0
playServiceiidVersion 17.0.0
playServiceBaseVersion 18.0.1
The following variables are used if you include on of the optional library listed in description
playServiceAnalyticsVersion 18.0.1 react-native-google-analytics-bridge
playServiceAdsVersion 20.6.0 react-native-prebid, react-native-dfp, react-native-admob
playServiceMapsVersion 17.0.0 react-native-maps
playBillingVersion 5.0.0 react-native-iap for google
amazonSdkVersion 3.0.3 react-native-iap for amazon
ext {
    compileSdk = 34
    androidxVersion = "1.4.0"
    ...
}

Settings Gradle

include ':newsmemory-android-sdk'

App Gradle

add the following lines if missing

plugin: "com.android.application"
apply plugin: "com.google.gms.google-services"
//add crashlytics only if the aar file is included
apply plugin: 'com.google.firebase.crashlytics'

android{
   ...

   defaultConfig {
       ...
       //This line is required by react-native-iap, not included by default
       missingDimensionStrategy "store", "play"
   }

   ...

   packagingOptions {
       pickFirst "lib/x86/libc++_shared.so"
       pickFirst "lib/x86_64/libc++_shared.so"
       pickFirst "lib/arm64-v8a/libc++_shared.so"
       pickFirst "lib/armeabi-v7a/libc++_shared.so"
   }
}

dependencies{
   implementation project(":newsmemory-android-sdk")
   ...
}

Add fragment to activity

public class YourActivity extends AppCompatActivity {
    private TaFragment taFragment;
    ...
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(taFragment == null) {
            taFragment = new TaFragment()
                .setDelegate(new TaFragmentDelegate() {
                    @Override
                    public void recreate() {
                        YourActivity.this.recreate();
                    }

                    @Override
                    public boolean isActionModeVisible() {
                        return false;
                    }

                    @Override
                    public boolean handleClose(){
                        //TODO implement it and return true if you consume the event
                        return false;
                    }

                    @Override
                    public boolean handleOpenUrl(String url){
                        //TODO implement it and return true if you consume the event
                        return false;
                    }

                    @Override
                    public boolean handleTrackAction(Bundle data){
                        //TODO implement it and return true if you consume the event
                        return false;
                    }
                    
                    @Override
                    public boolean handleTokenExpired(){
	                    //TODO implement it and return true if you consume the event
                        return false;
                    }
                })
                .setBuildProps(getBuildProps());
        } else {
            taFragment = (TaFragment) getSupportFragmentManager().findFragmentByTag("TA_FRAGMENT");
        }
         
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.rnFragment, taFragment, "TA_FRAGMENT")
                .commit();
    }

    public Bundle getBuildProps() {
        Bundle bundle = new Bundle();
        bundle.putString(TaConstants.TA_PSETUP, "replace_with_psetup");
        bundle.putString(TaConstants.TA_MACHINE, "replace_with_server");
        bundle.putString(TaConstants.TA_LOCALE, "en");
        bundle.putString(TaConstants.TA_TOKEN, "replace with a valid token");
        //the value inside R.string will be avilable after first build
        bundle.putString(TaConstants.TA_APP_VERSION_NAME, getString(com.tecnavia.sdk.R.string.APP_VERSION_NAME));
        bundle.putString(TaConstants.TA_APP_VERSION_CODE, getString(com.tecnavia.sdk.R.string.APP_VERSION_CODE));
        bundle.putString(TaConstants.TA_ANDROID_APP_ID,getString(com.tecnavia.sdk.R.string.ANDROID_APP_ID));
        bundle.putString(TaConstants.TA_APP_NAME, getString(com.tecnavia.sdk.R.string.APP_NAME));
        //must be true otherwise the module doesn't work in SDK mode
        bundle.putBoolean(TaConstants.TA_IS_ADDON, true);
        bundle.putString(TaConstants.TA_API_KEY, "Required to be authorized");
        
        // Specify the device type for the TA_LOCKED_ORIENTATION. If not provided, all devices will use TA_LOCKED_ORIENTATION.
        bundle.putString(TaConstants.TA_LOCKED_ORIENTATION_DEVICE, "tablet|phone");

        // Define the orientation for the app. If not specified, the app will use its default behavior.
        bundle.putString(TaConstants.TA_LOCKED_ORIENTATION, "portrait|landscape");
        return bundle;
    }
}

the following constant is required by SDK to be authorized

	bundle.putString(TaConstants.TA_API_KEY, "");

the following constants are required by SDK otherwise there will be some inconsinstecies and bugs

    bundle.putString(TaConstants.TA_APP_VERSION_NAME, getString(com.tecnavia.sdk.R.string.APP_VERSION_NAME));
    bundle.putString(TaConstants.TA_APP_VERSION_CODE, getString(com.tecnavia.sdk.R.string.APP_VERSION_CODE));
    bundle.putString(TaConstants.TA_ANDROID_APP_ID,getString(com.tecnavia.sdk.R.string.ANDROID_APP_ID));
    bundle.putString(TaConstants.TA_APP_NAME, getString(com.tecnavia.sdk.R.string.APP_NAME));
    bundle.putBoolean(TaConstants.TA_IS_ADDON, true);
  1. The activity that load TaFragment must implement the following interface DefaultHardwareBackBtnHandler
public class YourActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
    ...
    
    @Override
    public void invokeDefaultOnBackPressed() {
        //TODO handle finish
    }
}
  1. you could extends activity class with TaActivity that already has an implementation of DefaultHardwareBackBtnHandler but also add some other methods to force locale.
public class YourActivity extends TaActivity {
    ...
}

Troubleshooting Guide

  1. Google Play Services Build Issues: If you encounter build issues related to Google Play Services versions, consider adding the following setting to your build.gradle file:
android {
    ...
    googleServices {
        disableVersionCheck = true
    }
    ...
}
  1. Java Base Access Error: If you receive an error during the build process that reads Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not "opens java.io" to unnamed module, add the --add-opens=java.base/java.io=ALL-UNNAMED option to the org.gradle.jvmargs entry in your gradle.properties file:
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 --add-opens=java.base/java.io=ALL-UNNAMED
  1. Orientation Change Crash: If your application crashes when the orientation changes, add the following attributes to your activity in the Android manifest:
configChanges="...|screenLayout|screenSize|smallestScreenSize"

For more information, refer to this GitHub issue comment.

  1. Background or Awakening Crash: If your application crashes when it moves to the background or wakes up, try adding the following to your activity:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
}

For more information, refer to this GitHub issue comment.

Authors

Nicolò Aquilini, iOS Software developer, Tecnavia Andrea Mauri, Android Software developer, Tecnavia