I am just starting to learn Android, Java and need help.
I have an activity with the countdowntimer, which works fine. However, I want it to be displayed in the fragment. What is the best way to do it?
I tried calling Timer.getCountdowntimer, I tried calling Timer.getUserTime (userTime is the user selected time for the countdowntimer), but the textview in my fragment doesn't display the timer.
thanks in advance!
If you are coding in Java purely, and want to use the android SDK to do it, I would recommend:-
//Create a handler that runs on main loop so we can update UX
final android.os.Handler handler = new android.os.Handler(Looper.getMainLooper());
//Get a callback in 1 second
handler.postDelayed(new Runnable() {
int timer;
#Override
public void run() {
timer += 1;
myTextView.setText(String.valueOf(timer));
//Recursively get another callback in a second
handler.postDelayed(this, 1000);
}
}, 1000);
Make sure you add some logic to stop the timer when you want, and also onPause/onResume
Related
I have an activity in my android app that shows a word to the user. if the user could guess the answer in less than 60 seconds he would press a button and go to another activity. but if he could not do it and the time finishes, a third activity must show. How should I do it? with threading or timer or something like that?
I have tried threading but the app crashes.
You can achieve this by using Handler.
Kotlin
// declare this variables as attributes in you class
val handler = Handler()
val runnable = Runnable {
// Call something when it finishes
}
handler.postDelayed(runnable, 60_000) // Do something after 60 seconds
// and if you want to cancel the timer, you can cancel it this way
handler.removeCallbacks(runnable)
Java
// declare this variables as attributes in you class
Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
// Call something when it finishes
}
};
handler.postDelayed(runnable, 60_000);
// and if you want to cancel the timer, you can cancel it this way
handler.removeCallbacks(runnable);
i need a countDownTimer keep running when i swap between activities.. i have more than one activity, i put the countDownTimer in the main activity but when i swap to another activity and back to the main activity it turns back to count again from the start, i believe because the method countDownTimer is onCreate method.
So, how should I go about doing this?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
questionTime();
}
public void updateTimer(int secondsLeft){
int minutes = (int) secondsLeft / 60;
int seconds = secondsLeft - minutes * 60;
String secondString = Integer.toString(seconds);
timerTextView.setText(Integer.toString(minutes) + ":" + secondString);
}
private void questionTime(){
new CountDownTimer(10000, 1000){
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
timerTextView.setText("0:00");
Log.i("finished", "timer Done");
}
}.start();
}
Update: That helped me to reach my purpose How to run CountDownTimer in a Service in Android?
Maybe this is a little far fetched, but the way that I think to solve this issue and not worrying for the Activities is using an IntentService.
Even if you store some sort of value in the Bundle of the onSaveInstance() hook method this can lead to some pretty messy results if you enable the "Don't keep activities" flag in the device's settings.
What I would do is create an IntentService that when It's triggered starts the countdown, then It broadcast the changes of that countdown through EventBus/Otto/BroadcastReceiver back to the UI.
Another way of doing it is having the countdown instance in your Application class, and check it from there.
I would go with the IntentService solution because having a countdown instance running in the Application class sounds a little off.
Let me know if you want any specifics on how to implement the IntentService but a little bit of Googling should show you how to do it.
As soon as the time starts, write the time (unix timestamp) to properties file. And when the user comes back to your main activity, read the properties file and compare it the time in the properties file with current timestamp and update the timer based on that.
I have an app with a title screen. When the app first starts, I have an onCreate method that contains the following code:
setContentView(R.layout.title_screen);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
setContentView(R.layout.main_screen);
}
}, 2000);
When I run my app and press the back button while on the main_screen layout, it closes the app (as it should). However, when I reopen the app, it displays the title_screen layout for two seconds again even though the app is already running. How can I prevent this?
This will prevent the delay appearing again when resumed:
private static boolean flag = false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!flag){
setContentView(R.layout.title_screen);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
setContentView(R.layout.main_screen);
}
}, 2000);
flag = true;
} else {
setContentView(R.layout.main_screen);
}
}
Btw, if your app was on background and it is calling onCreate again while being resumed, it means that it is killed by the OS. Therefore it is normal to have the initial delay again.
What I would do is to implement two different activities first one showing title_screen and the second which is started after 2s should show your main screen.
After looking at your code I can see that you ALWAYS start with title_screen then after 2s, you change to main_screen. Therefore, when you press back, that means you finish your activity. When you re-open your app, onCreated is called again, and it run every line of code as the previous opening.Of course, there's no difference in 2 times you open your app. To overcome it, I recommend to use SharedPreference to store the flag to check main_screen or title_screen.
I have an Activity that I want to run a Delay Function when it runs. I [i]don't[/i] want a delay in OnClick function, I want delay when activity [i]starts[/i].
I have tried the following solutions :
How to set delay in Android onClick function
How to pause/delay on Android?
Android: Timer/Delay Alternative
Android timer set delay
...and some more and none of them did what I want. I want a delay when activity starts (for my project , when The Game Starts) but with that codes, it starts the delay (e.g 10s) when I put my finger on the screen.
You should put a Thread.sleep(long) before the "setContentView(R.layout.xxxx..)" in the onCreate(..) function. In that way, it will actually delay before showing you the elements of the Activity.
If you want to delay even before the onCreate(...) is fired, the approach will need to be different, here is one suggestion:
Run a Service and check for the Foreground application using ActivityManager class (see sample code below). Keep checking for when your app is fired or brought to the 'foreground' (using code below) and then just go back to homescreen & start a timer (in the service itself). Once the timer expires, start your app.
You can run the function below inside an AsyncTask in the Service.
The two approaches are quite different and really depends on what you are looking to achieve exactly.
#SuppressWarnings("deprecation")
private void getRunningAppName() throws NameNotFoundException {
Log.v("neiltag", "Entered getRunningAppName()");
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
// The first in the list of RunningTasks is always the foreground task.
RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);
String foregroundTaskPackageName = foregroundTaskInfo .topActivity.getPackageName();
PackageManager pm = this.getPackageManager();
PackageInfo foregroundAppPackageInfo = pm.getPackageInfo(foregroundTaskPackageName, 0);
String foregroundTaskAppName = foregroundAppPackageInfo.applicationInfo.loadLabel(pm).toString();
String packageName = foregroundAppPackageInfo.packageName;
if(foregroundTaskAppName.matches("<NAME OF YOUR APP HERE>")) {
//If your app is fired go back to the Homescreen(i.e. the delay)
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "You are not allowed to open Facbeook now, sorry!", Toast.LENGTH_SHORT).show();
}
});
}
//ADD A TIMER HERE
//ONCE TIMER EXPIRES, FIRE UP YOUR APP AGAIN
}
Im trying to call a function from within a doInBackground of an AsyncTask that fades in a progressBar. Everytime i call this function the progressbar fades in as required then disappears. I added a check at the end which tells me that the visibility of the progressbar has returned back to GONE as soon as the runOnUIThread method completes:
Reset Prog To Gone
Why is this and how can I make it so the progressbar remains visible?
I have been using the following:
#TargetApi(12)
private void fadeInProgressBar(final int time, ProgressBar prog){
System.out.println("MainActivity: Fading In ProgressBar");
runOnUiThread(new Runnable(){
#Override
public void run() {
if(usingHigherApiThan(12)&&prog.getVisibility()==View.GONE){
prog.setVisibility(View.VISIBLE);
if(prog.getAlpha()<1){
prog.animate().setDuration(time).alpha(1);
}
}else if(prog.getVisibility()==View.GONE){
prog.setVisibility(View.VISIBLE);
final AlphaAnimation animation = new AlphaAnimation(0F, 1F);
animation.setDuration(time);
animation.setFillAfter(true);
prog.startAnimation(animation);
}
}
});
if(prog.getVisibility()==View.VISIBLE){
System.out.println("Left Prog Visible");
}else{
System.out.println("Reset Prog To Gone");
}
}
note usingHigherApiThan(12) just checks the build version is 12 or greater and this problem occurs for both above 12 and below 11.
You don't need to, and probably shouldn't, do it this way. AsyncTask has methods that run on the UI thread already (all but doInBackground())
Put your code that you want to run on the UI into onPostExecute() to run when doInBackground() has finished.
Or if it suits your needs better you can also put the code in onProgressUpdate() and call this function when needed with publishProgress().
Alternatively, if you only need it to run when the task starts then you can just put it in onPreExecute(). All of these run on the UI Thread. There's no need to add extra steps with runOnUiThread().
AsyncTask Docs