I am trying to use Android Beam to transfer large files between apps. The sending part is working well and files are appearing in the 'beam/' directory. The Notification status bar displays "Beam complete". However, the receiving app does not get notified after the files are renamed into the beam/ directory and onNewIntent() never gets called on the receiving end. What am I missing with the intent-filter? Also is it possible to specify a Android Application Record while using createBeamUris()? TIA
// sending app
nfcAdapter.setBeamPushUrisCallback(this, this);
...
@Override
public Uri[] createBeamUris(NfcEvent event) { // send files
File dir = Environment.getExternalStorageDirectory();
File file = new File(dir, "test.txt");
file.setReadable(true, false); // readable=true, ownerOnly=false
return new Uri[] { Uri.fromFile(file) };
}
My Manifest.xml:
<activity
android:name=".BeamDemo2"
android:label="@string/app_name"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.txt" />
<data android:host="*" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/com.example.beamdemo2" />
</intent-filter>
</activity>
I have also tried enableForegroundDispatch():
@Override
public void onResume() {
super.onResume();
try {
PendingIntent mPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter ndefIntent = new IntentFilter("android.intent.action.VIEW");
ndefIntent.addCategory("android.intent.category.DEFAULT");
ndefIntent.addDataType("*/*");
IntentFilter[]mIntentFilters = new IntentFilter[] { ndefIntent };
String[][] mNFCTechLists = new String[][] { new String[] { NfcF.class.getName() } };
mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, mIntentFilters, mNFCTechLists);
} catch (Exception e) {
Log.e("onResume", e.toString());
}
}
Short answer, there is no answer :-(. After the Beam finishes, one needs to pull down the "Beam Complete" notification and select "View File". This causes a Chooser to appear, and then a VIEW intent is dispatched to the activity. I was hoping to avoid this manual step, but it seems to be unavoidable. I'd also like to avoid the Chooser to select an application for VIEW, but that too seems unavoidable. EnableForegroundDispatch seems to be only for android.nfc.action.NDEF_DISCOVERED.
After choosing the app, things work as expected. I see onNewIntent(), followed by onResume(). One weirdness, the received intent seems to stick and keeps reappearing. After processing the VIEW intent in onResume(), I had to kill it by calling setIntent(null).
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
@Override
public void onResume() {
super.onResume();
Intent intent = getIntent();
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
processIntent(intent); //
setIntent(null); // kill this event
}
}