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.
Related
We are using intents to switch from one of our apps to another on request, typically a button that is pressed. That way our apps present themselves as a functional unit to the user. We switch back by means of results we hand back.
Recently we implemented a switch that is not triggered by an immediate user interaction, but by an implicit event. When navigating inside one app we use an activity from another app as a drop-in-replacement for some feature in the first app. So the first app sends the user to the second app if it detects that second app is installed.
I realize we have an issue here: if that second app is buggy, crashes, then the first app is broken. Since it switches to the second back again and again without the user being able to alter that behavior. So apparently it makes sense to enable the first app to realize that the second app just crashed. So that it would not switch over next time, although that second app is indeed installed.
This does not work out of the box, since the first app never is informed about the crash of the second app. Instead that app crashes, the OS hint comes app ("Unfortunately XY just crshed") and that's it. The flow never returns to the first app, so there is no return value to evaluate or similar.
So my question is: how can I enable the first app to learn about the fact that the second app just crashed?
I thought about registering a global handler for uncaught exceptions in the second app. That handler would have to somehow signal to the first app that it is currently crashing. Either by sending a specific intent itself (sounds ugly) or by handing back a result (is that possible at all?).
Is there a common practice for this? What is it? What other options exist? Or is that question itself obsolete, since I only failed to see how this is meant to be done?
UPDATE:
Interesting enough I learend that this actually works if the crash in that second app is raised not upon startup but much later ... In that case indeed the first app is in foreground again and is indeed able to detect the crash: the result is "CANCELED" in that case, which is perfectly fine for me.
The the question is reduced to "early crashes" and how this can be handled. Or, the other way round: what is the difference between early and later crashes in that second app?
You technically can't detect that the app crashed, but you can keep something like a "failure counter" in your 1st app. Basically, every time you're about to launch app #2, save a variable in SharedPreferences, something like launchAttempts. You'll want to increment it every time right before you launch app #2, and then decrement it in your onActivityResult() when a result is returned. Then you can set a threshold for how many failed attempts would qualify for "too many", and stop launching app #2
I have an app for the SW2 that has a user option for whether the app should use low-power mode (LPM). Which works fine. The problem is that the SW API only calls my app's supportsLowPowerMode() registration method once, when it first starts up. Meaning that if the user later changes the setting in my app, it won't take effect until the whole shebang restarts.
I've tried a few tricks (like killing my app's process) to force a reload, but nothing's worked so far. My last resort is telling the user that s/he needs to reboot the phone before this takes effect, but that's pretty hokey. Is there a better way?
The solution is not to try to change your response to supportsLowPowerMode() at runtime, but to start and stop your extension instead.
Basically, if your extension can ever support LPM, then it should be returning a value of true in supportsLowPowerMode(). If the extension's LPM usage can change, you handle that by simply doing different things in the onActiveLowPowerModeChange() handler. Specifically, if the user has chosen NOT to use LPM, you want a handler that looks like this:
#Override
public void onActiveLowPowerModeChange(boolean lowPowerModeOn) {
super.onActiveLowPowerModeChange(lowPowerModeOn);
if (lowPowerModeOn) {
// User doesn't want to use LPM, so stop the app on the SW
stopRequest();
}
}
This has the effect of shutting down your extension when the device's backlight turns off, and it'll drop back to its default LPM watchface.
EDIT: I'm reopening this as I've found an unacceptable side effect to the above technique. If your app returns false to supportsLowPowerMode(), the SW2 will keep it running (but paused) in the background when the watch goes to sleep. This means that, when the user "wakes up" the SW2, your app will immediately reappear on screen. Calling stopRequest() (as in my code sample above) disrupts this behavior, requiring the user to reopen your app after awakening the SW2. I've not found any way around this; what's needed is a pauseRequest() instead, but the API doesn't have one.
As far as I know there is no way to change this at runtime. Let me double check with my team though just in case there is a way I don't know about.
I was just bored of iOS and I recently changed to Android. I have a Nexus 5 device, and I've just finished installing my favourite apps in my device.
One of those apps is Line, the famous communication app from naver. I installed it and I configured it with a passcode in order to secure access to it, so no one despite me could see the "confidential" conversations inside.
The problem is even if I have the passcode enabled on line, if someone presses the "Recent list applications" button, they can see perfectly a screenshot of Line with my last conversation, so anyone could see what I was doing in Line.
I made the same test on iPhone and .. surprise ... iOS is taking the snapshot AFTER the passcode screen is enabled, so anyone could see nothing. It seems that in Android the snapshot is taken BEFORE passcode screen is enabled so anyone could see what last line screen looks like :)
So, having read other threads on this forums, I'm supposed to have several ways to solve this:
Wait for LINE's company NAVER to add an option to prevent this app to show on recent app list (adding android:excludeFromRecents="true" on THEIR manifest) [that won't be soon]
Wait for LINE's company NAVER to force the snapshot after passcode screen is enabled [maybe soon but not in company'sroadmap]
Decompile apk and change manifest on my own - or use FLAG_SECURE - (I tried it but when I launch the new app it suddenly dies on startup with a message "Application stopped". I thing LINE's server verifies on startup that the client app is what is expected to be, comparing sizes or something else)
So I don't know more ways to get around this. Do you have any more idea? I'm stucked on it.
Thank you a lot.
Detect when LINE has left foreground
Create a background service that detects if LINE is on foreground and when it leaves the foreground. (https://stackoverflow.com/a/14044662/1683141)
When line has left foreground, you should take action:
A. Stop the line app completely
OR
B. Open & "close" the line app so it will show a locked state in the multitask thumbnail
A possible way to accomplish situation B:
Optionally: detect which app the user has now opened and remember it
Wait a few seconds and open the LINE app again after the user closed it (by intent for example)
Now the LINE app will show the lock screen
Now let the background service open the home screen (or make an intent to the remembered activity)
Now the LINE app is back to the background and it will have a multitask-thumbnail showing the locked screen.
Ofcourse, this will create a loop, and this isn't a stable solution
-Option A is a relatively reliable, and a (in my opinion) good way to accomplish what you want: no one can see your secure chat. Disadvantage is that the application is now removed from multitasking.
-Option B is only an idea, but maybe, if it's done the right way, It could work.
Edit: Option A will not work. The application will not be removed from multitasking if the task is killed.
I have developed one app in which there is option for sharing on twitter.Its working properly fine.Now one requirement came which says that if the app is force killed it should again ask for authentication with twitter so that we can give user id and password again.The main thing is if user want to login to twitter with his new credentials how he will do that.Any idea how to solve this issue.Right now if i am uninstalling the app or clearing the data it is doing authentication but it should do on force killing the app.
You can't detect your app being force killed: https://groups.google.com/forum/?fromgroups#!topic/android-developers/xfkfRc-j4cw
It might be possible to set a flag when your app starts, and clear the flag when your app stops in an orderly way. If the flag is set when your app is starting, then you know it was last stopped in a disorderly way, like being force killed. This method of detection will probably give you both false positives (if someone pulls the battery out of their phone, your flag will probably still be set) and false negatives (if your app considers itself to have been stopped in an orderly way, and is then force killed). This method will surely give you angst and tears unto the fifth generation. Here be dragons, and the dragons will eat you.
You should push back against the requirement.
For your problem, you can clear your tokens when the app starts again, in an onStart(); method for example. So next time the user will use the application after the forced kill, this last wouldn't get any access tokens to work properly and would be consequently "forced" to ask tokens again via a classic OAuth Authentication Flow.
Reauthentications are just like classic authentications. At the end, the Twitter API will give you back the missed (or deleted) access tokens.
I'm having a bit of an issue with interaction beween my app and other apps on my phone, but I'm starting to think that maybe it's working as designed? Anyway, here's the problem.
My App, call it App A is a photo-manipulation app. So a user goes in, plays around to make changes and then uses the Share button to pass it on (SEND Intent). The photo is sent to another app, chosen from the Share menu, call it App B. This stand-alone app has its own menus, completely different look and feel, etc. The user does his thing in this app for a bit, then hits the home button and goes his way to do something else.
Sometime later, he decides he wants to run my app again. He goes into the launcher, hits the icon for App A (my app), and up pops App B. Very confusing. If he happens to remember that last time he ran App A, he used the share button to get into App B, maybe he'll think to use the back button, to get back into App A. If he doesn't remember, all he knows is that he is trying to use App A, but Android is giving him App B.
(I have one app on my phone that takes over the back button for its own use so you more-or-less get stuck in App B with no way out. Ugh. You hit the icon for App A and always end up in App B)
Is there any solution to this, or is it working as designed? None of my onCreate, OnResume, onStart, etc. methods get called when this is second-open is occurring, so I can't trap it. And realistically, I can see the desire for this behavior when timelines are short - i.e. hit the home button, quickly use some other tool, and then go back to what you were doing. But with a timeline any longer than a minute or two, it gets very confusing.
Anybody else dealing with this problem? Is there a basic Android architectural issue here? Is the SEND intent being mis-used by being accepted by stand-alone apps instead of small utilities?
I think you may use Intent flag 'FLAG_ACTIVITY_NO_HISTORY'. It means starting intent never goes into activity stack.