0

I want to beam the content of my currient screen. Basically I have three tabs with long lists, I want to beam the actual tab and its position.

My goal is if the app is installed:
Beam some id, the tab and position

If the app is not installed:
I want to offer a weblink like this http://example.com/viewer/42?tab=2

I'm playing with this code here:

adapter.setNdefPushMessageCallback(new CreateNdefMessageCallback() {
    @Override
    public NdefMessage createNdefMessage(NfcEvent event) {
        return new NdefMessage(new NdefRecord[] {
            NdefRecord.createExternal("com.example.android", "viewer", getData()),
            NdefRecord.createUri(VIEWER_URL + id + "?tab=" + tab),
            NdefRecord.createApplicationRecord("com.example.android"),
            NdefRecord.createApplicationRecord("com.android.browser"),
        });
    }
}, this);

I would be happy if someone could explain me how that works and if this is not possible to explain me why this is impossible.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
rekire
  • 47,260
  • 30
  • 167
  • 264

2 Answers2

2

You can simply beam the weblink in a Uri record, I would say, and add an intent filter for this URL. If the app is installed, it can get the required info from parsing the URL. And if not, the browser will open.

NFC guy
  • 10,151
  • 3
  • 27
  • 58
  • Well I had that idea too, but I want to avoid the intent chooser. I would like to add some kind of alternative NDEF messages. I read somewhere that it would be possible that I could address a message to a speficic app and if it would not been installed forwarted to another... such a best fit algorithm. – rekire Oct 13 '13 at 08:37
1

As @NFC guy already explained, the way to go is to Beam your URI (and only that URI, or at least that URI as the first record of that NDEF message). So your NDEF message would look something like that:

new NdefMessage(new NdefRecord[] {
    NdefRecord.createUri("http://example.com/viewer/ + id + "?tab=" + tab),
    // TODO: add more records if you want to provide additional data to YOUR app if it is installed
});

Then you would use an NDEF_DISCOVERED intent filter in your app's manifest to catch that specific URI:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="http" android:host="example.com" android:pathPrefix="/viewer/" />
</intent-filter>

If the URI belongs to you (i.e. if no other app registers for a URI that starts with http://example.com/myapp/) and your app ins installed, there will be no intent chooser (as the more specific URI will take precedence). If your app is installed, it will receive the URI. If it's not installed, the browser will open the URI, or if other apps registered for NDEF_DISCOVERED with only the scheme "http", there will be an intent chooser (though usually other apps than web browsers should usually register for a more specific URI).

Regarding your current NDEF message:

  1. You should not use more than one Android Application Record (AAR). Only one of them will be effective.
  2. If you use an AAR for your app, you make it impossible for the web browser to catch the URI in case your app is not installed. Instead, your app's Play Store listing will be opened.
  3. Using something other than a URI as the first record will make automatic launching of the default web browser impossible if your app is not installed.
Community
  • 1
  • 1
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • You are pointing out some very interesting points like that an app will be preferred if it is the only url listener for the registered scheme/url. I'll check it next week. If it works like described I'll accept your answer. About opening the play store: I can link to it in the HTML so this is IMHO no problem. – rekire Apr 19 '14 at 05:34