0

What I am trying to achieve:

I have created Android Plugin Project (cclib-release.aar) which has a targeted Activity.

I want to invoke this Activity in ionic2 using Cordova Plugin which has cclib-release.aar added as dependency inside Cordova Plugin. aar file added in cordova plugin as per this link

Problem facing:

While invoking Activity, I am getting the following error

java.lang.NoClassDefFoundError: Failed resolution of: Lcompute/cclib/MainActivity;
Caused by: java.lang.ClassNotFoundException: Didn't find class "compute.cclib.MainActivity" on path: DexPathList[[zip file "/data/app/com.ionicframework.fragmentwithionic759798-2/base.apk"],nativeLibraryDirectories=[/data/app/com.ionicframework.fragmentwithionic759798-2/lib/arm, /vendor/lib, /system/lib]]

The issue is similar to SO Link in which the issue was resolved. But even after following similar step's I am getting the above mentioned error!

My Plugin Structure: (cclib-release.aar is my targeted library with Activity)

enter image description here

My Inject.java goes like this

    public class Inject extends CordovaPlugin {

    @Override
        public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {

       if (action.equals("coolMethod")) {
                String message = args.getString(0);
                this.coolMethod(message, callbackContext);
                return true;
            }
           return false;
      }

    private void coolMethod(String message, CallbackContext callbackContext) {

         if (message != null && message.length() > 0) {
                cordova.getActivity().runOnUiThread(new Runnable() {
                public void run() {
                    Intent intent = new Intent(cordova.getActivity().getApplicationContext(), 
                    compute.cclib.MainActivity.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    cordova.getActivity().startActivity(intent);
                }
                });
                callbackContext.success(message);
            } else {
                callbackContext.error("Expected one non-empty string argument.");
            }
      }
    }

Added this plugin in ionic2 using

cordova plugin add PATH_TO_PLUGIN

As per above mentioned answer by SO, I have modified Ionic2 project's AndroidManifest.xml manually .Path =FragmentWithIonic\platforms\android to refer the Activity.

<activity android:label="@string/activity_name"  
android:launchMode="singleTop" android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
android:name="compute.cclib.MainActivity">
</activity>

I am invoking this in Ionic2 using below which works fine in other cases.

this.platform.ready().then(() => {
            window.plugins.Inject.coolMethod(message, "short", position);
        });

I tried to manually import compute.cclib.MainActivity in Inject.java. But invoking Activity is still giving run time error!

Below is the modified FragmentWithIonic\platforms\android\AndroidManifest.xml

<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" 
        android:versionCode="1" 
        android:versionName="0.0.1" 
        package="com.ionicframework.fragmentwithionic759798" 
        xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" 
    android:largeScreens="true" 
    android:normalScreens="true" 
    android:resizeable="true" 
    android:smallScreens="true" 
    android:xlargeScreens="true" />
    <application android:hardwareAccelerated="true" 
        android:icon="@mipmap/icon" 
        android:label="@string/app_name" 
        android:supportsRtl="true">
        <activity 
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" 
            android:label="@string/activity_name" 
            android:launchMode="singleTop" 
            android:name="MainActivity" 
            android:theme="@android:style/Theme.DeviceDefault.NoActionBar" 
            android:windowSoftInputMode="adjustResize">
            <intent-filter android:label="@string/launcher_name">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:label="@string/activity_name"
        android:launchMode="singleTop"
        android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
        android:name="compute.cclib.MainActivity">
        </activity>
    </application>
    <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="24" />
</manifest>

What modifications I need to do to invoke Activity in my plugin?


EDIT 1

After @gmmo suggested, I included reference libraries in my Plugin's gradle File (Inject.gradle)

   repositories{
   jcenter()
   maven { url "https://jitpack.io" }
   flatDir{
    dirs 'aar'
   }
   }
  dependencies {
    compile 'com.android.support:appcompat-v7:25.1.0'
    compile(name:'cclib-release', ext:'aar')
   }

 android {
    packagingOptions {
      exclude 'META-INF/NOTICE'
      exclude 'META-INF/LICENSE'
    }
 }

Now I am getting the following error while building my ionic2 project.

A problem occurred configuring root project 'android'.
> You have not accepted the license agreements of the following SDK components:
[Android Support Repository].
Before building your project, you need to accept the license agreements and complete the installation of the missing components using the Android Studio SDK Manager.
Alternatively, to learn how to transfer the license agreements from one workstation to another, go to http://d.android.com/r/studio-ui/export-licenses.html

enter image description here

I have already updated with all license agreements in SDK. I am pretty sure this is due to this lines in Inject.gradle

compile 'com.android.support:appcompat-v7:25.1.0'

Plugin might not able to find the corresponding dependencies

Community
  • 1
  • 1
Sreehari
  • 5,621
  • 2
  • 25
  • 59

2 Answers2

1

You can definitely invoke full activities inside the aar file. My aar file contained several activities. I have not seen the issue you mentioned, but I have seen path issues when the aar gradle file had problems. You may want to revise your gradle file. This is the one my plugin uses:

repositories{
  jcenter()
  maven { url "https://jitpack.io" }
  flatDir{
      dirs 'libs'
   }
}
dependencies {
    compile 'com.android.support:support-v13:23.1.0'
    compile 'com.android.support:support-v4:23.1.0'
    compile 'com.android.support:gridlayout-v7:23.1.1'
    compile 'com.android.support:appcompat-v7:23.1.0'
    compile 'com.android.support:design:23.1.0'
    compile 'com.android.volley:volley:1.0.0'
    compile 'com.google.code.gson:gson:2.4'
    compile 'com.google.android.gms:play-services-base:8.1.0'
    compile 'com.google.android.gms:play-services-location:8.1.0'
    compile 'com.google.android.gms:play-services-maps:8.1.0'
    compile 'com.google.android.gms:play-services-gcm:8.1.0'
    compile 'com.github.bumptech.glide:glide:3.7.0'
    compile 'com.android.support:recyclerview-v7:23.1.0'
    compile 'com.android.support:cardview-v7:23.1.0'
    compile 'org.altbeacon:android-beacon-library:2.+'
    compile 'com.cloudinary:cloudinary-android:1.2.2'

    compile(name:'mysdk', ext:'aar')
}

android {
  packagingOptions {
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/LICENSE'
  }
}

and this is how I invoke activities from the cordova plugin:

@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
    super.initialize(cordova, webView);
    Logger.v(Constants.Engine.LOGGER_TAG_APP, "Plugin Initialized...");
    Context context = cordova.getActivity();

    // This works for me
    Intent intent = new Intent(context, PermissionsActivity.class);
    context.startActivity(intent);
}

