Search code examples
androidnfcandroid-beam

Android Beam: How to Beam Contents being Downloaded


I am developing an applicaiton which supports content delivery via Android Beam (to be more accurate, supporting an NFC-initiated content transfer using Bluetooth). I'm using the well-known APIs available through NfcAdapter class, nameley,

nfcAdapter.setBeamPushUrisCallback(new NfcAdapter.CreateBeamUrisCallback() {

                @Override
                public Uri[] createBeamUris(NfcEvent event) {
                    if (singleItemToTransfer()) {
                        if (item.getLocalPath() != null) {
                            File file = new File(item.getLocalPath());
                            return new Uri[] { Uri.fromFile(file) };
                        } else {
                            // Download the content & pass the handle
                            // for the content being downloaded
                        }
                    }
                }

}, this);

Now the question is how Android framework will handle scenarios, where the content to be transferred is currently not available and yet needs to be downloaded first and then transferred. For example, only the preview of a photo is available and upon selecting the preview, the app downlads the content first and then transfers via Android Beam (Bluetooth, for instance). I searched arround and found out that there are ways to obtain a handle to the files currently being downloaded by the Android DownloadManager. For example, there is an interesting post here. Basically, the DownloadManager class stores a list of http downloads initiated and their associated status. It was suggested that we filter downloads out based on whether the downloads are 'RUNNING', 'PENDING', 'PAUSED' and so on. This list can be read into a cursor and one of the columns of the result is 'COLUMN_URI', which is the url from where the file is being downloaded.

Regaridng the aforementioned solution, there is a concern, though: What if the content is in the Cloud? Say, Google Drive? I search further and came across with many posts, e.g., here. Apparently, the download part is still in place. The content needs to be first downloaded before being transferred.

Apart from the above question, I also wondered how Android Beam would act if we are first aiming at downloading the content and then returning the URI of the file whose download is now complete. In order to test, I created a mock code, like Thread.sleep(_some_time_); and then passed the URI of an actual within createBeamUris() call. In this case, Android Beam prompts the user on detecting the other device in the field and then waits for the amount of time introduced above and then issues "Tap to Beam", which in general gives an extremely terrible user experience (for example, the other device's screen gets locked and NFC goes OFF). Subsequently, I thought about passing a URI for the file being downloaded and then transfer the content while it is being downloaded! I am not sure how this will be handled. I am afraid that modifying how Android Beam works is the only option. Any hints is highly appreciated!

If you believe I have missed something, kindly let me know and I will update the post.


Solution

  • I eventually decided to change the Android framework and got it working.