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
Related
If I set a timer in the default Android clock app, then it has the following behavior when the time runs out:
If the phone is unlocked, a pop-up comes up allowing you to stop the alarm or navigate back to the app.
If the phone is locked (including if the screen is off), the screen turns on and you're taken to a special Activity to stop the alarm.
What is the best way to reproduce both of these behaviors in my own app? I've been copy-pasting various magical incantations involving AlarmManager for the second, but nothing is working. None of the questions that have come up when Googling things like "bring Activity to front" or "wake up phone" seem to be what I need.
This can't be done, and it's by design. There are 2 separate problems, and they're both impossible to implement.
Google has progressively disabled the ability to launch activities without user interaction in all recent API versions. They also disabled "springboard" behavior, where background services and/or receivers try to start activities from the background. You're supposed to use notifications to let the user know what you're trying to do, and when they interact with that notification, then your activity can be launched
There is absolutely no app, unless you have a custom ROM or a rooted phone, that can bypass the lock screen. It's a security issue, and the idea is the same as in the previous case -- you need to notify the user, and if they interact with the notification, they can be prompted to unlock their phone and your activity will launch
Simple put: I want the app to relaunch (yes, from the launch activity, like if the user just tapped the icon button) every time Android kills my task because of lacking resources reasons.
The reason is that instead of managing everything that could possible go wrong after the app came back "from the dead", like NPEs, I want to start all over from the beginning.
I've searched for a "good practice" solution, but nothing came across.
Any ideas?
EDIT: I don't want to force the app back to foreground. However, if the user do it, I mean he brings it back to fore by his own free will, if Android killed my app because of resources purposes, I want the app to relaunch.
Sorry for not being clear previously.
Bringing your app to the foreground when it hasn't been explicitly opened by the user is considered a bad practice and discouraged. In fact, it won't be allowed in Android Q, except in a few cases:
Android Q places restrictions on when apps can start activities. This
behavior change helps minimize interruptions for the user and keeps
the user more in control of what's shown on their screen. In
particular, apps running on Android Q can start activities only when
one or more of the following conditions are met:
The app has a visible window, such as an activity in the foreground.
A different app that's in the foreground sends a PendingIntent belonging to the app. Examples include a Custom Tabs provider sending
a menu item pending intent.
The system sends a PendingIntent that belongs to the app, such as tapping on a notification. Only pending intents where the app is
expected to launch a UI are exempt.
The system sends a broadcast, such as SECRET_CODE_ACTION, to the app. Only specific broadcasts where the app is expected the launch a
UI are exempt.
Therefore, I would definitely recommend you to discard the idea.
I'm trying to start an app upon the first boot of the device before the keyguard appears. I need to ensure the first thing the user sees after the boot animation (which I've also changed) is this app. My app is just three screens of text in fullscreen mode with a next button in between them.
I realize that for most cases, this would be a terrible user experience. However, the phones we're shipping have a very specific purpose and because of this I need to meet the following criteria:
my app needs to be the first thing the user sees (after the boot animation of course) when they take the phone out of the box and power it on for the first time.
after the first boot, the phone should function as normal (i.e the keyguard should appear upon bootup instead of my app).
this only needs to work for lollipop since that's the android version we're shipping.
I can modify the Android framework if needed, but a solution where I don't have to is preferred.
My (Failed) Approach
Create an app that starts upon boot. Have the app dismiss the keyguard as the first thing it does.
The problem I found with this approach is the keyguard code is called before the app initialization code so the user sees the keyguard briefly and then sees my app.
A Possible Solution
I think the best way to do this is to add code in the framework to call my app before calling the keyguard. I'm imagining having a boolean that's used to keep track of whether it's the first time the device is powered on. If that boolean is true, open the app. If not, open the keyguard.
The problem is there's a lot of code in the android userspace boot process and I have a quickly-approaching deadline (don't we all?). How can I modify the framework code to show my app before the keyguard?
If there's a better way, please let me know that too!
i made a sample android app,which starts a started service by calling startService(serviceintent).
it works fine,but if i forceQuit my application from settings>app>downloaded>force_Quit.my service stops and even destroyed is not called.
i studied for 3-4 days and know about start_sticky in StartOnCommand method.i am able to achieve all aspects of service.
I want to know whatever i am achieving that service stops and doesnot restart automatically even if started as Start_Sticky is normal behaviour according to android.Can i make it restared if user force quit my application.
my manifest is correct i uses process tag also.
if i forceQuit my application from settings>app>downloaded>force_Quit.my service stops and even destroyed is not called.
Correct.
Can i make it restared if user force quit my application.
No. Nothing of your app will run again until something uses an explicit Intent to start one of your components. Usually, that means that the user taps on your icon in the home screen launcher, though there are other explicit-Intent scenarios (e.g., GCM message).
I am not satisfied with any of the app locker programs for Android that I have found and would like to create my own, but I am having trouble figuring out how to implement the actual lock. How does one go about implementing an app locker for Android?
There are two issues:
Detecting an Intent, usually from the launcher calling startActivity() or from an ad launching the market app (I'm not talking about broadcast intents -- I need to handle explicit Activity Intents).
The permissions for the locker apps I have seen all have "read system log files" and/or "retrieve running applications" which suggests they might use polling to look for app launches. I think I could do this, but I would like to find a better solution if possible.
Preventing the locked app from processing the Intent. I would prefer not to allow the locked app to run at all until the passcode is entered since it is impossible to tell what it might do when it starts up.
When running my current app locker, logcat shows "ActivityManager: Starting activity" first with the Intent for the locked app, then again with the Intent for the app locker, with nothing in between (separated by 10-20ms). If I enter the correct passcode then I see "ActivityManager: moveTaskToBack".
I have experimented with a test app which demonstrates that, using my current app locker, none of the Activity callbacks are invoked if the app is locked and I do not enter the correct passcode. So it appears to be preventing the app from starting (but I don't know how).
I could use ActivityManager.killBackgroundProcesses() to stop an app, but I have no guarantee that the app hasn't already started running by the time it gets "killed".
I might be able to use PackageManager.setApplicationEnabledSetting() to prevent an app from being instantiated, but I don't think that will take care of apps that are already running (which shouldn't be allowed to process new Intents or come to the foreground). I might be able to use killBackgroundProcesses() to stop all running locked processes so they would have to be re-instantiated. But I don't like this approach because other apps could mess with the Enabled settings and defeat the lock.
Optimally, the system would send every Intent to my app for inspection and allow me to stop or let it pass through, but I'm pretty sure that's not possible (at least, not for explicit intents to start activities from a launcher).
Does anyone know how app locker apps are implemented, or have any bright ideas on how it could be done?
I would look into the lifecycle. Once the app in question begins to load, some activity from that package will be added to the forefront activity.
A scan of the changes in forefront activities might do the trick.
http://developer.android.com/reference/android/app/Activity.html#ProcessLifecycle