[User Guide] How to write a plugin step by step

Post Reply
MCADevelopment
Posts: 28
Joined: Tue Sep 18, 2018 6:23 am

[User Guide] How to write a plugin step by step

Post by MCADevelopment » Fri Oct 26, 2018 7:24 am

This guide contains how to write your own plugin for MCA Pro.

Setup the plugin project

1. Install Android Studio
https://developer.android.com/studio/

2. Open Android Studio and New a project
Image
  • Company domain must be "mcaplugin.com", otherwise the plugin can't be found by MCA Pro.
  • Set any name you like to "Application name".
  • If you want to use JNI, select "Including C++ support"
  • Click next.
Image
  • Select API 21
Image
  • Select "Add No Activity"
3. Put PluginIF.jar to "The project's folder\app\libs" and add it into the project.
Image
  • Change to "Project"
Image
  • Find Plugin.jar, click right button of the mouse, and press "Add as Library"
Image
  • Press "Ok"
4. New the java class
Image
  • Change back to "Android"
  • New the class by right-clicking app/java/com.mcaplugin.[your Application] and press "New" -> Java Class
Image
  • The name of the class must be [your Application name] in lower case. Otherwise the plugin can't be found by MCA Pro.
  • Set Superclass to "com.mcapro.pluginif.MCA_Plugin"
  • Set Interface(s) to the plugin type you want to implement. One plugin can only one type.
    • com.mcapro.pluginif.EncodeInputIF
    • com.mcapro.pluginif.EncodeOutputIF
    • com.mcapro.pluginif.DecodeInputAudioIF
    • com.mcapro.pluginif.DecodeInputSampleIF
    • com.mcapro.pluginif.DecodeOutputIF
5. Implement MCA_Plugin methods and the interface of the plugin type:
  • public abstract class MCA_Plugin {
    public static final int LIBERARY_VERSION = 20181013;

    public abstract int getType();
    public static final int TYPE_ENCODE_INPUT = 1; //Must implements EncodeInputIF
    public static final int TYPE_ENCODE_OUTPUT = 2; //Must implements EncodeOutputIF
    public static final int TYPE_DECODE_INPUT_AUDIO = 11; //Must implements DecodeInputAudioIF
    public static final int TYPE_DECODE_INPUT_SAMPLE = 12; //Must implements DecodeInputSampleIF
    public static final int TYPE_DECODE_OUTPUT = 13; //Must implements DecodeOutputIF

    //Common
    public abstract String getName(Object resource);
    public abstract String getDescription(Object resource);
    public abstract int getVersion();
    public abstract int getMinSDK();

    //State control
    public abstract boolean init();
    public abstract boolean start();
    public abstract boolean stop();
    public abstract boolean release();
    //Return false if the action is succeed.
    //Return true if something is wrong.
    //But MCA Pro doesn't handle these return states currently.

    public abstract Object getView(Object context, Object resource);

    //Control flow:
    //Load in plugin: init() -> getView()
    //Unload plugin: stop() -> release()
    //After pressing "Encode" or "Decode" button: stop() -> start() -> getInputString() or getInput() or handleOutput() -> Process by MCAPro -> handleOutput()
    //After pressing "Stop" button or whenever need it: stop()
    }

MCADevelopment
Posts: 28
Joined: Tue Sep 18, 2018 6:23 am

Re: [User Guide] How to write a plugin step by step

Post by MCADevelopment » Fri Oct 26, 2018 7:36 am

Fill informant of the plugin.

Image
  • getType() must match the implements interface
  • getName() - The name of this plugin. This is show on UI in plugin option list.
    • The string in strings.xml can be got by converting "Object resource" to "(Resources) resource" and getString() from it.
  • getDescription() - Description about this plugin. Not use in UI currently.
  • getVersion() - The version of this plugin. Start from 1.
  • getMinSDK() - The minimum Android SDK this plugin need. Start from 21 (Android 5.0).

MCADevelopment
Posts: 28
Joined: Tue Sep 18, 2018 6:23 am

Re: [User Guide] How to write a plugin step by step

Post by MCADevelopment » Fri Oct 26, 2018 7:43 am

Handle the state of plugin

Image
The control flow is:
  • Load in plugin: init() -> getView()
  • Unload plugin: stop() -> release()
  • After pressing "Encode" or "Decode" button: stop() -> start() -> getInputString() or getInput() or handleOutput() -> Process by MCAPro -> handleOutput()
  • After pressing "Stop" button or whenever need it: stop()

MCADevelopment
Posts: 28
Joined: Tue Sep 18, 2018 6:23 am

Re: [User Guide] How to write a plugin step by step

Post by MCADevelopment » Fri Oct 26, 2018 8:21 am

Setup the Control UI

