The issue I'm trying to solve is as follows:
An NFC tag will trigger my app, from which I'm launching another app. What sometimes will happen is that the NFC tag will move and will be "re discovered" by the phone and launch my app once again. The moving of the NFC tag is something I can't control.
This really ruins the experience.
What I would ideally like to do is once my app is launched, NFC triggering will be disabled or paused, and once app is closed (OnDestroy()) I will enable / un-pause NFC functionality.
I couldn't find how this could be done and your help would be really appreciated. If you have another (code related) approach on how this can be solved, this is just as good.
I noticed this post from a couple years back : NFC disable adapter
But I hope there is another solution, being a system application is not an option and prompting the user the disable NFC is just as bad...
Thanks in advance.
You can create an activity-alias that handles the intent, disable it while your activity is running and re-enable it when it is destroyed.
You're assuming that you can saftely turn off an important functionality of the phone, and disable any other service and/or app that is dependant on it.
This is of course wrong. You should only make assumptions regarding your own app.
So what you're really trying to do is to disable the re-launch. This can be done in many ways:
Control your main Activity's launch mode, and thus your entire app's.
Handle the NFC intent correctly, via a Service that monitors the NFC state as well as your app's. As per #Michael's remark - since you can only associate an NFC intent with an Activity - you would have to create a non-ui Activity (one that does not call setContentView) to act as a BroadcastListener for this Service.
Tag your app, as suggested by #Tristan.
Related
Background
I included Navigation Component in my app which basically means that I have a single Navigation Activity and multiple Fragments that display my Views and Data. The app has the ability to read NFC Tags from ID Cards.
I followed the implementation guide of Android Developers to include the capability of NFC Tag reading and in their example they edit the Activity in the AndroidManifest and enable the ForegroundDispatcher in their Activity. Since I only have a single Activity basically anywhere in my App the NFC Capability is available.
I'm using setIntent(intent) to delegate the incoming Intents to my Fragments. Only the Fragment that is supposed to work with NFC handles the Intent while the others just ignore it.
The Problem
The problem is that when I hold a NFC card close to the phone the phone starts to vibrate since it recognized a NFC device. This happens in every Fragment and is unwanted behavior.
Question
What can i do about this or am I stuck with this behavior? I read a bit about enabling the foregroundDispatcher in a Fragment but the answer was almost always to handle it in my Activity and the function also demands an Activity.
Don't use ForegroundDispatcher (unless you really need to do NFC before API 19) use the newer and better enableReaderMode method instead.
The Sound is generated by the system NFC App and with enableForegroundDispatch you have no control of the sound plus enableForegroundDispatch has a bad side effect of pausing your App to read the NFC Tag and can be unreliable at times especially if writing to the NFC Tag.
With enableReaderMode you get to control whether the system NFC App makes a sound or not with the FLAG_READER_NO_PLATFORM_SOUNDS flag.
So your design will have to change a bit as the onTagDiscovered method is called in another Thread in your application when a NFC Tag is discovered, that thread has to then communicate the data to the Fragment (as it cannot interact with the UI thread directly). One possible method to do this is the onTagDiscovered method in the Activity sets a value in a shared view model and then the Fragment that is interested in it "Observes" this value for change and reacts according including making a sound and vibrate itself.
Full example of enableReaderMode is at https://stackoverflow.com/a/64921434/2373819
Note only enabling ForeGroundDispatch NFC in a Fragment is a bad idea, as it is likely the System NFC App will still make a sound anyway when a NFC Tag is presented and because your App might not be handling the event because the Fragment is not running then system NFC App might also show it's own screen over your App as well.
I have a device management application, which essentially runs as a service in the background from boot. I'd like to start this application immediately after installation. How do I achieve this?
You cannot do this -- there is no way to automatically start your service merely because it was installed.
The application must first be invoked by the user through some sort of activity. Or, you are going to need to hook into some relevant broadcast Intent via the manifest, so you can get control when one of those events occur and kick off your service that way. Or, you are going to need to ask the user to reboot so your BOOT_COMPLETED Intent filter can get control.
There was a hole - the Android Analytics SDK used to send an intent right after installation - but that got closed (producing lots of confusion, of course).
But the final answer, I believe, is here:
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
This seems to suggest that, as of 3.1, Google made the decision that apps are in a stopped state until the user explicitly activates them, e.g. by launching app or placing widget.
This means that the strategy of listening of a common broadcast (i.e. to get your app launched surreptitiously) won't work either.
I need to read an NFC TAG which is fixed at the back of the phone periodically. The problem is that android will only trigger NFC intent the first time it detects the TAG. I think that any of this two possibilities could solve the problem, but don't know if android allows any of them
1- Force Android to read NFC TAG, but I don't know if it is possible, if it is, this would be the best solution, in that case, how could i do this?
2- Turn on NFC Adapter, when it turns on it will trigger NFC detection and my activity will consume that intent, but i think it is not possible to enable/disable NFC adapter programmatically without user interaction (I need it to be automatic, opening WIFI settings is not a possibility)
Thanks!!
Assuming your app is always in the foreground I would keep the initial Tag object in memory and periodically query the tag. If an exception is thrown when connect() is called then the tag has moved out of range.
Then set Tag object to null and listen for an intent being fired when the tag re-enters the phone's field.
It isn't possible to use Android's reader/writer mode when the screen is off or locked. Beside that there is an application that apparently can make this possible. Read this answer, it's an similar question.
We want to use Android mobile for dedicated application. Can somebody suggest how can we make it happen.
Here are the requirement:
The phone when started, should launch our application., so the user cannot launch any other application. The application will be a 1D barcode reader.
The application should be live as long as the phone is up and running, user cannot close the application at all.
Thanks for your help.
Regards,
Manish
Android after boot is complete sends a bradcast intent:
android.intent.action.BOOT_COMPLETED
if you listen for this intent, you can launch a service that in turn launch your activity.
In the Activity you have to take care of the user's interactions that explicitly close the activity, like home button, back button and camera button press.
Setting your activity to be full-screen also should prevent the user to use the notification bar to interact with notification like those from market-app that can close your activity.
Finally, your activity can be killed by the system by various and uncatchable reasons: in those cases, the service that first launched your Activity comes in handy, as it can periodically monitor the general state of the application and relaunch components as needed.
Check out the new Android Enterprise solutions for your use case.
https://developers.google.com/android/work/overview
Its well documented. You can either use
Android Management API to provision the devices and apply policies to the device which will be applied to the device using Android's Device Policy Controller (DPC) or,
Use Google Play EMM API and develop your custom DPC
It depends upon your use-case really, but the first solution set should serve your purpose
I'm afraid there's no single answer to this, but you need to work on multiple fronts.
One of these fronts is preventing user from running other applications: for this there are applications sold on Android Market that can put other apps of your choosing behind passcode.
You need to combine this with automatic launch, but I don't yet know how to do that.
I have a device management application, which essentially runs as a service in the background from boot. I'd like to start this application immediately after installation. How do I achieve this?
You cannot do this -- there is no way to automatically start your service merely because it was installed.
The application must first be invoked by the user through some sort of activity. Or, you are going to need to hook into some relevant broadcast Intent via the manifest, so you can get control when one of those events occur and kick off your service that way. Or, you are going to need to ask the user to reboot so your BOOT_COMPLETED Intent filter can get control.
There was a hole - the Android Analytics SDK used to send an intent right after installation - but that got closed (producing lots of confusion, of course).
But the final answer, I believe, is here:
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
This seems to suggest that, as of 3.1, Google made the decision that apps are in a stopped state until the user explicitly activates them, e.g. by launching app or placing widget.
This means that the strategy of listening of a common broadcast (i.e. to get your app launched surreptitiously) won't work either.