0
votes

I have an ionic 3 application that i need to add an android sdk to. there is no plugin for it so I have to create a cordova plugin for it. I tried for a few days now, and i can get the plugin to install and build, error free, but calling the plugin methods don't seem to do anything. I can get the js file of the plugin to output console.logs but the java file doesn't seem to running at all. this is my ionic info for my project. I have zero experience with java code or cordova plugin development so i've hit a major roadblock as i cannot figure out why the java code is not being called. can anyone see what i am doing wrong? Ionic:

ionic (Ionic CLI) : 4.4.0 (/usr/local/lib/node_modules/ionic) Ionic Framework : ionic-angular 3.9.2 @ionic/app-scripts : 3.2.0

Cordova:

cordova (Cordova CLI) : 8.1.2 ([email protected]) Cordova Platforms : android 7.1.4, ios 4.5.5 Cordova Plugins : cordova-plugin-ionic-webview 1.2.1, (and 31 other plugins)

System:

ios-deploy : 1.9.4 NodeJS : v10.7.0 (/usr/local/bin/node) npm : 6.4.1 OS : macOS High Sierra Xcode : Xcode 10.1 Build version 10B61

This is my Plugin.xml

<?xml version='1.0' encoding='utf-8'?>
<plugin id="cordova-plugin-chirp"
  version="0.1.0"
  xmlns="http://apache.org/cordova/ns/plugins/1.0"
  xmlns:android="http://schemas.android.com/apk/res/android">
  <name>chirp</name>
  <js-module name="chirp" src="www/chirp.js">
    <clobbers target="cordova.plugins.chirp" />
  </js-module>
  <platform name="ios">
    <config-file parent="/*" target="config.xml">
      <feature name="chirp">
        <param name="ios-package" value="chirp" />
      </feature>
    </config-file>
    <header-file src="src/ios/chirp.h" />
    <source-file src="src/ios/chirp.m" />
  </platform>
  <platform name="android">
    <source-file src="src/android/chirp.java" target-dir="src/org/apache/cordova/plugin/chirp" />
    <source-file framework="true" src="src/android/libs/chirp-connect-release.aar" target-dir="libs"/>
    <!-- <framework src="src/android/chirp.gradle" custom="true" type="gradleReference" /> -->
    <config-file parent="/*" target="res/xml/config.xml">
      <feature name="chirp">
        <param name="android-package" value="org.apache.cordova.plugin.chirp" />
      </feature>
    </config-file>
    <config-file parent="/*" target="AndroidManifest.xml">
      <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
      <uses-permission android:name="android.permission.RECORD_AUDIO" />
      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    </config-file>
  </platform>
</plugin>

This is my js file. chirp.js:

var exec = require('cordova/exec');

var chirp ={
  getPermissions:function(message){
    console.log(message);
    exec(null, null, 'Chirp', 'getPermissions', [message]);
  },
  start:function(message){
    console.log(message);
    exec(null, null, 'Chirp', 'start', [message]);
  },
  send:function(message){
    console.log(message);
    exec(null, null, 'Chirp', 'send', [message]);
  }
};

module.exports = chirp

This is my gradle file. chirp.gradle:

repositories {
  jcenter()
  flatDir {
    dirs 'libs'
  }
}

dependencies {
   compile(name:'chirp-connect-release', ext:'aar')
}

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

and this is my java file. chirp.java:

package com.chirp.cordova.plugin;

import android.content.Context;
import android.content.pm.PackageManager;
import android.Manifest;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.LOG;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.PluginResult;
import org.apache.cordova.PermissionHelper;


import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import io.chirp.connect.ChirpConnect;
import io.chirp.connect.interfaces.ConnectEventListener;
import io.chirp.connect.interfaces.ConnectSetConfigListener;
import io.chirp.connect.models.ChirpError;
import io.chirp.connect.models.ConnectState;

/**
 * This class echoes a string called from JavaScript.
 */
public class chirp extends CordovaPlugin {

    private ChirpConnect chirpConnect;
    private Context context;
    CallbackContext callbackC;
    String TAG = "ChirpPlugin";

    String [] permissions = {Manifest.permission.MODIFY_AUDIO_SETTINGS, Manifest.permission.RECORD_AUDIO, Manifest.permission.INTERNET, Manifest.permission.ACCESS_NETWORK_STATE};

