In one of my activities, I want my UI to be dimmed at all times. When the used presses a navigation button (back, home, recent apps) it should act like normal, but when focus is back to my activity, it should go back to lights-out. Currently, I have lights-out working, but after I press Recent Apps, the lights stay on forever.
How do I make my app always stay in lights-out?
Figured out something that worked.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
if (hasFocus) {
lightsOut();
}
}
}
Basically, every time my app gets focus, it forces lights out (possibly redundantly, but it doesn't really matter).
Works like a charm!
Related
I have an app where I animate some views on click.
However while the animation is going on it's still possible to initiate other on click events, which in the end cause multiple problems with the animations. I would need to make it so that no new animation starts while a certain one is going on.
Let's say the animation shuffles clickable views on screen. How do I make it so that the user can't initiate a new click command for x amount of time, where x could be the duration of the animation, or some other solution with similar results.
I'm just not even sure what I'm looking for when it comes to terminology. What areas should I look into to manipulate user inputs like this? Any good source on the topic would also be welcome.
You can always disable the click event with a flag and enable it again when the animation has finished. It isn't a perfect solution, but it does the trick quite well in most cases.
For example, if you are using an Animator for your animation, you can do something like this:
private boolean isClickEnabled = true;
...
#Override
public synchronized void onClick(View v) {
if (isClickEnabled) {
// We disable the click, which will be enabled again when the animation ends
isClickEnabled = false;
...
animator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
// We enable the click again now that the animation has finished
isClickEnabled = true;
}
});
animator.start();
}
}
The same applies for when you use the Animation class, but with the AnimationListener instead.
Please note that, instead of saving a local boolean, you could just disable and enable the click on the view using view.setClickable(true/false) – it really depends on what you need and on your implementation, but the basic idea remains the same.
if you want to block the touch for some time try to Implement Runnable or runonuithread and than whatever view you want to block use mathod called view.setClickable(false).
I created an android app. The screen never turns off:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Now I want to show a picture if the screen is not pressed for 5 minutes or something else. The app should not be closed, when pressing on the image the app should be open.
How can I realize that?
I would discourage you from taking this approach. Users expect to have a consistent user experience between various apps on their devices, and likely have a preference to how their device sleeps, either by having specified a sleep timeout or displaying a daydream as introduced in Android 4.2.
If you'd like to provide users with the option to display a screensaver associated with your app, I suggest including a Daydream in your app and otherwise acknowledging the user's preferences.
That being said, if you cannot use Daydream, you could observe if the app is being used or not. Two things come to mind:
Have the root view of your activity intercept touch events to observe if any of its children have been touched.
Observe the activity's onPause() and onResume() to acknowledge that the activity is still being displayed.
You could then invoke a Runnable by posting it to a view using postDelayed(Runnable action, long delayMillis), being wary to remove it when the activity is paused or the timer should be reset using removeCallbacks(Runnable).
I solved the problem!!!
I used that event:
public boolean dispatchTouchEvent(MotionEvent ev)
{
super.dispatchTouchEvent(ev);
// cancel my Timer
return true;
}
Thanks!!
I'm developing an android application and when I press the back button from my device (normal press time for a person, 1 second or less), it skips from my activity, to the previous activity (menu) and then exits the application.
But if I tap the back button quickly, it reacts as expected, it goes to the menu.
I've tried to find a solution but no success.
I've always tried to override the back button default behavior but no success either.
Is there a way to set a reaction time for the back button to react?
Many thanks in advance!
P.S.- I have other activities that maintains the expected behavior in back button when pressed with a normal press time.
"Is there a way to set a reaction time for the back button to react?"
Yes, you can simply record the time when the button is pressed and react differently in onBackPressed by calculating the (currentTime-lastTimePressed)
To allow this to work with previous activities, you can ask activities to startActivityForResult, so that when you finish your activity you can pass on the time as well to let them know if they should exit as well.
I was developing an extra option for an application that already exists, and I found out that I should extend not from the Activity from Android but an already extended Activity called SEActivity. So in this extended version of Activity they override the method onKeyDown like this:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
}
else
return super.onKeyDown(keyCode, event);
}
By extending this SEActivity, the Back button works with the expected behavior.
Thanks anyway :)
I have an application containing multiple activities.
At the moment the whole application contains about 8 activities. First I show a splash screen for a few seconds where all the preferences are loaded and set up (from sharedPreferences) - these are saved in a "Setting" class I made for this - this class basicly just have a bunch of static variables, so all activities in the app can read these and modify them as they need to.
EDIT: More data is getting stored in this class as the app runs, some of this is from a webservice - the data is parsed into obejcts and references to these obejcts are saved in the Settings class too (or a list of the objects).
My problem is then, that when users press the HOME key, the current activity is put in the background. If the activity is in the background for a long time (a lot of users "close" apps by pressing home instead of back), and then reopened it shows the activity that was running before HOME was pressed.
As an example - lets say the user starts the app, sees the Splash screen for a few seconds. The splash screen then starts a new activity and calls finish on itself.
This means that now the Activity stack is just the MainActivity (main menu). In the MainActivity I supply all the buttons with listeners in the onCreate method, and most buttons require some info from the Settings class mentioned above.
When I then press HOME and reopens the app a few hours later, none of the buttons works anymore - seems the graphic is reacting etc, but something still goes wrong. One of the buttons that should work even with all settings wiped will just open a dialog with some text in it.
The listener:
Button b = (Button)v.findViewById(R.id.id_b1);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Dialog dialog = createDialog(MainActivity.this, DIALOG_CONST1);
dialog.show();
}
});
I have some constantst for dialog types, as I'm using some custom designs for the dialogs I have created a class to created the dialogs for me.
From the activity containing the button (simplified a bit):
public static Dialog createDialog(final Context c, int dialogId) {
Dialog dialog = null;
CustomDialog.Builder customBuilder;
switch (dialogId) {
...
case d1:
customBuilder = new CustomDialog.Builder(c, DIALOG_CONST1);
//Sets up the parapters to create the dialog afterwards
customBuilder.setTitle("Header").setMessage("Content")
.setPositiveButton("", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog = customBuilder.create(); //Creates the dialog from the above settings
dialog.setCanceledOnTouchOutside(true);
break;
...
}
... //Set the width of the dialog
return dialog;
}
The CustomDialog class extends the Dialog class and then depending on the const it
s supplied with it inflates one of several dialog layouts and adds content etc. Works great normally, but after the app have been paused by HOME for a while, and things go wrong no dialog is shown when I press the button. I do se a flash of a loading dialog on the other buttons, but nothing happens afterwards - no dialog is shown. Strange thing is that if I press on the button again in the middle of the screen, I can't press it (grahics dont react), but when pressing once in the side of the screen and then in the middle the graphics do react, the dialogs does get cancelled when pressing outside, so I'm wondering if there is some very slim "transparent" dialog in the middle or something - I just have no clue why this would happen.
EDIT: Actually looking through the variables I save in Settings class I see that I do save the width and height in pixels of the screen. Width used to set the width of the custom dialogs to a certain % of the screen width. IF the Settings gets wiped, that might explain why I don't see any dialogs as width is set to 0... I really can't seem to figure what is happening if it's not all my variables in the Settings class that gets wiped - everything really do point to that.
dialog.getWindow().setLayout(Settings._widthpx - (Settings._widthpx/5), dialog.getWindow().getAttributes().height); //Width = 80%
Actually I have to admit that I don't really know what is causing this, as I'm rather new to Android. I suspect that the GC does delete all my variables after a while when the Settings class haven't been used - causing all settings to be wiped when the user returns a few hours later. This however does not explain why the buttons doesn't work (one of them require no setting).
This main activity can start other activities, and these can again launch new activities.
I think all my problems can be solved if I can just force the whole app to close when HOME is pressed, and thereby force it to be started from scratch whenever the icon is pressed - forcing the listeners on the buttons and the settings to be loaded.
I read on here about "android:clearTaskOnLaunch", " android:launchMode" and "android:finishOnTaskLaunch" but I'm not quite sure how to use these correct.
Anyone who could either explain to me why the buttons does not work, or what might happen to the variables in my Settings class when the app has been in the background for a while, or maybe give me a few good hints on how to use the "activity" settigns properly.
EDIT: The app will be running Android 1.6+, so I can't use any newer functions or anything...
Thank you very much
DO NOT override home key functionality. Maybe you'll find something, somewhere, that would allow you to do this. A god-fearing, standards-embracing application would not in any way override the home key.
Just put android:clearTaskOnLaunch=true in your manifest. This will ensure that your main activity will be launched everytime you press the launcher icon.
I suspect that the GC does delete all my variables after a while when
the Settings class haven't been used - causing all settings to be
wiped when the user returns a few hours later
Android is not that evil to do this to your app. It may kill your application, services, and whatever is running on the background after some time of inactivity and/or need for more memory, but will never leave your application hanging in there without your variables.
I had actually customized this for android 2.0 development 2.0.May be better options are available now.What I did was to declare all activities global and when you click home button from anywhere we check whether each of them is not null.If not null close them and set references to null.The activities are only declared globally.They are defined only when they are to be used.
If you are using Android 4.0 or higher, you can enable "Don't keep activities" in Developer options?. If you don't have a 4.0 device, then use the emulator.
you have to kill all the activities that are on the top of current activity on Home button and
for do that you have to override Home key functionality in which you have to write
Intent intent = new Intent(context,login.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
this will clear all the activities on the top of that activity where you press home key and switch it to login activity and
if you don't want to override Home key functionallity then you have to write only one in Androidmanifest.xml that is android:clearTaskOnLaunch=true from this when ever you click on app icon it will starts your 1st activity
I Suggest the second approach is best suted for you.
For posterity, in my app I just added finish(); in the onStop() method after everything i do there and it worked as a charm.
I have a simple button onClickListener in my android application, and all it does is write some stuff to the database. It looks something like this
private void setEventListeners(){
mSpecialViewClass.getSubmitButton().setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
handleSubmitClick();
}
});
}
private void handleSubmitClicks(){
if (counter<0){
writeCounterToDb();
} else {
//do some stuff
closeDatabase();
}
}
now this works nicely, but if I tap the button fast enough, I get a closed DB error
java.lang.IllegalStateException: database not open
How can I prevent the key listener from doing anything, before the previous key event has been handeled?
Edit: some user suggested closing my database on Activity.onDestroy() which is quite nice, and he deleted the answer. That is a nice workaround for my problem, but still not the solution I am looking for.
I also tried disabling the button and enabling the button on various positions, and the problem remains. It seems I can always achieve that the function gets called one too many times, if I tap the button too fast.
A good UI trick, that you could possibly use here, is to disable the button once the user clicks. Just do something like this:
#Override
public void onClick(View arg0) {
arg0.setEnabled(false);
handleSubmitClick();
}
You can of course enable the button at the end of your onClick function if you need to.
While the button is disabled the user won't be able to click on it, so you will never get two onClick events. What is more, the style of the button changes, so the user will know that clicking won't do anything.
This technique is used all over the place (Gmail's send button for instance) and I consider it good UI design.
Now if you want to permit your user to press a button multiple times, really really fast and never loose or skip a single press, you'll need to implement some sort of a queuing mechanism. But I can only imagine this being necessary in games where there is a matter of life and death :)