I am trying to allow users of my app to change the length of the splash screen. I created an EditTextPreference in my preferences.xml and gave it a default value of 5. The key is "duration". I figured that I could use SharedPreferences and use the getLong method to get the value of the field, and then use it as the parameter for the Thread's sleep method.
Here is my code:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
long dur = prefs.getLong("duration", 5);
final long duration = dur*1000; //convert from seconds to milliseconds
Thread timer = new Thread() {
public void run() {
try{
sleep(duration);
}
catch (InterruptedException e) {
e.printStackTrace();
}
finally {
Intent openMenu = new Intent("com.heh.blah.MENU");
startActivity(openMenu);
}
}
};
timer.start();
This code works perfectly fine as long as the preference isn't changed. However, if I go into the preferences and change the Duration preference (even if I don't change it and just hit "ok" with the default value of 5 in the box OR hit cancel) and close the app, the next time it opens, the screen goes all white for a few seconds, then all black, and then it crashes and I get the "Unfortunately, App has stopped." popup box. Clearing app data allows the app to start up normally again (but with a 5 second splash screen).
UPDATE: Just opening the preferences EVEN WITHOUT CHANGING CLICKING ON OR CHANGING ANYTHING causes it to crash during the next start up.
Any help with this issue would be much appreciated!!!
Thanks,
Max
You would be better off sending a delayed Message to a Handler on the UI thread.
Related
Trying to figure out how to do this, basically my App requires a button to be hit and hit multiple times, it counts how many times you hit it and if you don't hit one within a certain space of time it will display a message.
I just can't figure out how to get the 'If button isn't pressed within 'x' seconds then...' part, I've tried if(imagebutton1.isPressed()) statement but it checks it instantly when the actvity starts, I just want it to check 'X' amount of seconds after the button was last pressed.
ANy help is appreciated thanks.
In your case you would need to record the last time the button was pressed
Then add a updated while statement
In c++
Int presses;
Int timelimit; //the seconds between each press (you can use a chronometer but this is simpler but less accurate (and no decimals)
Int lastpressed; //need chronometer for more accuracy or decimals)
Int ammountpassed; //time since you pressed it
If(imagebutton1.isPressed())
{
Bool Started = Yes;
Presses++;
While(!imagebutton1.isPressed()&&ammountpassed<TimeLimit)
{
Ammountpassed++;
};
};
If (ammountpassed>=timelimit)
{
If (presses>=highscore)
{
DisplayMsg " Number of presses" presses; "! New highscore!";
};
Else(presses<highscore)
{
DisplayMsg "not fast enough! Number of presses" presses; "!" };
};
};
You will have to tweak it a bit to fit your needs ("displaymsg" I for think is the actual function so you might have to change that but there's the logic :)
I recommend hand typing this as I belive I may have made a few error but nothing adding a semi colon or 2 won't fix ;)
Hope it helps :) Good Luck :)
Every time the user hits the button you can post a message on the handler's queue with your text message to be displayed and the appropriate delay time (and remove previous messages). Therefore if the delayed time exceeds without any press the thread will execute the handler's message. Lets say you want to post to the main handler a message to be executed in delay number of milliseconds, then in your activity you would need to hold the reference to the handler and create a Runnable where the necessary text message will be displayed:
Handler mainHandler = new Handler(getMainLooper());
Runnable runnable = new Runnable(...);
In your OnClickListener of the button you would need to execute only:
#Override
public void onClick(View v) {
mainHandler.removeCallbacksAndMessages(null);
mainHandler.postDelayed(runnable, delay);
}
I want to programm a game for Android.
Play principle: The user should have a short time to choose the correct answer.
My problem is the combination between the input (choosing the answer) and the time (countdown). I tried to run a thread, but the thread isn't stoppable. So the user gives the answer, the next activity will be shown and after a while (when the "timer" becomes 0) the activity will be shown again.
How could I implement this in a correct way?
Should I use Thread, Handler, CountDownTimer ?
You can keep a running timer using this on init:
Timer updateTimer = new Timer("update");
updateTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
updateGUI();
}
}, 0, 1000);
long startTime = System.currentTimeMillis();
Then in a Thread:
//Clock update
currentTime = System.currentTimeMillis() - startTime;
SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
clock.setText(sdf.format(currentTime));
clock.invalidate();
You could stop the Thread with a boolean inside or outside as you please?
Okay, I don't know the specific libraries to use, and I haven't done any thread programming myself, but I would think of the program as a state machine. I hope it helps :/
Set up a boolean userHasAnswered = false.
Set up a specialized listener (e.g. touch listener for some button) for answers.
If the listener gets an appropriate response from the user, set userHasAnswered = true.
When question loads up, start the thread which counts down.
If user fails to give ans when the time reaches zero, just call loadNextQuestion().
In your thread, do periodic checks every few units of time to see if userHasAnswered == true, and if it is true, then call updateScore() and loadNextQuestion().
You may want to have a look at alarm manager
Following up on https://stackoverflow.com/a/3448189, what is the best way to actually show the password screen?
My first try was starting a SubActivity with a LockActivity:
// MainActivity.java
public void onResume() {
super.onResume();
ApplicationState state = ((ApplicationState) getApplication());
if ((new Date().getTime() - state.mLastPause) > 5000) {
// Prompt for password if more than 5 seconds since last pause
Intent intent = new Intent(this, LockActivity.class);
startActivityForResult(intent, UNLOCKED);
}
}
However, this causes the MainActivity to be paused again after getting unlocked if the LockActivity is shown longer than 5 seconds.
So, I have some things in mind:
Use Fragments to show the Main screen or the Lock screen inside of MainActivity.
Show a Dialog as Lock screen (not preferred).
Using several if ... else branches to check whether a password has been set and the MainActivity has been paused longer than five seconds.
To give you an example, I would like to achieve the same behavior as in the Dropbox app (using the "Passcode lock" option).
What is the correct way to handle this?
P.S. I'm not sure whether I should have posted this as a question to the original question, thus digging out the old thread. I felt like posting a new question is a cleaner solution.
Since I was the one asking the other question, I might as well tell you how I solved it. I'm using a dialog for prompting for the password (which I do know you do not prefer, but it might help someone else) and makes sure that the only way to dismiss it is by entering the correct password.
MyApplication app = ((MyApplication)getApplication());
if (new Date().getTime() - app.mLastPause > 5000) {
// If more than 5 seconds since last pause, check if password is set and prompt if necessary
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
String password = pref.getString("password", "");
if (password.length() > 0) {
// Prompt for password
MyPasswordDialog dlg = new MyPasswordDialog(this, password);
dlg.setOwnerActivity(this);
dlg.show();
}
}
And in the OnCreate()-method of MyPasswordDialog i make sure that it is not cancelable
protected void onCreate(Bundle savedInstanceState) {
this.setCancelable(false);
// ...and some other initializations
}
I have been trying to get a bitmap screenshot of a SurfaceView for days but the more I look into it, there doesn't seem to be a solution at present for Android OS 2.3.4 based OSs my device from HTC.
So on to Plan B, where I just found out another blog: "On my HTC Evo 3d, all I have to do is hold the power button for 1-2 sec and then hit the home button and it takes a screen shot. No app required." Turns out this works perfectly on my tablet.
I also know from digging around there are these intents: android.intent.action.SCREEN_OFF & android.intent.category.HOME
(So I tried a bunch of code experiments to try to mimic the 2-key combo in code to get a screenshot in this brute force manor. Unfortunately without success).
So my ? -- Does anyone have any insights into a method to invoke this 'screenshot sequence' for my HTC device from java code? (Presume I need to fool the OS into thinking I am holding down the power key AND tap the Home key, simultaneously)...
More: Here is a snip of the code I am attempting:
Button click for test... ...
Thread t = new Thread() {
public void run() {
Instrumentation inst = new Instrumentation();
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_POWER);
Instrumentation inst2 = new Instrumentation();
inst2.sendKeyDownUpSync(KeyEvent.KEYCODE_HOME);
} // run
}; // thread t
Doesnt work as the inst.sendKeyDownUpSync is wrong as I need a sendKeyDown (& hold) behavior or its equivel
Many thanks for any advise. If I do get this working, I will post the solution here. Cheers GH
PS; I presume there is some custom intent under the hood doing this? Is there a system log somewhere to trey to peek at the call tree to find out what it is ?
EDIT (MORE)... 9/24/11
More. Still not working but I am heading down this path & think it is closer...
// Attempt to SIMULATE A Long press (DOWN) + HOME to tell the HTC to invoke the 'Screenshot' command (WARNING: HTC Tablet specific behavior!)
Thread tt = new Thread() {
public void run() {
final KeyEvent dapowerkey = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_POWER);
Handler onesecondhandler = new Handler();
onesecondhandler.postDelayed(new Runnable() {
public void run() {
// fpr about 1 second send power down keystrokes (DOWN ONLY)
while (true) { dispatchKeyEvent(dapowerkey); }
} // we are done running on the timer past time point
}, 750); // 3/4 second key press
// send the HOME keystroke
Instrumentation inst1 = new Instrumentation();
inst1.sendKeyDownUpSync(KeyEvent.KEYCODE_HOME);
} // outer thread run tp mpt block the GUI
}; // outer thread t
tt.start();
...
Also thought if I can send the right intent directly to the proper place on the device that I might be able to kick off a screen capture function directly (which is what I really want. Through some log examinations (when you Long-Power + Home click on HTC) a program called 'com.htc.mysketcher' (FlashActivity) is being called...
Again, if I figure this out then I will post to the group... Cheers GH
I am developing an App where I show the countdown timer. To countdown the time I am using Handler class. Once the countdown timer reaches certain time the Alarm goes off. My problem is as below,
Initially I show the timer time as 04:00:00. Once it reaches 00:00:00 then the Alarm goes off. The Alarm code is working fine. But the timer display is not reliable. It works fine until I keep the App open. If I close the App (using Home or Back) or lock the device and open App again then the timer shown is not the correct one (delaying a lot, but still alarm works on-time). (But it works sometimes very fine under the same scenario). But whenever I ping the device to the system for checking the Log in eclipse that time all works fine!!!!!!!
1. I want to know whether I am using the Handler properly or not
2. (or) Is going out of the App or locking the device causing the problem
Below is my Handler code,
Handler digiHandler;
// Method to initialize the time and define the Handler
public void initialize(int hourstime,int mintime,int sectime){
hour = hourstime;
min = mintime;
sec = sectime;
digiHandler = new Handler();
handleRunnable = new Runnable(){
public void run(){
updateTimes();
}
};
}
public void startUpdateTheread(){
digiHandler.postDelayed(handleRunnable, UPDATEDELAY);
}
// Method to update the timer times
private void updateTimes(){
timerText = String.format(timerFormat,hour,min,sec );
-------------------------
-------------------------
-- code for incrementing the time ---
--------------------------
--------------------------
--------------------------
startUpdateTheread();
}
Please give the suggestions
Thanks
Edit:
When I observed the log it shows that to countdown 1 second of timer sometimes it is taking 1 minute time. The log is as below,
09-21 21:09:18.965: DEBUG/DigitalTimer(7656): timerText**:04:22:54
****long difference here****
09-21 21:10:19.308: DEBUG/DigitalTimer(7656): timerText**:04:22:53
..................................................................................
..................................................................................
..................................................................................
09-21 21:10:23.314: DEBUG/DigitalTimer(7656): timerText**: 04:22:49
**--long difference here ---**
09-21 21:11:22.604: DEBUG/DigitalTimer(7656): timerText**:04:22:48
It is happening always. So I can rule out that locking/coming out of an App is causing the problem. Seems I need to tweak the Handler part of the code.
The problem is that if the activity dies, then so does the thread it spawned, I recommend creating a service to handle this since such timers can be long i imagine (over 4 minutes) and in that time, you need the application to not die.
take a look at http://developer.android.com/reference/android/app/Service.html and let me know if that seems like a good enough solution.