    public static final int SEARCH_REQ_CODE = 0;
    public static final int SAVE_REQ_CODE = 1;
    public static final int REMOVE_REQ_CODE = 2;
    public static final int PICK_REQ_CODE = 3;

    public String executeArgs = "";

    String KEY = "myKey";
    String SECRET = "mySecret";
    String CONFIG = "myConfig";

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
      callbackC = callbackContext;
        LOG.d(TAG, "We are entering execute");
        if (action.equals("start")){
          if(hasPermission()){
            String message = args.getString(0);
            executeArgs = message;
            // start(message);
            callbackContext.success();
            return true;
          } else {
            PermissionHelper.requestPermissions(this, 0, permissions);
          }
        } else if (action.equals("send")){
          String message = args.getString(0);
          this.send(message);
          callbackContext.success();
          return true;
        }
        return false;
    };

    public chirp(Context context) {
        this.context = context;
    };

    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
      super.initialize(cordova, webView);
        ChirpConnect chirpConnect = new ChirpConnect(context, KEY, SECRET);
        chirpConnect.setConfigFromNetwork(new ConnectSetConfigListener(){
          @Override
          public void onSuccess(){
            chirpConnect.setListener(connectEventListener);
            LOG.i("setConfig", "Config successfully set");
          }
          @Override
          public void onError(ChirpError setConfigError){
            LOG.e("setConfigError", setConfigError.getMessage());
          }
        });
    };

    ConnectEventListener connectEventListener = new ConnectEventListener() {

        @Override
        public void onSending(byte[] payload, byte channel) {
          LOG.v("chirpConnectDemoApp", "This is called when a payload is being sent " + payload + " on channel: " + channel);
        }

        @Override
        public void onSent(byte[] payload, byte channel) {
          LOG.v("chirpConnectDemoApp", "This is called when a payload has been sent " + payload  + " on channel: " + channel);
        }

        @Override
        public void onReceiving(byte channel) {
          LOG.v("chirpConnectDemoApp", "This is called when the SDK is expecting a payload to be received on channel: " + channel);
        }

        @Override
        public void onReceived(byte[] payload, byte channel) {
          LOG.v("chirpConnectDemoApp", "This is called when a payload has been received " + payload  + " on channel: " + channel);
        }

        @Override
        public void onStateChanged(byte oldState, byte newState) {
          LOG.v("chirpConnectDemoApp", "This is called when the SDK state has changed " + oldState + " -> " + newState);
        }

        @Override
        public void onSystemVolumeChanged(int old, int current) {
          LOG.d("chirpConnectDemoApp", "This is called when the Android system volume has changed " + old + " -> " + current);
        }
    };

    private void start(String message) {
        if (message != null && message.length() > 0) {
            chirpConnect.start();

        }
    };


    private void send(String message) {
        if (message != null && message.length() > 0) {
            long maxLength = chirpConnect.getMaxPayloadLength();
            byte[] payload = chirpConnect.randomPayload(maxLength);
            chirpConnect.send(payload);
        }
    };

    public boolean hasPermission() {
        for(String p : permissions)
        {
            if(!PermissionHelper.hasPermission(this, p))
            {
                return false;
            }
        }
        return true;
    }

    public void requestPermissions(int requestCode)
    {
        PermissionHelper.requestPermissions(this, requestCode, permissions);
    }
}
1

1 Answers

0
votes

One thing I've spotted is that the target filepath for your plugin Java file is wrong:

<source-file src="src/android/chirp.java" target-dir="src/org/apache/cordova/plugin/chirp" />

The package name of your chirp class is com.chirp.cordova.plugin so the target-dir should be src/org/apache/cordova/plugin not src/org/apache/cordova/plugin/chirp, i.e.:

<source-file src="src/android/chirp.java" target-dir="src/org/apache/cordova/plugin" />

Note that the value required for <param name="android-package"> is actually the fully-qualified class name (not the package name) so the name android-package is somewhat misleading. Therefore what you currently have is correct:

<param name="android-package" value="org.apache.cordova.plugin.chirp" />

If you are developing a Cordova plugin, I would recommend you debug the Android and iOS implementations using Android Studio and Xcode respectively.

If you had run your plugin in a test harness app in Android Studio, you would have seen a warning in the logcat output which indicates that Cordova cannot find the native implementation of the specified plugin. Also you can then debug any issues in the native plugin Java code using the step-through debugger in Android Studio.