NFC + Krautmilen + Android

kraut

We needed to make something to measure timings during the running event Krautmilen.

Equipment:

  1. Make a fugly Android app which could relay runners NFC keyring blips to a server API.
  2. Make a server API to handle the basic running logic (ie pair up names of runners with their start and finish times)

The application is quite simple: once the NFC tag has been blipped it sends an Intent to the application that contains the NDEF data. We grab the ID from the NDEF and perform a HTTP request to the server API.

Since the Android app basically just relays on sending NFC tag IDs to a server, there are lots of use cases, so we released it on Google Play yey! You can enter your own URL, make HTTP requests and use the data to whatever you want. NFC is everywhere nowdays; in travelcards, passports, library books and much more.

Here’s a small code example for handling the Intent:

private void handleIntent(Intent intent) {
      String action = intent.getAction();

      if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {

            NdefMessage[] messages;
            Parcelable tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            getTagData(tag);
      }
}

The only boring thing is that the Android device needs to be unlocked, because the device turns off the NFC chip when it is asleep. This is quite annoying but due to safety reasons it makes sense. You can go around that though, but you will have to root your Android device.

 

/Johanna

Relaying push notifications to your own API

We recently made a campaign for Loka mineral water, where users together reveal the new flavors. This is done by using Snapchat. We send users snaps containing puzzle pieces, and when they make a screen grab of a specific piece – we put that piece in the puzzle on the website.

Because of legal reasons we aren’t allowed to use the Snapchat API, but we still need to have some automation. For example we wanted to know immediately when a user made a screen grab of our puzzle piece snap, so we got around the problem by building an Android application.

In the latest Android SDK 4.4 (API 19) the “NotificationListenerService” was released. Using it, we can listen for incoming push notifications on our Nexus tablet. In the app, we’re just checking if the package name from the StatusBarNotification equals “com.snapchat.android” and if the notification ID matches the ID you get when someone is screenshoting your snap.

Then we post the username to our API, and cancel the notification from the NotificationListenerService.

code example:

@Override
   public void onNotificationPosted(StatusBarNotification statusBarNotif) {

       Notification notif = statusBarNotif.getNotification();

       if (notif != null){

           Bundle extras = notif.extras;
           Intent intent = new Intent(MainActivity.INTENT_NOTIFICATION);
           intent.putExtras(notif.extras);
           sendBroadcast(intent);

           Bundle intentExtras = intent.getExtras();
           String notifTitle = intentExtras.getString(Notification.EXTRA_TITLE);
           CharSequence notifText = intentExtras.getCharSequence(Notification.EXTRA_TEXT);

           int notificationId = statusBarNotif.getId();

           //Check if the notification is from snapchat, and the id matches the printscreen id from notification.
           if(statusBarNotif.getPackageName().equals(snapchatPackageName)){
               if(notificationId == printScreenId){
                  
                   //Split the String to get the username. 
                   String arr[] = notifText.toString().split(" ", 2);
                   String userName = arr[0];
                   
                   //Send to api.
                   runHttpPost(userName);
                  
                   //Cancel all notifications.
                   NLService.this.cancelAllNotifications();
               }
           }
           else{
               Log.i("Other", "Another type of notification.");
           }

       }
   }