2

I am writing an app using both the aws android api and the aws Amplify api. The issue occurs when I am using methods from AWSKinesisVideoClient (look at the line starting with Caused by).

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.appliedstructures.myapp_v002, PID: 32474
java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$4.done(AsyncTask.java:399)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
    at java.util.concurrent.FutureTask.run(FutureTask.java:271)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:919)
 Caused by: java.lang.NoSuchFieldError: No instance field timeOffset of type I in class Lcom/amazonaws/services/kinesisvideo/AWSKinesisVideoClient; or its superclasses (declaration of 'com.amazonaws.services.kinesisvideo.AWSKinesisVideoClient' appears in /data/app/com.appliedstructures.myapp_v002-ktjX0i0uX6YfDy0RwrPWFA==/base.apk)
    at com.amazonaws.services.kinesisvideo.AWSKinesisVideoClient.invoke(AWSKinesisVideoClient.java:1532)
    at com.amazonaws.services.kinesisvideo.AWSKinesisVideoClient.describeSignalingChannel(AWSKinesisVideoClient.java:653)
    at com.appliedstructures.myapp_v002.ui.home.HomeFragment$InfoUpdaterTask.doInBackground(HomeFragment.java:141)
    at com.appliedstructures.myapp_v002.ui.home.HomeFragment$InfoUpdaterTask.doInBackground(HomeFragment.java:102)

However, when I manually inspect the code in that class, there is clearly a field called timeOffset. I read online that a source of this issue might be android's ProGuard (since it can remove unused code and accidentally remove this field as well). However, in my gradle.build I directly specified minifyEnabled false in both release and debug.

here is my gradle.build (root):

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        google()
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.3"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

And here is gradle.build (app):

plugins {
    id 'com.android.application'
}

android {
    compileSdk 30

    defaultConfig {
        applicationId "com.appliedstructures.myapp_v002"
        minSdk 24
        targetSdk 30
        versionCode 1
        versionName "1.0"
        android
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    packagingOptions {
        exclude 'com/fasterxml/jackson/databind/cfg/VERSION.txt'
        exclude 'com/fasterxml/jackson/core/json/VERSION.txt'
        exclude 'META-INF/DEPENDENCIES'
    }

    buildTypes {
        release {
            minifyEnabled false
            //proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            minifyEnabled false
        }
    }
    compileOptions {
        coreLibraryDesugaringEnabled true
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    buildFeatures {
        viewBinding true
    }
}

dependencies {
    //builAmplify dependencies
    implementation 'com.amplifyframework:core:1.28.1'
    implementation 'com.amplifyframework:aws-auth-cognito:1.28.1'

    //aws dependencies
    def aws_version = '2.16.13'
    implementation ("com.amazonaws:aws-android-sdk-kinesisvideo:$aws_version@aar") { transitive = true }
    implementation ("com.amazonaws:aws-android-sdk-kinesisvideo-signaling:$aws_version@jar") { transitive = true }
    implementation ("com.amazonaws:aws-android-sdk-mobile-client:$aws_version@aar") { transitive = true }
    implementation ("com.amazonaws:aws-android-sdk-auth-userpools:$aws_version@aar") { transitive = true }

    //android default dependencies
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
    implementation 'androidx.navigation:navigation-fragment:2.3.5'
    implementation 'androidx.navigation:navigation-ui:2.3.5'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    //support for Java 8 features
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}

So what is the source of the problem and how can it be fixed (refreshing gradle, and restarting android studio did not work)?

Edit: Here is the exact code snippet that causes the issue:

AWSKinesisVideoClient client;

try {
    client = getAwsKinesisVideoClient();
} catch (Exception e) {
    return FAILED;
}

DescribeSignalingChannelResult describeResult = client.describeSignalingChannel(
        new DescribeSignalingChannelRequest().withChannelARN(channelName));
            
1
  • 1
    Sure, I am only trying to follow the convention recommended by AWS themselves. According to Amplify's official website: "Amplify Android is the recommended way to build native Android applications powered by AWS. You can also use the low-level AWS Mobile SDK for Android with Amplify Android if the use case you are trying to build is not currently available in Amplify Android.". So I am using Amplify for authentication, and the low level AWS library for video streaming using Kinesis. Commented Oct 24, 2021 at 14:03

2 Answers 2

1

To write Android apps that invoke AWS Services, consider using the new AWS SDK for Kotlin. This is still in Alpha, but lets you write Native Android Apps that can easily invoke AWS Services.

Get started with the SDK for Kotlin

Update

Using the new Kotlin SDK, i was able to code a little Native Android app and successfully use the KinesisVideoClient.

Here is the App showing an ARN value of a Video Stream using a Toast.

enter image description here

Code for this is:

package com.example.androidkinvideo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.kinesisvideo.KinesisVideoClient
import aws.sdk.kotlin.services.kinesisvideo.model.DescribeStreamRequest
import kotlinx.coroutines.runBlocking

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun showARN(view: View) = runBlocking{

        val staticCredentials = StaticCredentialsProvider {
            accessKeyId = "AKIA33JWYxxxxxxxxxxxxxxx"
            secretAccessKey = "/zyyrAnarbnxxxxxxxxxxxxxxxx"
        }

        val vidClient = KinesisVideoClient{
            region = "us-east-1"
            credentialsProvider = staticCredentials
        }

        val request = DescribeStreamRequest {
            streamName = "ExampleStream"
        }

        val streamResponse = vidClient.describeStream(request)
        val arnVal = streamResponse.streamInfo?.streamArn
        if (arnVal != null) {
            showToast(arnVal)
        }
    }

    fun showToast(value:String){
        val toast = Toast.makeText(applicationContext, value, Toast.LENGTH_SHORT)
        toast.setMargin(50f, 50f)
        toast.show()
    }
}

Gradle Build:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {

    compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
        coreLibraryDesugaringEnabled true
    }

    lintOptions {
        abortOnError false
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }

    compileSdkVersion 30
    buildToolsVersion "30.0.0"

    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/ASL2.0'
        exclude("META-INF/*.kotlin_module")
    }

    defaultConfig {
        applicationId "com.example.aws"
        minSdkVersion 26
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    api("aws.sdk.kotlin:kinesisvideo:0.6.0-alpha")
    api("aws.sdk.kotlin:dynamodb:0.6.0-alpha")
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.6.0'
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
Sign up to request clarification or add additional context in comments.

10 Comments

I don't think that would make any difference. The library that causes the issue is com.amazonaws:aws-android-sdk-mobile-client and it would cause the same issue regardless of the language that uses it (under the hood Kotlin and Java use the same JVM).
Can you post your Kinesis Code. This can be tested to see if this issue exists in new Kotlin API.
Done. I added an Edit section to the question.
I will work with the Kotlin SDK team on this. I will test it too.
See update - using the new AWS SDK for Kotlin - it worked
|
0

In my case it was a compatibility issue I was using

    implementation 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.16.2'

and S3 version

implementation 'com.amazonaws:aws-android-sdk-s3:2.73.0'

I changed the cognitoidentityprovider to 2.73.0 same as s3 service. It fixes the issue.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.