Search code examples
javaandroidc++android-ndkandroid-productflavors

NDK support with different Product Flavour


I want different string value from ndk library. as i have two flavor demo and live I want value "hello I am from demo " for demo flavor and for live flavor i want "hello I am from live "

Here is my java file code

public class MainActivity extends AppCompatActivity {
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Example of a call to a native method
    TextView tv = (TextView) findViewById(R.id.sample_text);
    tv.setText(stringFromJNI());
}

/**
 * A native method that is implemented by the 'native-lib' native library,
 * which is packaged with this application.
 */
public native String stringFromJNI();

}

Here is my cpp file code

#include <jni.h>
#include <string>

extern "C"
JNIEXPORT jstring JNICALL
Java_com_de_demo_ndk2_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "hello I am from  demo";
    return env->NewStringUTF(hello.c_str());
}

this is my build.gradle file

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.de.demo.ndk2"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        flavorDimensions "default"
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {

        demo
                {
                    // applicationId "com.readwhere.whitelabel.test"
                    //applicationId "com.android.rwstaging"
                    applicationId "com.android.demo"
                    versionName "2.1"
                    dimension "default"

                    externalNativeBuild {
                        cmake {

                            targets "native-lib-demo","my-executible-                   demo"

                        }}


                }
        live
                {
                    // applicationId "com.readwhere.whitelabel.test"
                    //applicationId "com.android.rwstaging"
                    applicationId "com.android.live"
                    versionName "2.1"
                    dimension "default"



                }}
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

I have paste same cpp file in demo folder as well as in main folder but could achieve my task. Any help would be appreciate this are some refrence links

https://developer.android.com/studio/projects/gradle-external-native-builds.html

How to set CmakeLists path in product flavor for each Android ABI?


Solution

  • Finally I a solution. Here is my cpp file code

    Java_com_de_demo_ndk2_MainActivity_stringFromJNI(
            JNIEnv *env,
            jobject jobject1, jstring jstring1) {
    
        std::string hello;
        const char *nativeString1 = env->GetStringUTFChars( jstring1, 0);
        if (strcmp(nativeString1, "demo") == 0) {
            hello = "Hello from demo C++";
        } else if (strcmp(nativeString1, "live") == 0) {
            hello = "Hello from live C++";
        }
    
        return env->NewStringUTF(hello.c_str());
    }
    

    I am passing flavor value from java code here is my code for java file.

    public class MainActivity extends AppCompatActivity {
    
        // Used to load the 'native-lib' library on application startup.
        static {
            System.loadLibrary("native-lib");
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // Example of a call to a native method
            TextView tv = (TextView) findViewById(R.id.sample_text);
            String value = BuildConfig.FLAVOR;
            String ndkValue = stringFromJNI(value);
            tv.setText(ndkValue);
        }
    
        /**
         * A native method that is implemented by the 'native-lib' native library,
         * which is packaged with this application.
         * @param value
         */
        public native String stringFromJNI(String value);
    }
    

    Now i can get whatever text i want according to selected flavor.