8

I am trying to use NFC to send a URL from an Android app to a WP8 phone.

When beaming to an Android device, the URL is sent correctly. However, when beaming to WP8, IE loads a link to the Play Store instead of the one I want to send (e.g. "http://www.stackoverflow.com").

The Play Store link is: "https://play.google.com/store/apps/details?id=com.example.conductrnfc&feature=beam". Where "com.example.conductrnfc" is the package name in the project.

The code I used to generate the NFC message is given below. Is there something I'm doing wrong here that breaks compatibility with WP8?

NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
nfc.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
    @Override
    public NdefMessage createNdefMessage(NfcEvent event)
    {
        NdefRecord uriRecord = NdefRecord.createUri(urlString);
        return new NdefMessage(new NdefRecord[] { uriRecord });
    }
}, 
this);
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
J Yang
  • 81
  • 3
  • Are you also attaching an AAR to the message? It wouldn't seem like it, given your code, but that's one thing that I know of that leads apps to the Play Store from an NFC message. – CommonsWare Jan 04 '14 at 22:15
  • I haven't attached an AAR, the URL is the only record in the message. – J Yang Jan 04 '14 at 22:52
  • 1
    can you show the link you send to WP8 and what appears in WP8 exactly? – 72DFBF5B A0DF5BE9 Jan 08 '14 at 04:39
  • @M.C. - The actual code is `NdefRecord uriRecord = NdefRecord.createUri(webView.getUrl());` with the webView having been pointed to a website (not the play store) in the activity's onCreate. What WP8 sees is the URL mentioned in the question – Robert Levy Jan 08 '14 at 15:16
  • @RobertLevy, so any URL you send to WP8, it sends URL to your app in app store? – 72DFBF5B A0DF5BE9 Jan 08 '14 at 16:10
  • Yes, that's what it looks like... except that this app isn't actually in the store – Robert Levy Jan 08 '14 at 16:11
  • Android Beam sending the Play Store URL is the default behavior if the app doesn't itself setup any NDEF message for Beam. Can you confirm that the `createNdefMessage` callback is actually called (e.g. by adding logging)? – Michael Roland Jan 08 '14 at 20:33
  • It is called in the debugger when I attempt to send a message. – J Yang Jan 09 '14 at 05:07
  • Can you try if you get the same result if you use `setNdefPushMessage` to set a static NDEF message instead of creating one dynamically using the callback? (Note that you must not register a callback with `setNdefPushMessageCallback` in that case!) – Michael Roland Jan 09 '14 at 08:03
  • Btw. what Android version are you using? – Michael Roland Jan 09 '14 at 08:04
  • You did not also register for `setBeamPushUris` or `setBeamPushUrisCallback`, right? – Michael Roland Jan 09 '14 at 08:37
  • @MichaelRoland this is 4.4.2 and OP is not calling those functions. should he? – Robert Levy Jan 10 '14 at 02:51
  • another clue: i noticed that it's not just our app that is sending Play Store links... it seems android is doing that by default for all apps except a few are sending over custom things (Chrome has no problem sending over whatever URL it is currently showing). Is the code posted in the question insufficient? – Robert Levy Jan 10 '14 at 02:55
  • @MichaelRoland correction: `createNdefMessage` is called when beaming to Android, but not called when beaming to WP8. What could the reason be? – J Yang Jan 10 '14 at 03:25
  • further strangeness: setNdefPushMessageCallback works android-to-android but not WP8. If we do setNdefPushMessage, that works for both (but we kinda want to use the callback approach to dynamically generate the URL) – Robert Levy Jan 10 '14 at 04:03
  • @RobertLevy No, the setBeamPushUri* functions should not need to be called. – Michael Roland Jan 10 '14 at 06:06
  • @RobertLevy sending Play Store links: That's what I wrote about Android Beam's default behavior above. – Michael Roland Jan 10 '14 at 06:07
  • Okay then, that's bringing us closer to identifying the issue. Could you add log messages to the lifecycle methods of the activity (onCreate, onStart, onResume, onPause, onStop, onDestroy) and show us the result for both an android-to-android beam and an android-to-wp8 beam? I would guess that there's a difference... – Michael Roland Jan 10 '14 at 06:08
  • In addition to the above, in case you use a Nexus device, can you check if you receive any log messages with log tag `NfcP2pLinkManager` (again for both android-to-android and android-to-wp8)? – Michael Roland Jan 10 '14 at 07:12

2 Answers2

3

Can you try this:

NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
nfc.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
    @Override
    public NdefMessage createNdefMessage(NfcEvent event)
    {
        byte[] payload = urlString.getBytes();
        NdefRecord uriRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload); 
        return new NdefMessage(new NdefRecord[] { uriRecord });
    }
}, 
this);
72DFBF5B A0DF5BE9
  • 4,954
  • 3
  • 21
  • 24
0

Eventhough I still miss some more debugging results from the OP, I thought I'd give it a shot:

As the discussion in the commands revealed that the createNdefMessage callback is not called when interacting with a WP8 phone, it would be interesting why this appens and how to prevent this. Unfortunately I have no details about the actual lifecycle of the activity, so I can only guess what might go wrong.

  1. One reason why a registered createNdefMessage callback may not be called is that the activity that registered the callback is no longer in the foreground. So there may be a difference between an Android device and a WP8 device that causes the current activity to be paused.

  2. Another reason would be that the WP8 device interupts communication before the Android NFC stack had the time to call the createNdefMessage callback method. However, this should be detectable as the Beam UI would typically disappear before the user is able to click it.

One cause for reason 1 may be that the WP8 device itself sends an NDEF message that causes intent processing on the Android device. If that's the case, a method to overcome this problem may be to register for the foreground dispatch system. This would prevent regular intent processing and would directly send all incoming NDEF messages to the current activity:

@Override
public void onResume() {
    super.onResume();
    NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
    PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    adapter.enableForegroundDispatch(this, pi, null, null);
}

@Override
public void onNewIntent(Intent intent) {
    if (intent != null) {
        String action = intent.getAction();
        if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) ||
            NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) ||
            NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
            Log.d("NdefTest", "This problem was actually caused by an incoming NDEF message.");
        }
    }
}
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • Hey sorry we haven't had a chance to dig in and get other details to really solve this. I appreciate your patience and the back and forth troubleshooting effort though so the bounty is all yours. – Robert Levy Jan 15 '14 at 02:24
  • Yup, us too :) Will definitely come back to this when time allows and post results here – Robert Levy Jan 15 '14 at 14:12