How to integrate your plugin into Dimple app

What is Dimple plugin

Dimple plugin is activity (both for setup and execution) with io.dimple.action.PLUGIN as action in Intent filter (for just press) or activity (for setup) and broadcast receiver (for execution) with io.dimple.action.PLUGIN_LONGPRESS as action (for long press). Dimple will list all activities with those actions in "Third party plugins" list. One application can contain multiple plugins.

All communication with Dimple app happens thorugh standart Android appliaction lifecycle and methods.

Types of Dimple plugins

Simple plugin

Simple plugin is activity that can be started by pressing Dimple. Activity is started with Intent containing data that was set up during set-up phase of plugin. For this plugin setup activity and plugin executor activity is the same.

Long-press plugin

Long-press plugin is broadcast listener that can receive three type of events - on Dimple button down, on Dimple hold (interval can be set up during setup) and on Dimple button up. Setup happens through activity that is provided in AndroidManifest.xml file.

Long-press plugins are not compatible with "popup window" feature and using one will disable this feature in UI.

How to interact with Dimple

Preparing activity to be listed as Dimple plugin

In AndroidManifest.xml file each activity that will be used as plugin need to have intent filter defined like this:

<activity android:name="PluginActivity">
      <intent-filter>
          <action android:name="io.dimple.action.PLUGIN"/>
          <category android:name="android.intent.category.DEFAULT"/>
      </intent-filter>
</activity>

(Replace "io.dimple.action.PLUGIN" with "io.dimple.action.PLUGIN_LONGPRESS" for long press plugins).

Activity should be able to return result so that activity shouldn't have limitations on how it can be used (f.e. activity can't have launchMode="singleInstance").

Plugin start

When user chooses plugin from plugin list in Dimple app, plugin activity is started with extras. String extra "type" contains value "create" if plugin is started from plugin chooser in Dimple app or "execute"(only if simple plugin) if plugin is started from Dimple press.

Setting up action

When plugin is started from Dimple app chooser, Dimple app is waiting for plugin data passed back as activity result. Integer extra "memory" contains maximum array size that can be sent back and still fit Dimple (can vary from launch to launch). To send data back to Dimple app, create Intent with byte[] extra "data" that contains byte array with plugin data and set it as result intent with Activity.RESULT_OK result code afterwards finishing your activity.

Executing plugin

Simple plugin

When plugin is started from Dimple press, plugin is started in new task and data previously set is passed as byte array extra "data".

Long-press plugins

Dimple press will send broadcast events to application. To get events you need to set up broadcast listener like this

    <receiver android:name=".PluginLongPressBroadcastReceiver">
        <intent-filter>
            <action android:name="io.dimple.action.PLUGIN_LONGPRESS"/>
        </intent-filter>
    </receiver>

We suggest to have one receiver per app and identify functionality by using data array.

Show me the code (sample)

This is plugin that saves String into Dimple and shows it when executed.

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    final Bundle extras = getIntent().getExtras();
    if (extras != null && extras.containsKey("type"))
    {
        //Dimple app plugin chooser
        if ("create".equals(extras.getString("type")))
        {
            int bytesLeft = extras.getInt("memory");
            create(bytesLeft);
        }
        //Dimple press
        else if ("execute".equals(extras.getString("type")))
        {
            execute(extras.getByteArray("data"));
        }
        else
        {
            finish();
        }

    }
    else
    {
        finish();
    }
}

public void create(int bytesLeft)
{
    //Preparing data
    String dataString = "Hello world, " + System.currentTimeMillis();
    //Converting data to byte array
    byte[] data = dataString.getBytes(Charset.forName("UTF-8"));

    //Checking if Dimple have enough space
    if (bytesLeft < data.length)
    {
        Toast.makeText(this, "Not enough space",Toast.LENGTH_SHORT).show();
        setResult(RESULT_CANCELED);
        finish();
        return;
    }

    //Sending data back to Dimple
    Intent result = new Intent();
    result.putExtra("data", data);
    setResult(RESULT_OK, result);
    finish();
}

public void execute(byte[] data)
{
    //Setting layout (containing TextView with ID text_output
    setContentView(R.layout.main);

    //Getting back String from data
    String message = new String(data, Charset.forName("UTF-8"));
    //Displaying result to user
    ((TextView) findViewById(R.id.text_output)).setText(message);
}

Plugin styling

Dimple use icon and label information from activitiy record in AndroidManifest.xml. If some of information is missing Dimple falls back to application record. To use distinct icon and label for plugin, set those like in this sample:

    <activity android:name="PluginActivity"
              android:label="@string/plugin_name"
              android:icon="@drawable/ic_plugin">

Tips

  • If you don't need to save data for plugin, send back new byte[0] as data.
  • You don't need to send result back immediatly, you can ask user for input, run other activities and do other things Android task lifecycle permits before returning result. [Documentation](http://developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent, int)) on method used by Dimple.
  • To optimize for space, choose short activity class names (and package names if possible) and place activity in root of package when creating plugins. Package name and path to activity are saved into Dimple to execute plugin.

Tags: plugins