Are You OK? App

I’ve just published a companion  site for my free app Are You OK?.

The app is aimed at people wishing to regularly check the status of family or friends who may for example live alone and are vulnerable to accidents like a fall in their home, unable to call for help. Something like the reverse of a panic button system; if they don’t press a button every few hours, it sends an SMS message to selected contacts with a call to check in.

Head over to the website to read more about the app and find the download link.

Fragments and Activities in Android Apps

When asking “should I use a Fragment or Activity?” it’s not always immediately obvious on how you should architect an app.

My advice is try to avoid a single “god” Activity (h/t Eric Burke) that manages navigation between tens of Fragments – it may seem to give you good control over transitions, but it gets messy quickly*.

My go to is always to use a combination of Activities and Fragments. So here are some tips:

  • If it’s a distinct part of an app (News, Settings, Write Post), use a new Activity. This Activity may be fairly light-weight, simply inflating a Fragment in its layout XML or in code.
  • For everything else use Fragments.
  • This gives you flexibility when combining Fragments in Activity layouts for tablet.
  • Create a BaseActivity class which handles setup/styling of ActionBar and SlidingDrawerLayout if you have that kind of navigation.
  • Nullify or customise the transitions between Activities if for example if you don’t want to have an obvious transition with an ActionBar that’s already in place (and you can make use of new L Activity transitions to smoothly transitions).
  • Fragments don’t need to be visual, an Activity can use the FragmentManager to create a persistent headless Fragment with setRetainInstance() who’s job may be to perform a background task (update, upload, refresh) – this means the user can rotate the device without destroying and recreating the Fragment, and is sometimes and alternative to binding to a Service onResume().

Some good sources for how to architect apps, as always the Google I/O Schedule app:

https://github.com/google/iosched

and Eric Burke’s 2012 talk, around half-way through:

http://www.infoq.com/presentations/Android-Design/

*When does it get messy?

  • When dealing with deeper hierarchies, and with navigational requests that come from a user action within a Fragment.
  • When you need the ActionBar to be in overlay mode (for a full screen experience) but only in certain screens.
  • When you need to create new tasks (either shooting off to another app and back, or allowing other apps to start Activities in your app to do something like with a Share action)
  • There are many more, please feel free to add some in the comments if you can think of any.

Registering Your Android App for File Types and Email Attachments

I’ve recently finished work on an app that registers itself as a handler for a given file extension, let’s call it “.mytype”, so if the user attempts to open a file named “file1.mytype” our app would launch and receive an Intent containing the informati…

I’ve recently finished work on an app that registers itself as a handler for a given file extension, let’s call it “.mytype”, so if the user attempts to open a file named “file1.mytype” our app would launch and receive an Intent containing the information on the file’s location and its data can be imported. Specifically I wanted this to happen when the user opened an email attachment, as data is shared between users via email attachment for this app.

There are many pitfalls to doing this, and the Stack Overflow answers I saw given for the question had various side-effects or problems. The most common was that your app would appear in the chooser dialog whenever the user clicked on an email notification, for any email – not just those with your attachment. After some trial and error, I came up with this method.

Create IntentFilters in AndroidManifest.xml

The first step is to add <intent-filter> nodes to the application node of the AndroidManifest.xml. Here’s an example of that:

<intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <action android:name="android.intent.action.EDIT" />
  <category android:name="android.intent.category.DEFAULT" />
  <data
    android:mimeType="application/octet-stream"
    android:host="*" 
    android:pathPattern=".*\\.mytype"
  />
</intent-filter>
<intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <action android:name="android.intent.action.EDIT" />
  <category android:name="android.intent.category.DEFAULT" />
  <data
    android:mimeType="application/mytype"
    android:host="*" 
    android:pathPattern=".*\\.mytype"
  />
</intent-filter>

