I am working on an alarm feature for my application where, at a certain time, an alarm Activity is started, which subsequently starts either a vibration or a ringtone. The problem I've run into is that the vibration or ringtone is not stopped if the user presses the Home button.
I have overriden onKeyDown so that the alarm is stopped when a button is pressed, but that does not intercept the Home button code:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (mVibrator != null)
mVibrator.cancel();
if (mPlayer != null) {
mPlayer.stop();
mPlayer.release();
}
return super.onKeyDown(keyCode, event);
}
How can I go about stopping the vibration/ringtone when this occurs?
I'd suggest stopping the alarm in onPause(). That gets called whenever another application comes to the foreground (including the home screen).
you can't intercept the home button - it's there for the reason that any app should allow the user to press home to immediately go to the home screen. you should consider stopping the alarm in your onStop() if you want the same effect.
the Home key event is intercepted by the framework and is not passed to the application layer,so you can't monitor this event.
my solution is that you can start a dummy activity (no status bar, no title bar, with a transparent background, so it looks like that there is no activity running).
within that activity , override the onPause() method to stop ringing or vibration. so when user press the home key , it would be called.
Just my idea. possibly there are better ideas.
Related
I've an app which on a home button press it performs a certain action, most of the time the press is detected and the action is successfully performed.
But sometimes the press is not detected for no apparent reason. The press is detected via this receiver:
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
[...]
if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
mListener.onHomePressed();
[...]
}
}
}
}
}
Why could such a thing happen? Is there any way so if it gets pressed it always fires that onReceive?
Why could such a thing happen?
You will not receive that broadcast if your app is in the background and you registered the receiver via registerReceiver(). Also, I do not know if there is a requirement for all devices to send that broadcast. Plus, there are devices that do not have a HOME button (e.g., Chrome OS).
Is there any way so if it gets pressed it always fires that onReceive?
Not that I am aware of.
I would focus far more on removing this functionality. Your app is more likely to be compatible with more devices that way.
I'm currently developing an app that requires the Android's location service to always be active.
Right now I'm able to detect if the user activates or deactivates the location service when he resumes the app (in the onResume() event ).
The problem is that, if the user deactivates the location service throught the quick settings menu, I am not able to detect the event.
How can I know when the user activates / deactivates the device's location through the quick settings?
Thank you.
My code:
...
BroadcastReceiver mGpsSwitchStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() != null && intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
// Make an action or refresh an already managed state.
Log.d("vtApp", "CHANGED");
}
}
};
currentActivity.registerReceiver(mGpsSwitchStateReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));
References I followed:
How to trigger broadcast receiver when gps is turn on/off?
Android Quick Settings notifications?
Changing Location Settings
I had the same problem.
this worked for me
intentFilter.addAction(android.location.LocationManager.PROVIDERS_CHANGED_ACTION);
not to confuse it with
Intent.ACTION_PROVIDER_CHANGED
If I launch the app from the home screen (by taping the app icon), then I navigate through the app and then I leave the app, when I reopen the app the same way (by taping the app icon from the home screen) it will resume the previous state and show the last activity I was on before leaving the app.
That part works as expected.
Here is the issue:
If I first launch the app from the play store or manually from the apk installer, and then reopen the app another way (by taping the app icon from the home screen for instance), the app will start a new instance of the main activity and will add it the previous navigation stack (If I press the back button it will go back to the last activity I was on before leaving the app).
I always want the app to open the last activity from background, no matter how the app was first launched (via the home screen or the play store or manually).
I already tried stuff like that in the main activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!isTaskRoot()
&& getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
&& getIntent().getAction() != null
&& getIntent().getAction().equals(Intent.ACTION_MAIN)) {
finish();
return;
}
[...]
}
but the finish() call crashes the app.
I actually found why finish() crashed the app: onDestroy() was called and it tried to unregister a receiver that was not registered yet, so the app crashed: Unable to destroy activity [...] Receiver not registered.
So that code actually works fine for my issue:
if (!isTaskRoot()
&& getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
&& getIntent().getAction() != null
&& getIntent().getAction().equals(Intent.ACTION_MAIN)) {
finish();
return;
}
I just didn't pay attention to onDestroy()
I know for an activity you can override onStart on onStop methods to know when an activity starts / exits. The issue I'm running into is I want to keep a session open from when a user opens the app until it enters the background / user exits and tying into onStop (for end session) for each activity isn't giving the the results I want, it ends the session every new activity. So I was wondering what are my options for knowing when a user puts the app in the background or exits.
One thing I thought of is keeping track of onStart and onStop (or any two combinations in the activity life cycle) so I know if I have a onStop without a onStart right before the app is exiting. This seems very hacky, not sure if its the right place to start.
Thanks for any input.
You can extend Application class and use registerActivityLifecycleCallbacks to build the logic.
Using for example these two callbacks:
#Override
public void onActivityResumed(Activity activity) {
mBackground = false;
}
#Override
public void onActivityPaused(Activity activity) {
mBackground = true;
}
https://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks)
I have a app which i want the back button to not close my app. So from research, I tried following 2 methods separately:
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Back?
if (keyCode == KeyEvent.KEYCODE_BACK) {
// Back
moveTaskToBack(true);
return true;
} else {
// Return
return super.onKeyDown(keyCode, event);
}
}
and
#Override
public void onBackPressed() {
moveTaskToBack(true);
}
Both methods seem to work on my Nexus 6 which has soft back button (back button is on the screen itself).
However when I had my friend Beta test the app on his One plus 1 device which has hard back buttons, on his phone it closes the app completely. So when he goes back to app, the app launches from scratch.
I have 2 questions:
How can I prevent hard back button from closing the app? Do I need to add some extra code for hard back button handling?
Is there someway I can test hard back button with simulator as I don't have a device with hard back button.
Thanks!