[Java for Android App Development] nikwen:
[GUIDE] Adding this to your app

As indicated in the first post, the implementation is a little bit different than with Google's ShareActionProvider.

I assume that you are using Google's ActionBarCompat library.

Add the ActionBarCompat and the DynamicShareActionProvider library to your project first.

Afterwards, there are two ways of sharing your data using the DynamicShareActionProvider:

You can pass the data to the library when an app is selected and it will do the sharing part.

Or the library gives you an Intent which you just need to add the data to. This allows using an AsyncTask for data generation.

Adding the provider to the menu file

The first steps are the same for both ways. Add this to your menu resource file:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:library="http://schemas.android.com/apk/res-auto">

<item android:id="@+id/menu_item_share"
library:showAsAction="always"
android:title="Share"
android:icon="@drawable/abc_ic_menu_share_holo_dark"
library:actionProviderClass="de.nikwen.dynamicshareactionprovider.library.DynamicShareActionProvider" />

<!-- Your other entries here -->

</menu>

I saved the menu file as "res/menu/main.xml".

What's different from Google's Provider here, is that you need to set the icon for the menu entry. That shouldn't be a problem though because we can use the one from the ActionBarCompat library.

Then inflate the menu resource in the onCreateOptionsMenu() method of your Activity and get the provider from the menu:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);

DynamicShareActionProvider provider = (DynamicShareActionProvider) MenuItemCompat.getActionProvider(menu.findItem(R.id.menu_item_share));

return true;
}

Set the data type

To be able to filter your installed apps for those that can handle the data which should be shared, the provider needs to know which type of data you want to share. Set it like this:

provider.setShareDataType("text/plain");

(Add this to your onCreateOptionsMenu() method.)

Two different types of listeners

Now you need to choose the way you want to do the sharing:

Using the OnShareIntentUpdateListener - Let the library do the sharing for you

Set the listener using the setOnShareIntentUpdateListener() method:

provider.setOnShareIntentUpdateListener(new DynamicShareActionProvider.OnShareIntentUpdateListener() {

@Override
public Bundle onShareIntentExtrasUpdate() {
Bundle extras = new Bundle();

//Generate your data here and add it to the Bundle

return extras;
}

});

(Add this to your onCreateOptionsMenu() method as well.)

We override the onShareIntentExtrasUpdate() method here and pass a Bundle as the return value. The data you add to the bundle should have the same format that you would use, if you added it to the Intent directly using the Intent#putExtras(Bundle extras) method (that's what is used internally).

This is an example for passing the data from an EditText:

@Override
public Bundle onShareIntentExtrasUpdate() {
Bundle extras = new Bundle();
EditText shareEdit = (EditText) findViewById(R.id.share_edit);
extras.putString(android.content.Intent.EXTRA_TEXT, shareEdit.getText().toString());
return extras;
}

You're done. :)

Using the OnShareLaterListener - Do the sharing yourself

This time we override the onShareClick() method of the OnShareLaterListener:

provider.setOnShareLaterListener(new DynamicShareActionProvider.OnShareLaterListener() {

@Override
public void onShareClick(Intent shareIntent) {
MyShareAsyncTask task = new MyShareAsyncTask();
task.execute(shareIntent);
}

});

We get the share Intent as an argument and don't have to pass a return value. Instead, we have to do the sharing part manually.

The example code uses an AsyncTask for that:

private class MyShareAsyncTask extends AsyncTask<Intent, Void, Intent> {

@Override
protected void onPreExecute() {
Toast.makeText(MainActivity.this, R.string.asynctask, Toast.LENGTH_LONG).show();
}

@Override
protected Intent doInBackground(Intent... intents) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}

EditText shareEdit = (EditText) findViewById(R.id.share_edit);
intents[0].putExtra(android.content.Intent.EXTRA_TEXT, "Shared from an AsyncTask: " + shareEdit.getText().toString());

return intents[0];
}

@Override
protected void onPostExecute(Intent intent) {
startActivity(intent);
}

}

However, you're free to do it the way you like. ;)

You're done. :)