Now something to note here, I’ve specified a filter for both “application/mytype” mimetype and also the more generic “application/octet-stream” mime type. The reason for this is because we can’t guarantee the attachment’s mime-type has been set correctly. We have iOS users and Android users sharing timers via email, and with iOS the mime type is set, with Android, at least in my tests on Android 4.2, the mime-type reverts to application/octet-stream for attachments sent from within the app.

Permissions

I initially put these IntentFilters on the “home” Activity of my app, however I soon started encountering security exceptions in LogCat detailing how my Activity didn’t have access to the data from the other process (Gmail). I realised this was because my Activity’s tag had the launch mode set to:

android:launchMode="singleTask"

Which prevents multiple instances of it being launched, this is important when users can launch the app from either the launcher icon or in this case via attachment (I didn’t want to have multiple instances of my home Activity running as that would confuse the user). So the solution was simply to create a new “ImportDataActivity” that handled the data import from the attachment, and then launched the home Activity with the Intent.FLAG_ACTIVITY_CLEAR_TOP flag added.

Importing Data

So in ImportDataActivity we need to import the data stored in the attachment, in my case this was JSON. The following shows how you might go about doing this:

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

  Uri data = getIntent().getData();
  if(data!=null) {
    getIntent().setData(null);
    try {
      importData(data);
    } catch (Exception e) {
      // warn user about bad data here
      finish(); 
      return;
  }

  // launch home Activity (with FLAG_ACTIVITY_CLEAR_TOP) here…
}

private void importData(Uri data) {
  final String scheme = data.getScheme();

  if(ContentResolver.SCHEME_CONTENT.equals(scheme)) {
    try {
      ContentResolver cr = context.getContentResolver();
      InputStream is = cr.openInputStream(data);
      if(is == null) return;

      StringBuffer buf = new StringBuffer();			
      BufferedReader reader = new BufferedReader(new InputStreamReader(is));
      String str;
      if (is!=null) {							
        while ((str = reader.readLine()) != null) {	
          buf.append(str + "\n" );
        }				
      }		
      is.close();

      JSONObject json = new JSONObject(buf.toString());

      // perform your data import here…

  }
}

That’s all that’s needed to register-for, and read data from custom file-types.

Sending Email with Attachments

Now how about sending an email with a custom attachment. Here’s a sample of how you might do that:

String recipient = "", 
  subject = "Sharing example", 
  message = "";

final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("message/rfc822");

emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{recipient});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, message);

// create attachment
String filename = "example.mytype";

File file = new File(getExternalCacheDir(), filename);
FileOutputStream fos = new FileOutputStream(file);
byte[] bytes = json.toString().getBytes();
fos.write(bytes);
fos.close();

if (!file.exists() || !file.canRead()) {
  Toast.makeText(this, "Problem creating attachment", 
      Toast.LENGTH_SHORT).show();
  return;
}

Uri uri = Uri.parse("file://" + file.getAbsolutePath());
emailIntent.putExtra(Intent.EXTRA_STREAM, uri);

startActivityForResult(Intent.createChooser(emailIntent, 
        "Email custom data using..."), 
        REQUEST_SHARE_DATA);

Please note that “REQUEST_SHARE_DATA” is just an static int const in the class, used in onActivityResult() when the user returns from sending the email. This code will prompt the user to select an email client if they have multiple apps installed.

As always, please do point out any inaccuracies or improvements in the comments.

Seconds Pro for Android

The latest Android app I’ve been working on for Runloop’s, the hugely successful iOS interval timer Seconds Pro, is now live. Packed with the following features:

• Quickly create timers for interval training, tabata, circuit training
• Save your tim…

The latest Android app I’ve been working for Runloop, the hugely successful iOS interval timer Seconds Pro, is now live. Packed with the following features:

• Quickly create timers for interval training, tabata, circuit training
• Save your timers, as many as you need
• Organize Timers into groups
• Text to speech
• Install timers from the timer repository
• Send your timers to your friends
• Full control over every interval
• Assign music to intervals or timers
• Large display
• The choice of personal trainers up and down the country

seconds

You can download the app now from the Google Play Store.

