Add java class to android src folder


#1

Hello,

In order to use the google cast api, a CastOptionsProvider java class has to be present and configured in the AndroidManifest like so.

// app/App_Resources/Android/AndroidManifest.xml

<meta-data android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
	   android:value="com.tns.CastOptionsProvider" />

// platforms/android/src/main/java/com/tns/CastOptionsProvider.java

package com.tns;

import com.google.android.gms.cast.framework.CastOptions;
import com.google.android.gms.cast.framework.OptionsProvider;
import android.content.Context;
import com.google.android.gms.cast.framework.SessionProvider;
import java.util.List;

public class CastOptionsProvider implements OptionsProvider {
    public CastOptions getCastOptions(Context appContext) {
        return new CastOptions.Builder().setReceiverApplicationId("MY_APP_ID").build();
    }

    public List<SessionProvider> getAdditionalSessionProviders(Context context) {
        return null;
    }
}

If I manually drop the CastOptionsProvider.java file in the platforms/android/src/main/java/com/tns folder, everything works a treat. But this means I would have to do this each time I do a clean rebuild.

I suppose I could create a build step that does this for me but I’m wondering if there is a supported way to include native files in the build.

I have tried converting the file into a typescript file in the project root and decorating it with the @JavaProxy(‘com.tns.CastOptionsProvider’) annotation, but no dice.

Thanks!


#2

What’s the ‘no dice’ here? What have you actually tried that failed?

And to answer your original question - there is no supported mechanism by which you could add an arbitrary java file to your android project. This has been requested before, but we have not had enough input on use cases, and expected public api. - https://github.com/NativeScript/android-runtime/issues/700 https://github.com/NativeScript/android-runtime/issues/561


#3

Hi Pete, thanks for the info.

After seeing https://docs.nativescript.org/runtimes/android/advanced-topics/extend-application-activity, I tried converting the file to a typescript file and placed it in the root of the app.

// cast-options-provider.android.ts

@JavaProxy('com.tns.CastOptionsProvider')
class CastOptionsProvider {

    public getCastOptions(appContext: any) {
        return new com.google.android.gms.cast.framework.CastOptions.Builder().setReceiverApplicationId("MY_APP_ID").build();
    }

    public getAdditionalSessionProviders(context: any) {
        return null;
    }

}

I get the following error.

java.lang.ClassNotFoundException: Didn't find class "com.tns.CastOptionsProvider" on path: 
DexPathList[[zip file "/data/app/org.nativescript.nsng2app-1/base.apk"],nativeLibraryDirectories
=[/data/app/org.nativescript.nsng2app-1/lib/arm, /vendor/lib, /system/lib]]

#4

What you’ve done is create a simple TypeScript class, you however want to extend from a java.lang.Object, so as to have a Java class. The @JavaProxy decorator will have no effect if the typescript class does not extend a Java class. Additionally, in order to implement a Java interface in TypeScript, you should decorate the class with the @Interfaces decorator, and pass the interfaces you’ll be implementing as an array of constructor functions (read full Java class names). There is an article in the official docs portal where that’s explained - https://docs.nativescript.org/runtimes/android/generator/extend-class-interface#implementing-multiple-interfaces-in-nativescript

@JavaProxy('com.tns.CastOptionsProvider')
@Interfaces([com.google.android.gms.cast.framework.OptionsProvider])
class CastOptionsProvider extend java.lang.Object {
    constructor() {
        return global.__native(this)
    }
    public getCastOptions(appContext: any) {
        return new com.google.android.gms.cast.framework.CastOptions.Builder().setReceiverApplicationId("MY_APP_ID").build();
    }

    public getAdditionalSessionProviders(context: any) {
        return null;
    }
}

Let me know if this helped by liking the post, and/or marking the response as the solution to this thread.