1. New the layout xml for UI
Image
Image
  • Set "Layout File Name"
  • Set "Root Tag"
  • Press "Finish"
2. Implement getView()
Image
getView() is called by MCA Pro during run-up the plugin.
Unlike normal App, there are many rules:
  • All resource assignments are useless in layout file.
    • Instead, the resources, including string, image, drawable, event functions, must be set in Java code.
  • All resources must be got from "Resources resources = (Resources) resource;"
  • The Context must be got from "Context myContext = (Context) context;"
  • The XML Attribute: android:background="@drawable/xxx" must not be in layout file.

MCADevelopment
Posts: 28
Joined: Tue Sep 18, 2018 6:23 am

Re: [User Guide] How to write a plugin step by step

Post by MCADevelopment » Fri Oct 26, 2018 8:22 am

Implement the type's interface

Image
  • com.mcapro.pluginif.EncodeInputIF
    • public interface EncodeInputIF {
      public String getInputString();
      public boolean hasMoreInput();
      }
  • com.mcapro.pluginif.EncodeOutputIF
    • public interface EncodeOutputIF {
      public void handleOutput(String morseCode, boolean append);
      }
  • com.mcapro.pluginif.DecodeInputAudioIF
    • public interface DecodeInputAudioIF {
      public int getChannelNum(); //Support: 1 = Mono, 2 = Stereo
      public int getSampleRate(); //48000, 44100, etc.
      public int getInput(short[] shortArray, int arraySize);
      //Put input data to shortArray.
      //Return the number of input data.
      //Return 0 if no data is available currently. MCA Pro will sleep 10 millisecond before next calling.
      //If the number of input data < arraySize, the remaining positions of shortArray are filled of 0 before processing it.

      public boolean hasMoreInput();
      //Set true if there is data to be input no matter the data is available or not currently.
      //Set false if no more data to be handled.
      }
  • com.mcapro.pluginif.DecodeInputSampleIF
    • public interface DecodeInputSampleIF {
      public int getBytesPerSample(); //Support: 1 = byte, 2 = short, 8 = long
      public int getSampleIntervalInMilli(); //Ex: 30 FPS = about 33 millisecond per sample

      public int getInput(byte[] byteArray, int arraySize);
      public int getInput(short[] shortArray, int arraySize);
      public int getInput(long[] longArray, int arraySize);
      //Put input data to the Array.
      //Return the number of input samples.
      //Return 0 if no data is available currently. MCA Pro will sleep 10 millisecond before next calling.


      public boolean hasMoreInput();
      //Set true if there is data to be input no matter the data is available or not currently.
      //Set false if no more data to be handled.
      }
  • com.mcapro.pluginif.DecodeOutputIF
    • public interface DecodeOutputIF {
      public void handleOutput(String plainText, boolean append);
      }

MCADevelopment
Posts: 28
Joined: Tue Sep 18, 2018 6:23 am

Re: [User Guide] How to write a plugin step by step

Post by MCADevelopment » Fri Oct 26, 2018 8:35 am

Build and install the plugin

1. Modify styles.xml
Image
to
Image
  • <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
    </style>
2. Modify Build.gradle (Module: app) and "Sync" the project
Image
to
Image
  • dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    compileOnly files('libs/PluginIF.jar')
    }
3. Build plugin
Image

4. Find plugin file
Image

5. Change filename
Change the file name from app-debug.apk to [your application name in lower case].apk
  • In this case, pluginexample.apk
6. Install plugin
com.mcapro.pluginif.EncodeInputIF
  • Put apk to \Music\MorseCodeAgent\Plugin\EncodeInput
com.mcapro.pluginif.EncodeOutputIF
  • Put apk to \Music\MorseCodeAgent\Plugin\EncodeOutput
com.mcapro.pluginif.DecodeInputAudioIF & com.mcapro.pluginif.DecodeInputSampleIF
  • Put apk to \Music\MorseCodeAgent\Plugin\DecodeInput
com.mcapro.pluginif.DecodeOutputIF
  • Put apk to \Music\MorseCodeAgent\Plugin\DecodeOutput
*MCA Pro may need to be removed from the list showed by pressing recent button whenever any plugin is updated.
Otherwise, plugin may not be updated due to the Android cache.

.

cheshy
Posts: 8
Joined: Wed Dec 26, 2018 7:14 pm
Location: authekJek
Contact:

User Guide How to write a plugin step by step

Post by cheshy » Sun Jan 06, 2019 9:01 pm

Encode-Input plugin example - TextInputWithSimpleEncrypt

This plugin encrypts text before convert it to Morse code.
This plugin must works with the plugin: DecodeSimpleEncryption

TextInputWithSimpleEncrypt.apk must be put into MusicMorseCodeAgentPluginEncodeInput
TextInputWithSimpleEncrypt.7z is the source code.

.

Post Reply