If you’re looking for high quality Android development, head over to my company’s website – Valis Interactive.

Getting Started with NFC on Android for .NET Magazine

A tutorial I wrote for .NET Magazine is now up on their site. This tutorial takes you through the basics of getting NFC working with Android 4.0+ with a “Top Trumps” like demo. It covers both reading and writing data to/from NFC tags, stickers or cards.…

A tutorial I wrote for .NET Magazine is now up on their site. This tutorial takes you through the basics of getting NFC working with Android 4.0+ with a “Top Trumps” like demo. It covers both reading and writing data to/from NFC tags, stickers or cards.

nfc-netmag

Head over to .NET Magazine to read the tutorial!

FanChants for Android

Last week I pushed FanChants for Android live. This app for FanChants.com provides access to the 20,000 real football chants as sung by the fans. Chants include lyrics and through an in-app-purchase can be set as your phone’s ringtone.

View FanCh…

My latest Android project is now live. This app for FanChants.com provides access to the 20,000 real football chants as sung by fans all over the world. Chants include lyrics and through an in-app-purchase chants can be set as your phone’s ringtone.

FanChants

View FanChants over at Google Play

Snowball Fight for iOS and Android

I’m pleased to announce a game we’ve been working on is finally out. A collaboration between The Creation Agency and Bitmode, we bring you The Great Snowball Fight!The game is played over Google Maps, launching virtual snowballs at unsuspecting p…

I’m pleased to announce a game we’ve been working on is now out. A collaboration between The Creation Agency and Bitmode (my previous home), we bring you The Great Snowball Fight!

Snowball Fight

The game is played over Google Maps, launching virtual snowballs at unsuspecting players in order to rank up, earn points and even win prizes from retailers you hit. You can also add buddies, connect via Facebook and receive special powerups.

Utilising Flash with AIR 3 and native extensions, we were able to build a game for iOS, Android and also PC. The game uses native extensions for deeper platform integration, such as the compass sensor or push notifications, as well as GPS to pin-point your location.

Head on over to the site to download the game and get throwing some snowballs!

Update: See comments for iOS compass extension source.

.NET Mag: User Interface Design for Android Apps

I recently wrote a tutorial for .NET Magazine covering styling and theming components in Android. This includes how to use resolution independent units so that your UI looks crisp across a wide range of devices and 9-patch images for smooth scaling.…

I recently wrote a tutorial for .NET Magazine covering styling and theming components in Android. This includes how to use resolution independent units so that your UI looks crisp across a wide range of devices and 9-patch images for smooth scaling.

netmag_android

Here’s a link to the article.

Are You OK Made The Finals of The Vodafone Smart Accessibility Awards 2011

I was absolutely delighted to hear that the app I put together for the Vodafone Smart Accessibility Awards has been made a finalist for 2011. The app, “Are You OK” falls under the wellbeing category. If you’re not familar with the awards, the idea is to…

I was absolutely delighted to hear that the app I put together for the Vodafone Smart Accessibility Awards has been made a finalist. The app, “Are You OK” falls under the wellbeing category. If you’re not familar with the awards, the idea is to improve the lives of the elderly or disabled through technology.

Are You OK is a simple app that was inspired by the panic button pendants many elderly use in their homes. The button communicates with a base-station plugged into the phone which contacts an emergency call center and and a voice can be heard over the speakerphone. The problem is these buttons are often left lying around out of reach, and many hours, or at worst days can go by before they get help after something like a fall. On top of this there’s a monthly fee for the service.

Are You OK works in reverse. It has an easily configurable alarm which goes off every X hours throughout the day, asking if they are OK with two big buttons, yes or no. If they hit no or fail to get to the phone within a certain time, it sends a text message to chosen friends or family asking them to check in by phone or by dropping by.

Tomorrow I’m off to Brussels to present the app before a panel. Here’s hoping it all goes well and if I’m very lucky I’ll get to bring back good news!

You can view the final 12 apps here.