and snipped of my plugin .xml

<!-- Initialization -->
<platform name="android">
    <config-file target="config.xml" parent="/*">
        <feature name="PlatformSDK">
            <param name="android-package" value="com.mycompany.PlatformSdk.cordova.PlatformSDKCordovaPlugin" />
            <param name="onload" value="true" />
        </feature>
    </config-file>
    <framework src="libs/mysdk.gradle" custom="true" type="gradleReference" />
    <resource-file src="libs/mysdk.aar" target="libs/mysdk.aar" />
    <source-file src="PlatformSDKCordovaPlugin.java" target-dir="src/com/mycompany/PlatformSDK/cordova" />
</platform>
gmmo
  • 2,577
  • 3
  • 30
  • 56
  • However, I must add that my plugin is purely Java. Maybe there are issues with native c++ code. I would try a simple aar file only with java first to see if it works. – gmmo Dec 20 '16 at 19:22
  • My plugin is also purely java. I do not have any native C++ implementation. But the aar file is having Android plugin project. – Sreehari Dec 21 '16 at 06:23
  • Could you put up these whole structure (Cordova plugin/ Aar file / Android project ) in github? So that I can compare and do modifications accordingly? – Sreehari Dec 21 '16 at 06:26
  • I have edited my question with EDIT 1. Can you pls check – Sreehari Dec 21 '16 at 11:10
0

Okey finally I figure out the issue.

Ionic2 project need to update SDK tools by the following command

android update sdk --no-ui --filter extra

Got this input from cordova-plugin-issues

One more command was mentioned which I am not sure about which was the below one. If someone come across similar issue can try this out as well

android update sdk --no-ui --all --filter

A big Thanks to @gmmo , as he gave me the input to add all dependencies also along with plugin's Inject.gradle .

As I was in an impression that why would this be required after all these dependencies was already covered in Android Plugin Project.

Sreehari
  • 5,621
  • 2
  • 25
  • 59