The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.


Tutorial #15 - Sharing Your Notes

Perhaps you would like to get your notes off of our book reader app and into someplace else, or perhaps you would like to share them with somebody else. Either way, we can do that using an ACTION_SEND operation, to allow the user to choose how to “send” the notes, such as sending them by email or uploading them to some third-party note service.

To make this work, we will add a ShareActionProvider to our action bar on the NoteFragment.

This is a continuation of the work we did in the previous tutorial.

You can find the results of the previous tutorial and the results of this tutorial in the book’s GitHub repository:

Step #1: Adding a ShareActionProvider

First, we need to allow the user to indicate that they want to “share” the note displayed in the current NoteFragment. By putting an action bar item on the activity where the NoteFragment is displayed, we do not need to worry about letting the user choose which note to send — we simply send whichever note they happen to be viewing or editing.

By using a ShareActionProvider, the action item will handle most of the work for allowing the user to choose where to send the note to. We only need to provide an Intent that identifies what is to be shared.

Modify res/menu/notes.xml to add in the new share toolbar button:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item
    android:id="@+id/share"
    android:actionProviderClass="android.widget.ShareActionProvider"
    android:showAsAction="ifRoom"
    android:title="@string/share"/>
  <item
    android:id="@+id/delete"
    android:icon="@drawable/ic_delete_white_24dp"
    android:showAsAction="ifRoom|withText"
    android:title="@string/delete">
  </item>
</menu>

Note that this menu definition requires a new string resource, named share, with a value like Share.

Step #2: Sharing the Note

Now, we need to configure the ShareActionProvider, in particular supplying it with a continuously-updated Intent, based upon what the user has typed into the EditText.

Add a ShareActionProvider data member to NoteFragment, named share, along with an Intent data member named shareIntent configured to use ACTION_SEND of a MIME type of text/plain:

  private ShareActionProvider share=null;
  private Intent shareIntent=
    new Intent(Intent.ACTION_SEND).setType("text/plain");

Then, in onCreateView(), tell the EditText to let us know when the user changes the text, via addTextChangedListener():

  @Override
  public View onCreateView(LayoutInflater inflater,
                           ViewGroup container,
                           Bundle savedInstanceState) {
    View result=inflater.inflate(R.layout.editor, container, false);

    editor=(EditText)result.findViewById(R.id.editor);
    editor.addTextChangedListener(this);

    return(result);
  }

This will fail to compile, as our NoteFragment is not implementing the TextWatcher interface. So, modify the NoteFragment class declaration to include the TextWatcher interface:

public class NoteFragment extends Fragment implements TextWatcher {

That, in turn, will require us to implement three methods:

  1. afterTextChanged()
  2. beforeTextChanged()
  3. onTextChanged()

In our case, we care about afterTextChanged(). So, add the following three methods to NoteFragment:

  @Override
  public void afterTextChanged(Editable s) {
    shareIntent.putExtra(Intent.EXTRA_TEXT, s.toString());
  }

  @Override
  public void beforeTextChanged(CharSequence s, int start, int count,
                                int after) {
    // ignored
  }

  @Override
  public void onTextChanged(CharSequence s, int start, int before,
                            int count) {
    // ignored
  }

Here, we update the shareIntent with the latest text to be shared, storing it in EXTRA_TEXT, per the instructions in the Android developer documentation for working with ACTION_SEND.

However, we have not initialized share yet. We can do that in onCreateOptionsMenu(), adding a call to findItem() to find our R.id.share menu item, then calling getActionProvider() to get the ShareActionProvider out of the menu item:

  @Override
  public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.notes, menu);

    share=
      (ShareActionProvider)menu.findItem(R.id.share)
        .getActionProvider();
    share.setShareIntent(shareIntent);

    super.onCreateOptionsMenu(menu, inflater);
  }

Here, we also attach the shareIntent to the ShareActionProvider, so when it comes time to share the text, the ShareActionProvider knows how to do that.

Step #3: Testing the Result

The preview of this section is being chased by zombies.

In Our Next Episode…

The preview of this section was lost due to a rupture in the space-time continuum.