My First Open Source Contribution

It’s been awhile since my last post, and I’m sorry for that. I’m sure all of my readers have been greatly disappointed in the last few months. In the meantime though I was able to accomplish one of the goals I’ve had since first becoming a Software Engineer! I made my first open source contribution. It wasn’t much and it’s not something I think people would traditionally write about, but I enjoyed it and got a lot out of it.

The project I contributed to is an Android application. It is the Android client for my favorite software engineering podcast: Software Engineering Daily. If you haven’t listened to them, please go check them out at their website. Definitely worth a listen, and you’ll advance your career at the same time with interviews and knowledge about current trendy topics. I went to the github URL for their app and combed through issues looking for anything easy I could get my hands on. That ended up being implementing a share button.

Software Engineering Daily had a view within their Android application that enabled a user to play the podcast episode, view the transcription of the episode, and download the podcast to their phone. The Github issue involved placing a share button on that view so that users can also easily link their friends, family, and whoever else they want to the episode to increase the reach of Software Engineering Daily.

A button didn’t sound that hard initially to me, so I decided that this issue would be how I got my feet wet in the open source world, and I took it on.

I started by adding a menu to the podcast view that I could attach my button to. That menu looks something like this.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menu_item_share"
        android:actionProviderClass="android.support.v7.widget.ShareActionProvider"
        android:enabled="true"
        android:icon="@android:drawable/ic_menu_share"
        android:showAsAction="ifRoom"
        android:title="Share"
        android:visible="true"
        app:showAsAction="ifRoom" />
</menu>

While I didn’t know a whole lot about how and/or why this was the right way to set up the menu, I did a good bit of research, and can go into what each of these items mean in a little more detail.

menu - This is a container for different menu items, and represents one instance of the Menu class. I will go into how I actually use the menu later.

item - A MenuItem, represents either objects in the menu or nested Menu objects.

android:id - A unique identifier for this item, I chose menu_item_share

android:actionProviderClass - An object with nicely bundles functionality for accomplishing a given task. I chose the ShareActionProvider. This Action Provider will handle creating the actual share view as well as any graphics needed when we render this item and when we actually tap this item in the menu.

android:enabled - Whether or not this particular object is usable.

android:showAsAction - Defines how Android should display the item in the Action Bar, ‘ifRoom’ means that it will only display if there is enough space for it.

I left out the more self explanatory ones and anything redundant.

Okay so now that there is a menu, I tried to render the view I added the menu to to no avail. It wasn’t displaying? Why? It turns out there is more to it than just making an XML file. You have to actually use this menu in the view somehow to display it and programatically add functionality to it. Here is how I was able to do that.

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.podcast_detail_menu, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()) {
      case R.id.menu_item_share:
        startShareIntent();
        break;
    }

    return super.onOptionsItemSelected(item);
  }

  /*
   * Start a share intent
   */
  public void startShareIntent() {
    String shareContent = "Check out this episode of Software Engineering Daily: ";
    shareContent += post.getLink();

    Intent shareIntent = ShareCompat.IntentBuilder.from(this)
            .setText(shareContent)
            .setType("text/plain")
            .setChooserTitle("Share Podcast")
            .createChooserIntent();

    startActivity(shareIntent);
  }

The first function, onCreateOptionsMenu, programmatically inflates the menu on the activity. Using the ID R.menu.podcast_detail_menu, I am able to specify that it is my menu I showed above in XML that I want to inflate.

The second function, onOptionsItemSelected, overrides the default activity behavior to provide functionality to my options menu items. As other items are added to the menu, they can be reflected in the switch statement in the function there. My MenuItem, R.id.menu_item_share, is specified there and when selected will start a share Intent.

The last function startShareIntent, will first build a string with the URL of the global post object that represents the podcast being displayed in the activity. That string is then passed to the Intent shareIntent.

Android has objects that are called Intents. Intents are classes that allow Android apps to interface with other Android apps. Share buttons are backed by Share Intents. Share Intents are very easily created using the utility class ShareCompat.IntentBuilder. Using chained calls to the intent builder, I can then setup exactly what I want to be done in the Share view that is started by the intent, and then call startActivity

And that’s pretty much it! Again I can’t thank Software Engineering Daily enough for the awesome content they put out every week, and to the owners of the repository for how amazingly nice they were and helpful through the whole process. I have big plans for continuing to contribute to the app, as well as some other amazing OSS projects on the horizon. Thanks!

 Share!

 
I run WindleWare! Feel free to reach out!

Subscribe for Exclusive Updates

* indicates required