My app can be opened by NFC, and then use the information in the tag to do some processing, the processing is around 5 seconds.
If my app is opened by NFC, I don't want it shows on screen. So this is the onCreate.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(com.ab.R.layout.test);
Intent intent=getIntent();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
Log.v("nfc", "Start processing");
SystemClock.sleep(5000); // simulate the processing
Log.v("nfc", "End processing");
this.finish();
System.exit(0);
}
}
But it is not work, the app will shows on screen about 5 seconds.
Even I don't process anything
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
this.finish();
System.exit(0);
}
I still can see the app screen in very short time.
How to prevent the app to show the screen if I use NFC to run it?
In your manifest.xml you can specify set the following theme for your activity:
android:theme="#android:style/Theme.Translucent.NoTitleBar"
This makes your activity invisible (if it's empty).
If I am getting you right, you want to start some operations in the background as soon as the app gets started via NFC. The point is that, as soon as you actually start your app and the onCreate method of an activity gets called, your application will enter foreground and will become visible.
Assuming, you do not necessarily need to start an activity but some process in your application via NFC, the best solution is to outsource the code that should run without bringing the app into foreground into a BackgroundService. Set up a BroadcastReceiver onto the NFC-events you want to get informed about. As soon as it receives a notification, this receiver can then start your background service.
EDIT: grexter89 is right, I am sorry for my non-realizable hint. The intents provided by an NFC event can only be processed within an activity! Well, I am sure this is not the answer you want to here but I guess that this limitation is based upon some security/privacy issues. If the approach mentioned above was possible, NFC events could start processes without the consent and confirmation of the user as soon as the user, maybe accidentally, gets into contact with an NFC field. This is the use case you would like to use for your application but, however, these circumstances could be easily misused.
Regarding these points you should rethink if you actually want your activity to be invisible. Given the activity-only-limitation from Google and the above reasons (=> activation by accident, lack of user awareness) I would implement an approach with a visible Activity that shortly displays a hint to the user.
Put the line setContentView(com.airbutton.R.layout.test); inside an IF to validate if you should display it or not. Remember that activities can exist without an UI.
Related
I have a bug in my app which I thought I knew how to resolve, but now I've thought more about what is happening I'm not sure I do know the fix.
My app receives an incoming intent from a calling third party app as a string. That string can be sent as a SEND intent or a VIEW intent.
All of that works fine unless the app is already running...
This is what is happening:
My app is not running (not listed in the running apps view)
Share is clicked in another (third party) app and my app is selected to receive the shared text (text1).
My app opens and the text is displayed (and processed) as expected.
The user switches back to the third party app and shares some different text (text2) and my app is selected to receive this new text.
My app opens, but the original text (text1) is still displayed.
At this point I thought that the bug was because I am reading the intent in onCreate() and then displaying and processing it. My thinking was that as the app is already running onCreate() is not being called when the app is shown the second time as we jump into the lifecycle at onResume().
However, if I continue the test as follows:
Without exiting my app the user switches back to the third party app again and again shares the same piece of second text (text2) with my app.
My app is displayed again but this time correctly shows and processes the second text.
How can this be, as the app is still running, surely onCreate() is still not going to be called!
I thought that the fix was going to be simply to move the getIntent() call into onResume() (or onStart() ?) But now I'm not sure about this. Is this right thing to do?
The core of the issue is the fact that your Activity is already on top of the activity stack when the second Intent is being fired.
The launch mode will matter here.
What you can do is, set the launchMode to singleTop, and then get the intent in onNewIntent() method.
That is a good way of handling such scenarios. Please read the link above and it will make things very clear.
I'm currently plugging away at my first Android app, and I've run into a hitch. I have a main activity that will launch a service, and every time the screen turns on, it's supposed to make a toast. The only problem is that I've never used a Service before, and I don't know how to make it interact with my Activity, ie: the toast will be a user-defined string.
I'm not asking for anyone to write it for me, I just need some help being pointed in the right direction.
In case the above wasn't clear, basically, I want a service that will start when the main activity says start, then make a toast every time something happens (like the screen turning on or the phone being unlocked), and also stop only when the user presses stop.
Thanks for your help!
Look at BroadcastReceiver it will pick up system notifications if you register it in the androidmanifest.xml with IntentFilters. You can then use it to start a Service or an Activity with a PendingIntent
I want to create a password-protected android application. The password should be asked when the task is started or when it comes to foreground.
The complex part is that my app can invoke device inbuilt camera application to capture photo/video, so I cannot control that activity.
So the behavior should be that whenever user starts/returns to my app then password should be asked except for the scenario when he is returning from camera that I sent him to in the first place.
I have thought following ideas, but none of them solve my problem completely, the best one I could think of is
1) Set a flag(flagA) while sending the user to camera, then in a service keep checking that the foreground app is our app. When the foreground app is not our app then set another flag(flagB) to indicate that our app has gone to background. When the app in foreground is our app again, then check if flagA is false (we didnt send him to camera) and flagB is true (app is coming from background). Then show the password screen
Problems
1) The polling interval must be small like 3-4 seconds, so that foreground is detected quickly. This drains the battery.
Thanks
A few ideas come to mind.
This is just a quick idea of mine so it might not be useful but considering you haven't told us what you've already tried / have in mind we don't have a lot to go with.
You'll need at least 2 Activities to handle the whole password idea.
Firstly, when you start the app, run Activity A. This will ask for the password (assuming the password is always the same). If the password is correct -> start an intent with Activity B.
If the password is incorrect, close the app.
In B, give the user the option to invoke the camera. After using the camera, return to Activity B.
It doesn't get much better with the amount of info you've given us, but it should give you an idea on how to start.
I have solved the problem partially
1) Have a static long variable to track the time between onPause() and onResume(). During normal app operation this time is under 1 second, but if app goes to background and comes to foreground then this duration is more than 1 second. So in onResume() if the duration is more than 1 second then show the Password screen.
2) To handle the camera problem I am having a flag to detect whether I opened the camera, if that flag is set then dont ask for password in onResume().
This solution is not fool proof but works in most scenarios.
I want to write an app to send an sms from a shortcut on a home screen. That is all.
I just can't understand within the framework how I can write such an app. Here's what I've tried so far and what my ideas are:
I wrote an activity that sends an sms using SmsManager within the onCreate() however, this just keeps on sending messages even though the code is not in a loop. I realise I must be not be using an activity the way it's designed to be used. The android application fundamentals article says an activity is for displaying a screen or gui, but I don't need a gui. I just don't know what component I need to to use.
A service? no, because I don't need something running forever in the background.
An activity? I guess no because I don't need a gui.
I had an idea to create a broadcast receiver which would respond to a broadcast, so my sens smsm code would be in there ready to send when it receives the signal. But how do i send the signal from an app shortcut on the home screen? What would be the entry point of the app.
I'm just really confused, I've read the tutorials and the app fundamentals and searched forums and not found the answer. There's is just a big gap in my knowledge of the android framework that needs filling I guess, once it clicks I'll be fine but I'm just stuck right now.
Thanks people.
Service does not have to run forever. You can control how long it works in the background, you can even create Service that will shoot once and disappear. Suggestion:
from your shortcut (app icon) start Activity. That will be activity with translucent background. To achieve that skip line setContentView() and define theme
#android:style/Theme.Translucent
in your AndroidManifest.xml. This way you will avoid black screen flash at Activity startup.
from that Activity start Service and call finish() on that Activity
perform SMS sending (you already know how) from Service. Maybe, you do not even need Service, you can send SMS from the translucent Activity.
call stopSelf() from your Service immediatelly or after some short timeout (wait for SMS sending result).
All described can be done smoothly through Widget framework. In that case you can even have custom button user may press on. So, that would be another approach.
I am running into a critical conflict of sorts. My app is a remote service which essentially starts an activity when the screen goes to sleep. How it does this is very simple via screen off broadcast receiver and then an explicit intent to start the activity as a new task. The activity is basically in charge of responding to key events and displaying some simple text.
Thanks to a few window flags added in 2.0, activities can do this. They can be created in a way that either puts them on top of the lockscreen, or completely dismiss the lockscreen. This way they basically have focus without the lockscreen having to be dismissed by user. The alarm clock in 2.0 uses the flags to wake up the device and show the alarm dialog. I use them to place my activity when the screen sleeps so the user sees a custom wakeup lockscreen. The reason we create it at screen off is to get rid of lag the user experiences at wakeup involving first seeing the lockscreen, then seeing the activity appear. Also doing it immediately at sleep allows it to have focus so it can handle key events effectively.
The process works perfectly except in certain apps. So far, it seems the bug is consistent while browser (and even dolphin browser) as well as the facebook app are running. The bug never happens in GTalk or Launcher. It is rare but can still be duplicated in the messaging app every so often. I can't figure out why my activity doesn't get created at sleep while these apps are active. My remote service still gets the screen off broadcast and does the startActivity for the explicit intent, and that's all I get in the log. My onCreate is not being called. Instead it gets called when we wake the screen up again.
I have tried, as a control, to hold the partial wakelock starting when my remote service gets created, and the issue persists. So I don't believe it is a problem that the CPU has gone to sleep. Since only these particular apps cause the issue to duplicate, I can't imagine why the activity start fails. What could those apps be doing to interfere with another app's ability to get created? I use singleInstance as the launch mode so that I can ensure that the activity will never be able to be recalled by user process. I want it to go away when user unlocks and it is working fine like this, as long as it is able to be created. The singleInstance ensures I can have the same lockscreen handle an intent to do something specific based on user actions that the remote service monitors.
my source code can be viewed on my project page. http://code.google.com/p/mylockforandroid/source/browse/#svn/trunk/myLock/src/i4nc4mp/myLock
the issue happens to both my CustomLockService and NoLockService variations. These two services will start Lockscreen or ShowWhenLockedActivity and the bug is witnessed. The build illustrating the bug's end result-- user has to try to unlock 3 times due to the bug because on wakeup when the oncreate finally succeeds, user is seeing the activity when normally it would have auto-dismissed thanks to key event logic that also isn't seeming to happen due to the delayed onCreate, so they have to send it to sleep again. Now that the activity is properly done being started, and screen is asleep, the expected functionality happens at next wakeup-- can be downloaded also from the downloads tab.
This seems like an extremely irrational thing to be caused only by specific apps. I am quite baffled and out of ideas for a solution unless I've made some critical mistake in my activity definitions.
The answer is actually a bug in android that has been in review for a while. It has to do with the home key. For some reason start activity calls as new tasks are getting stopped after the home key has recently been launched. I never noticed the connection during the testing of this. The bug was not consistent and the factor of consistency was whether home button had been used during the wake in question
Here is the bug report: http://code.google.com/p/android/issues/detail?id=4536