Musubi on InformationWeek!

We’re very excited to have Musubi featured in InformationWeek! Kurt Marko’s article outlines some of the pitfalls of the modern landscape of the social web, and how Musubi offers an alternative. Check it out!

http://reports.informationweek.com/abstract/10/8776/Social+Networking-Collaboration/it-pro-impact-musubi-brings-openness-to-mobile-social-networking.html

Apr11

Writing interactive photo editors for Android

We recently released Musubi as a social messaging and app platform for Android devices. Musubi lets friends communicate using text, photos and voice, as well as using apps to create sketches or play games with each other.

With Musubi, we want to create a fun place for users to create and share content, and also a compelling platform for developers to create social apps. Here we will discuss how an app developer can make a photo editor that works with Musubi.

Editing pictures in Musubi is as easy as long-pressing the picture and choosing “Edit”. Musubi then finds apps on the user’s phone that are capable of editing photos and lets the user pick one from a list. Android’s system of Intents is perfectly suited for this, and it is a very common style of integration across Android apps. Android defines several well-known intent actions, such as “SEND” or “VIEW”.

Android also defines a standard action called “EDIT” for editing data. Simply filter on the EDIT action, and also specify the mime type of the data your app can edit. For example, to edit PNG images, filter on “image/png”. To edit any photo, use “image/*”.

However, the Edit intent as specified by Android doesn’t quite get us what we need. In Musubi, we wanted users to be able to choose a photo to edit, pick an application to use, and have that application return the altered photo so it can be displayed in a chat. According to the Android documentation, An app handling the Edit intent does not return any data to the calling app. For image editing, the location of the resulting image is unspecified and not reported to the calling application

The IN_PLACE category

Fortunately, Android intents offer a simple solution by way of categories. A category lets an app specify additional configuration information to a calling app, such as whether the target activity should be listed on the home screen (category LAUNCHER) or if it is safe for access from a browser (category BROWSABLE).

Musubi makes use of a new category for editing photos: mobisocial.intent.category.IN_PLACE. If an app includes this category in an intent filter, it is expected to save the resulting image over the image that was passed in as an argument, allowing the calling application to use the edited image.
Our whiteboard application allows a user to mark up a photo, with the resulting data returned to the calling app. Its intent filter is as follows:


<intent-filter>
  <action android:name="android.intent.action.EDIT" />
  <category android:name="mobisocial.intent.category.IN_PLACE" />
  <category android:name="android.intent.category.DEFAULT" />
  <data android:mimeType="image/*" />
</intent-filter>

The data passed in to the editor should be a uri for a file on the filesystem that can be read/written by both caller and callee apps. Also note that an intent filter with this IN_PLACE category will still match on intents that don’t specifically request this feature.

This simple addition to any photo editing app will make it more engaging and social, and we hope to see many apps take advantage of it soon!

Mar13

Writing Serverless, Multiplayer Apps for Android

Writing a multiplayer game for Android can be a bit of a chore. Standard options today include standing up a server to manage your games’ matches, or requiring those games take place purely locally using a LAN or a Bluetooth connection. Even with these solutions, developers must deal with the challenges of hooking up players and establishing connectivity across them.

With Musubi, we introduce a new option. Our mobile-first application platform lets developers write multiplayer applications without worrying about the details of connectivity and without managing any server code. Musubi lets friends run applications together by connecting them through the phone’s own built-in user network: it’s address book.

We are excited to see what kinds of applications can be built with Musubi, and we’re developing a library called SocialKit to help developers get started. There are many different styles of connected apps, and we provide different abstractions to help manage their unique cross-device requirements. For example, you can write a turn-based-game with the TurnBasedMultiplayer api, persist data in Musubi’s SocialDb, or support realtime communication using Junction.

Musubi, available now in the Android Market, serves as the platform for running serverless social applications built with SocialKit. All messages sent through Musubi are encrypted so that not even we can access your application’s data. SocialKit is still in beta and is updated often. We welcome developers to build cool social apps and new connectivity apis with us. We will post tutorials on writing SocialKit apps in the near future, and you can check out our SocialKit Wiki for more information about the protocols and apps we’ve built.

Jan26

Building NFC-aware Applications

As NFC finds its way into more and more phones, developers can start thinking about how to use it to make their applications more viral, more engaging, and easier to use. Android’s recent release of Ice Cream Sandwich adds some APIs to help developers make full use of NFC in compelling ways. Building the best possible NFC experience can be tricky, and we offer a few ideas to help get you there. (Full disclosure: I spent a few months interning with Android’s NFC team and got to help develop some of these APIs.)

This post is a quick guide to help you wrap your head around some of the NFC basics, applicable across platforms. For a detailed look at how NFC is implemented on Android, please see the SDK documentation.

NDEF: a primer

NDEF (NFC Data Exchange Format) is the fundamental data unit of an NFC interaction. An NFC event occurs when two devices come within range of each other, and either device may send or receive an NDEF message. NFC events can be between two active devices such as two phones, or between an active and a passive device such as a phone and an nfc tag or sticker.

An NDEF message is composed of one or more NDEF records. These records contain three primary pieces of information: (1) a “type name format” (TNF), indicating how the record’s bytes are to be interpreted, (2) a type field defining the context of that data, and (3) the actual payload of the record.

The TNFs are best understood by enumeration:

  • Absolute URI: The record is formatted as a uri
  • Well-Known: The format of this record is specified by the NFC Forum
  • Mime: The record is of a well-known mime type, defined outside of the NFC Forum
  • External: The record is formatted according to some external specification
  • Empty: The record contains no data beyond this TNF field

With this field set, the type field further defines how to interpret the bits. For example, if the record is for a mime type, we must know which mime type it represents– text/plain, image/jpeg, etc. Well-known types defined by the NFC forum include “Smart poster”, text, and uri.

Warning! There are overlaps in functionality across these TNFs. A text snippet could be represented as mime type “text/plain” or as the well-known type “text”. The actual bytes representing the text have different formats depending on the language, character codes, etc. A web URl could be represented as an absolute URI, but is better represented as the well-known type “uri”, which includes constants for common schemes like “http://” or “mailto:”.

NFC Interactions

An application on a phone can use NFC in a few different ways:

  1. Write NDEF messages to an NFC tag
  2. Read NDEF messages from an NFC tag
  3. Exchange data with another device
  4. Emulate an NFC tag (card emulation)
  5. Leverage the phone’s “secure element”.

Card emulation is available as an API on the Blackberry platform, but not on Android. Programming the secure element in a general way is a challenge and is not currently supported on either platform. Most commonly, applications will read and write tag data and exchange data with other devices.

A few months ago, the NFC Forum released a specification called SNEP. The goal of SNEP is to allow devices to communicate over P2P NFC across different platforms. As of Ice Cream Sandwich, Android devices communicate using the SNEP protocol, and hopefully other platforms will support it soon. In its most basic form, SNEP can be used to send and/or receive a single NDEF message across devices. While sending a single message may seem like a severe limitation, the functionality is extremely powerful and can in itself be complex to master.

Building an NFC Application

So how can you leverage this single NDEF message to do something cool in your application? Say Alice, your user, touches her phone to another device, be it a sticker or smartphone. If we take a snapshot of this scene, we can ask ourselves: what is running on Alice’s phone? Most smartphone operating systems have the user interact with one foreground application at a time. It may be your application, another application, or the platform’s home screen.

If your application is running in the foreground, you should think about how to handle various types of NDEF data. Often, your application will understand a limited set of data types. On Android, you can and should specify the type of data your application understands. If the user interacts with data that your application does not support, the operating system can find an application that does.

You should also think about the types of data your application might expose– A web browser can share its current webpage, a social network could allow for the exchange of contact information. If you cannot think of any appropriate data to share, you may want to share a reference to the application itself. In fact, as of Ice Cream Sandwich, Android applications will share a reference to themselves if no NFC functionality is defined— if Alice runs your application and touches another device, that device will either launch your application or be taken directly to its Market entry.

If your application is not running in the foreground, think about the types of data that should cause your application to be invoked. Again, Android lets you specify the types of data that should trigger your application by supporting the NDEF_DISCOVERED intent in your application’s manifest.

The NFC Forum dictates that the first record in an NDEF message defines the context of that message. In Android, this amounts to the platform dispatching records based on the type of this first record. Subsequent records are used to contain application-specific data payloads.

Educating your users about your application’s NFC functionality is a further challenge. Since NFC is a technology that essentially lives “behind the screen”, it is your responsibility to teach them about the added functionality, lest it remain an easter egg hidden within your application.

Cross-Platform Applications

Say your application is available for a variety of platforms: web, Android, Blackberry, Windows, iOS, etc. As mentioned, the first record is intended to define the NDEF message’s context, yet each platform may require a different type to invoke your application. To mitigate this, as of Ice Cream Sandwich, Android understands an “Android Application Record” (ARR), which can be located anywhere inside an NDEF message. The ARR can also be used to bring the user to your app’s market entry if it is not yet installed.

Extended Interactions

An NDEF exchange lets you send and receive only a single NDEF message. If your goal is to set up a long-lasting session between devices (for example, to run a 2-player multiplayer game), this is still enough information to get you going. We have developed a library for Android called EasyNFC which supports exactly this use case, helping you set up a Bluetooth link across phones. The library helps you get the best possible NFC user experience, launching the game regardless of whether both users have your application in the foreground or if only one does, and regardless of whether the application is installed on both devices or just one.

EasyNFC is an open-source library, and we’re happy to hear feedback and especially take contributions : )

Dec26

Android and SNEP

Google’s latest version of Android is slated for release soon. One of the key features include enhanced NFC support in the form of Android Beam. Many built-in applications, from YouTube to the standard web browser to the contact manager, will support NFC by default, allowing users to quickly share data from one device to another.

A few months ago, I was privileged to intern with the (incredibly hard working) NFC team. One of the main projects I got to help with affects the underpinnings of how peer-to-peer NFC works across devices in Android. Previously, Android relied on the custom “NDEF Push Protocol” for sharing messages across devices. The NFC Forum recently published a new specification for running p2p interactions, called SNEP (Simple NDEF Exchange Protocol). This specification supports the same interactions as the NDEF Push Protocol in a standards-compliant way.

In Ice Cream Sandwich and beyond, Android devices will make use of SNEP for P2P exchanges. As other platforms build out further support for NFC, hopefully they too will make use of the SNEP protocol, allowing NFC interactions across platforms. The future of mobile sharing is looking bright!

Oct23

Muse: Reviving Memories with Email Archives

(Cross-posted from the Crowd Research blog)

Since the first email message was sent in 1971, the usage of email has evolved significantly. Email is used today not just for interpersonal communication but also, for example, to plan events and trips, maintain records, make online purchases, track to do items, process business workflow, and even to indulge in email wars or tell people that you’ve been summarily fired. Our email archives directly or indirectly capture an astounding amount of our personal histories; in fact, many of us consciously deposit information into email “for the record”, knowing that we can look it up later.  Imagine an archive that captures all the email messages that you’ve typed over a period of 50 years or more! Such an archive would be extremely valuable for reasons of personal or family history, and may also be of interest to related individuals and organizations, and digital archaeologists of the future.  As the Library of Congress says, be sure to save your email archives!

However, even if you accumulate and preserve your email archives over decades, it is a challenge to make sense of a huge collection of messages. Given a loosely organized pile of tens of thousands of emails, how would you visualize it and find interesting patterns? How would you go about identifying and browsing the important and meaningful messages?  This is where Muse comes in. Muse (short for Memories Using Email) is a program that helps users revive memories, using their long-term email archives. You can supply Muse with your email from a webmail account like Gmail or Yahoo, or give it files stored locally on a hard drive. Muse crunches the archive, and throws up a set of cues that can be scanned rapidly and act as entry points into browsing messages in the archive. To generate these cues, we employ some novel data mining techniques that are lightweight enough to run quickly on fairly large collections. We have also designed an interactive user interface in Muse that faciliates rapid browsing. This is important since cues are merely reminders, and people spend most of their time browsing the actual message contents themselves.

Briefly, the four types of cues that we found useful in jogging users memories are the following: communication patterns with automatically inferred groups, sentimental words, a monthly timeline of significant names in the archive, and image attachments.  The details of how we generate and present these cues are in our UIST-2011 paper. In our studies, we asked users to rate these cues, and found that all four types of cues were broadly liked by users, with attachments, sentiment analysis, and the monthly top terms all rated close to the highest.  This was not particularly surprising to us, because we designed each cue type in response to early rounds of user testing, and observing users as they explored their archives.

However, what was surprising was the different kinds of uses that our users came up with while running Muse on their email archives. While our initial goal was only to support the task of reminiscence, we heard users say that Muse would be useful to summarize work progress, to remind one to renew long-neglected friendships, or even just to identify personal email inside a work account, so they could take it out with them when leaving a job. Moreover, users broadly enjoyed looking through their archives, and this process, instead of being a purely reflective activity, in some cases prompted them to take action in the future.

We’re also pleased to find that librarians and archivists are very interested in tools like Muse to help them process the archival papers of famous individuals. For example, wouldn’t it be wonderful to browse the historical email archives of Apple Computer or the email correspondence of Salman Rushdie — if they were part of their respective collections? Many archives being acquired today involve digital materials, and a lot of the detailed record is in the form of email. Tools like Muse may be helpful in these scenarios as well.

There is a lot of interest today in technologies for “life-logging”. Email archives represent the simplest and most pervasive form of life-logging that billions of people already use. It is also the form that is likely to have been used consistently over a long period of time, and thus studying it can inform the design of other forms of long-term life-logging.

Muse is an active research project in the Mobisocial laboratory at Stanford University, and is joint work by Sudheendra Hangal, Monica S. Lam and Jeffrey Heer.  We have made a beta version of Muse publicly available at the URL: http://mobisocial.stanford.edu/muse. Feedback and contributors are welcome!

Oct17

Ultra Fast Android Emulator

I gave up using the qemu based emulator bundled with the Android SDK a long time ago. It bogged down the whole system and performed abysmally slow. Sometimes its nice to be able to test things out without an actual phone handy though, so I did a bit of work to setup a VirtualBox VM that runs the x86 version of Android. It is missing Google’s services and frameworks for obvious reasons. The three worst limitation are that it lacks a camera, has no GPS, and doesn’t support screen rotation at runtime (only at boot). It may or may not work for you as a quick test bed. For me it’s ideal for rapidly trying out change to UI. Since it taps into the 3GHz of out of order execution power available on my host, it screams through basic application workloads. Another scenario where it is incredibly handy is for upgrade testing. You can take a snapshot of the VM before you deploy code that applies a database update. Then if it really messes things up, you can just rollback. It comes pre-rooted as well.

There are a bunch of little tweaks you need to make to the installation to get video modes, mouse support, and adb connectivity working. If you want to avoid all that, just download the packaged OVF format appliance from here. You’ll also need VirtualBox from here. Once you install VirtualBox, just import the .ova appliance file. After you start the VM, run adb connect 127.0.0.1 on your host machine to add the emulator to the device list.

Most of the work was done by the Android x86 Project since they created a clean installer for devices like the EEE PC. There is some more information about this concept here

I’ve had very good success being able to simulate all the Android buttons with the keys on an extended Windows keyboard. On an Apple laptop, I was not able to figure out how to press the “Menu” key.

Sep14

Rotating Images in Android

We’ve been hard at work on our latest research project, code-named DungBeetle, a social network between phones. Sharing photos is an important part of our mobile/social experience. To get it right, we had to learn a bit about image rotation in Android to handle the various ways a photo can be shared, and thought we’d share the experience.

In our app, images are shared as a Uri, and can come from a number of sources. Most importantly, an image might come from Android’s media provider, as a “content://” uri, or it might be stored on the filesystem using the “file://” uri scheme, and each source has its own way of handling image rotation.

For images from the filesystem, we use the standard EXIF metadata to handle image rotation, using Android’s ExifInterface. However, data from the content provider doesn’t have this metadata. Instead, the rotation value can be queried via the content provider.

The following code will handle rotation properly from either source:

public static float rotationForImage(Context context, Uri uri) {
	    if (uri.getScheme().equals("content")) {
            String[] projection = { Images.ImageColumns.ORIENTATION };
            Cursor c = context.getContentResolver().query(
                    uri, projection, null, null, null);
            if (c.moveToFirst()) {
                return c.getInt(0);
            }
        } else if (uri.getScheme().equals("file")) {
            try {
                ExifInterface exif = new ExifInterface(uri.getPath());
                int rotation = (int)exifOrientationToDegrees(
                        exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                                ExifInterface.ORIENTATION_NORMAL));
                return rotation;
            } catch (IOException e) {
                Log.e(TAG, "Error checking exif", e);
            }
        }
	    return 0f;
	}

	private static float exifOrientationToDegrees(int exifOrientation) {
        if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
            return 90;
        } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
            return 180;
        } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
            return 270;
        }
        return 0;
    }
}

The rotation value can be used to correct a photo’s orientation as follows:

Matrix matrix = new Matrix();
float rotation = PhotoTaker.rotationForImage(context, uri);
if (rotation != 0f) {
     matrix.preRotate(rotation);
}

Bitmap resizedBitmap = Bitmap.createBitmap(
     sourceBitmap, 0, 0, width, height, matrix, true);

Aug16

Build stuff with us!

Come code with us!

The thing that excites us most about what we do is getting other people interested and involved with our work. That’s why we make most of our development available as open source, and develop most of that code in the open as well.

We currently maintain two Github organizations with our code– One for Mobisocial’s projects in general, and a separate one for the Junction platform and applications. If you’d like to contribute, the easiest way is to fork a project on Github and submit push requests back to us. Forking a project will let us follow your work as you code, and let you tweak any project as you see fit. If you plan on contributing frequently, feel free to contact us to discuss more direct code access.

Jul21

Generating QR Codes in Chrome

Here’s a quick and easy way to generate QR codes in Chrome. Adding a pseudo-search engine for QR codes allows you to type “qr [content]” in the browser and instantly get back a QR code.

How to set it up:

In Chrome, open preferences, Basics => Search => Manage Search Engines. Click “Add…”:

  • Name: QR Generator
  • Keyword: qr
  • URL: http://chart.apis.google.com/chart?cht=qr&chs=350×350&chl=%s

That’s it! Here are some screenshots, professionally edited to highlight the action.

Jul19