ICS introduces the possibility to share an application via Android Beam using NFC, and as far as I understood if an app is opened on deviceA it will automatically be started on deviceB (if it's already installed on it, otherwise the Market app will open) when the devices are close enough and a user "touches to beam" it. Is there a way, inside the launcher Activity, to detect if it has been started because of a NFC message or because of a user interaction?
Only NFC Intents are started when a beam occurs. These are ACTION_NDEF_DISCOVERED, ACTION_TECH_DISCOVERED, or ACTION_TAG_DISCOVERED. Check out the beaming section of the dev guide for how to handle beams: http://developer.android.com/guide/topics/nfc/nfc.html#p2p
In case the Android Beam (or NDEF) message contains an Android Application Record, http://developer.android.com/guide/topics/nfc/nfc.html#aar, the resulting Intent to start the app will not be of the action ACTION_NDEF_DISCOVERED, but ACTION_MAIN. This method can be used to launch any app, including apps that do not filter for NFC intents.
Related
Sorry if this sounds like a lazy question, but I've Googled and couldn't find an answer: I suspect this is because it can't be done as I describe below.
I have an app which runs on the phone for remote controlling power devices. At the moment, users can create a home screen icon on the phone, which fires an intent on the phone which launches my app in the background to execute various macros.
I want to extend this functionality to Android Wear devices, i.e.
1) on the phone, the user would press a button which would programmatically create an icon on the Android Wear device (e.g. in Wear Mini Launcher), which would have an intent associated with it.
2) when the icon was pressed on the Wear device, it would fire the intent on the phone to launch the main app on the phone in the background which would then execute on the phone.
Is this even possible? I would like to avoid having to write a specific app for the Wear device if possible.
Any suggestions welcome, or code snippets would be even better! Thanks.
Andrew
You can do some of what you want, I'll break it down into your separate questions.
1) You would create a mobile and wear app, when the mobile app is installed it will install the wear app as well. There's no way to install them otherwise.
2) On the mobile app you could create a wearable listener service that would respond to messages from the wear app. On the wear app when you do your initial launch of your activity you could send a message to the listener service via the wear messaging api and the finish. Within the mobile wearable listener service upon receiving the message you would launch your intent.
Here's a pretty good example of how to do this -
Wear Messaging API example
I use NFC to send text records from my app on device Nr.1 to my app on device Nr.2. Then the device is in touch, on both devices popup "touch to beam" UI. If I touch and beam message on device Nr.1 (sending part ot the pair) - message sent, everything working is just fine. But if I touch "touch to beam" UI on device Nr.2 (which should receive message) - then my app on device Nr. 1 is reloaded. Logcat is show nothing wrong, no errors. Seems, is that case app get some kind of empty NFC message? But why it's just do nothing on that? Why reload? I'm using ForegroundDispatch, create "text/plain" filters programatically, without manifest.
How I can handle this situation, then the users press wrong side of "touch to beam" UI??
If you do not set up Android Beam in your app, Android's default behavior upon beaming is to instruct the other device to either open that same app (first activity that filters for MAIN/LAUNCHER intents of an app with the same package name as the app on the source device), or if your app is not installed, open the Play Store listing. This is done by sending an AAR (+ a Play Store link?) over Beam.
So in your case, clicking the Beam UI on device 2 causes the AAR to be sent to device 1. As a result, your app will be (re-)opened on device 1. In order to overcome this, you can do the following:
Enable foreground dispatch for the activity on device 1, so that the received NDEF message is immediately processed by your app. I'm not sure if this collides with the Beam UI though.
Change the NDEF message sent by device 2 to something that does not contain an AAR using the Beam API.
How to write an application that turn off/disable NFC programmatically when I close my application or when my application is idle?
If you really have to turn NFC off, use NfcAdapter.disable();.
However, you won't be able to use disable() API if your app is not system application which is build together with the platform.
Alternatively, you may show a notice (a dialog?) to the user and ask her if she wants to turn off the NFC. If user agrees, you can redirect her to global Settings UI using following Intent:
startActivity(new Intent("android.settings.NFC_SETTINGS"));
I'm writing a handful of NFC-capable apps for work.
I've got two of them on my tablet right now, and they are set to launch if an NFC tag is detected and they're not already open. So since I have two of them on the same device now I get an App Picker dialog. This is great.
What I would like is to make it so that if one of the apps is already open, that when the NFC tag is detected it doesn't show the app picker, but just uses the current activity to handle the NFC intent. How possible is this? Thanks
If the foreground activity is using enableForegroundDispatch(), it will take precedence over anything else registered in the manifest for the tag.
Here is a sample app that demonstrates the use of enableForegroundDispatch(), to write text shared from another app (e.g., URL from the Browser) to an NFC tag.
I want to create an app or background service that just listens for the launch of a 'default' app, say Contacts or the built-in Gmail app. If the contact app is clicked, I want to transfer control to my app temporarily (e.g. present a Yes/No popup to the user or increment an internal counter of my app ) and then redirect the user back to the app that was clicked. I want to do this only for a couple of 'well-known' built-in default apps, not any third party apps.
Is this possible? May be using some special intents?
Have you tried registering broadcast receivers for the intents that would launch those built-in apps? This might not work since that might confuse Android into thinking your app is a potential target for those intents (e.g. that it should be used to actually write and send the email in the case of a 'compose an email' intent), but it should be a good place to start.