I have a problem with canceling this timer out of this method.
public void nezablokovat() {
int secondsToRun = 9999999;
final ValueAnimator timern = ValueAnimator.ofInt(secondsToRun);
timern.setDuration(secondsToRun * 1000).setInterpolator(new LinearInterpolator());
timern.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
int elapsedSeconds = (int) animation.getAnimatedValue();
int minutes = elapsedSeconds / 60;
int seconds = elapsedSeconds % 60;
if (seconds%10 == 1) {
Pis("$$$");
}
}
});
timern.start();
}
I want to put timern.cancel(); to an other method in the onClick Listener for the Button.
Please Do you have some ideas?
If I put timern.cancel() here:
void teplotahore() {
STup.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
timern.cancel();
}
}
}
);
}
The compiler doesn't know timern.
I don't know how you're whole class is structured, but I believe you may be able to just move the "timern" "variable" outside the constructor (above it) that way making it a field.
A field is like a variable, however it is visible to all methods in the class.
For example:
final ValueAnimator timern = ValueAnimator.ofInt(secondsToRun);
public void nezablokovat() {
int secondsToRun = 9999999;
timern.setDuration(secondsToRun * 1000).setInterpolator(new LinearInterpolator());
timern.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
int elapsedSeconds = (int) animation.getAnimatedValue();
int minutes = elapsedSeconds / 60;
int seconds = elapsedSeconds % 60;
if (seconds%10 == 1) {
Pis("$$$");
}
}
});
timern.start();
}
void teplotahore() {
STup.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
timern.cancel();
}
}
});
}
Related
am getting a black screen when loading a new activity which contains mediaplayer with an mp3 from a URL. if internet is fast e.g 4G , everything is okay and it takes a few seconds to load. but if internet is slow. e.g 2g and 3g , it takes very long and brings a black screen . i need the activity to load without internet, without the black screen. please help me with what i can change on this code
Button download;
private ImageView imagePlayPause;
private TextView textCurrentTime, textTotalDuration;
private SeekBar playerSeekBar;
private MediaPlayer mediaPlayer;
private final Handler handler = new Handler();
#SuppressLint("ClickableViewAccessibility")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ct);
download = findViewById(R.id.download);
download.setOnClickListener(view -> gotoUrl("https://www.facebook.com/davidsibandeRN"));
ImageView imageView3=findViewById(R.id.ImageView3);
String url ="https://dl.dropboxusercontent.com/s/ruo77t7o3dyggpd/parotitis.png?dl=1";
Picasso.get().load(url).placeholder(R.drawable.ic_launcher_background).into(imageView3);
imagePlayPause = findViewById(R.id.imagePlayPause);
textCurrentTime = findViewById(R.id.textCurrentTime);
textTotalDuration = findViewById(R.id.textTotalDuration);
playerSeekBar = findViewById(R.id.playerSeekBar);
mediaPlayer = new MediaPlayer();
playerSeekBar.setMax(100);
imagePlayPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mediaPlayer.isPlaying()) {
handler.removeCallbacks(updater);
mediaPlayer.pause();
imagePlayPause.setImageResource(R.drawable.ic_baseline_play_arrow_24);
} else {
mediaPlayer.start();
imagePlayPause.setImageResource(R.drawable.ic_baseline_pause_24);
updateSeekBar();
}
}
});
prepareMediaPlayer();
playerSeekBar.setOnTouchListener(new View.OnTouchListener() {
#SuppressLint("ClickableViewAccessibility")
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
SeekBar seekBar = (SeekBar) view;
int playPosition = (mediaPlayer.getDuration() / 100) * seekBar.getProgress();
mediaPlayer.seekTo(playPosition);
textCurrentTime.setText(milliSecondsToTimer(mediaPlayer.getCurrentPosition()));
return false;
}
});
mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
#Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int i) {
playerSeekBar.setSecondaryProgress(i);
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
playerSeekBar.setProgress(0);
imagePlayPause.setImageResource(R.drawable.ic_baseline_play_arrow_24);
textCurrentTime.setText(R.string.zero);
textTotalDuration.setText(R.string.zero);
mediaPlayer.reset();
prepareMediaPlayer();
}
});
}
private void gotoUrl(String s) {
Uri uri = Uri.parse(s);
startActivity(new Intent(Intent.ACTION_VIEW,uri));
}
private void prepareMediaPlayer() {
try {
mediaPlayer.setDataSource("https://dl.dropboxusercontent.com/s/tnl4o8isv74rcjb/5.%20parotitis.mp3?dl=1");
mediaPlayer.prepare();
textTotalDuration.setText(milliSecondsToTimer(mediaPlayer.getDuration()));
} catch (Exception exception) {
Toast.makeText(this, exception.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private final Runnable updater = new Runnable() {
#Override
public void run() {
updateSeekBar();
long currentDuration = mediaPlayer.getCurrentPosition();
textCurrentTime.setText(milliSecondsToTimer(currentDuration));
}
};
private void updateSeekBar() {
if (mediaPlayer.isPlaying()) {
playerSeekBar.setProgress((int) (((float) mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration()) * 100));
handler.postDelayed(updater, 1000);
}
}
private String milliSecondsToTimer(long milliSeconds) {
String timerString = "";
String secondString;
int hours = (int) (milliSeconds / (1000 * 60 * 60));
int minutes = (int) (milliSeconds % (1000 * 60 * 60)) / (1000 * 60);
int seconds = (int) ((milliSeconds % (1000 * 60 * 60)) % (1000 * 60) / 1000);
if (hours > 0) {
timerString = hours + ":";
}
if (seconds < 10) {
secondString = "0" + seconds;
} else {
secondString = "" + seconds;
}
timerString = timerString + minutes + ":" + secondString;
return timerString;
}
#Override
public void onBackPressed() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
super.onBackPressed();
}
}
Here I have made this method for starting my timer and the one below it updates the timer:
private void startTimer()
{
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
progress++;
pb.setProgress((int)progress*100/((int)millisUntilFinished/1000));
}
#Override
public void onFinish()
{
progress++;
pb.setProgress(100);
//Vibration
if (Build.VERSION.SDK_INT >= 26)
{
((Vibrator) getSystemService(VIBRATOR_SERVICE)).vibrate(VibrationEffect.createOneShot(150, VibrationEffect.DEFAULT_AMPLITUDE));
Toast.makeText(MainActivity2.this,"Done",Toast.LENGTH_SHORT).show();
}
else
{
((Vibrator) getSystemService(VIBRATOR_SERVICE)).vibrate(VibrationEffect.createWaveform(new long[]{150}, new int[]{VibrationEffect.EFFECT_CLICK},-1));
}
}
}.start();
}
private void updateCountDownText()
{
//time in minutes and seconds
int minutes = (int)(mTimeLeftInMillis/1000)/60;
int seconds = (int)(mTimeLeftInMillis/1000)%60;
//formating the above to appear as String
String timeLeftFormatted = String.format("%02d:%02d",minutes,seconds);
timer.setText(timeLeftFormatted);
}
"pb" is the name of my progressbar. It keeps finishing earlier than the countdown by 2 minutes and I don't know how to synchronize them. Also upon completion the vibration is not triggered for some reason even though it did before. "progress" is initialized as zero as a global variable.
Here is the solution:
long millisInFuture;
private void startTimer() {
millisInFuture = mTimeLeftInMillis;
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
long millisPassed = millisInFuture - mTimeLeftInMillis;
progress = (int) (millisPassed * 100 / millisInFuture);
pb.setProgress(progress);
}
#Override
public void onFinish() {
pb.setProgress(100);
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
VibrationEffect effect =
VibrationEffect.createOneShot(150, VibrationEffect.DEFAULT_AMPLITUDE);
vibrator.vibrate(effect);
Toast.makeText(MainActivity2.this, "Done", Toast.LENGTH_SHORT).show();
} else {
vibrator.vibrate(150);
}
}
}.start();
}
But I don't see when you initialize your progressbar.
If you set pb.max ( or setMax in Java ) = 100
And on each onTick call a method :
private changePb(long millisUntilFinished){
pb.progress = (millisUntilFinished / millisStartValue) * 100
}
Where millisStartValue was the first value you put in new CountDownTimer(mTimeLeftInMillis
And in onFinish, you don't have to put new value for progressbar.
I am trying to set a timer in my Snackbar, I have tried this so far and gotten the timer to work but not in the getTime() method which I think might be the case which is why this isn't working.
I am sorry if this is too bad of a question, I only do Android as a side project.
public class MainActivity extends AppCompatActivity {
private static final String AUDIO_RECORDER_FILE_EXT = ".3gp";
private static final String AUDIO_RECORDER_FOLDER = "VRemind";
private MediaRecorder recorder = null;
private int currentFormat = 0;
private int output_format = MediaRecorder.OutputFormat.THREE_GPP;
private String file_ext = AUDIO_RECORDER_FILE_EXT;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final CountDownTimer t;
t = new CountDownTimer( Long.MAX_VALUE , 1000) {
int cnt=0;
#Override
public void onTick(long millisUntilFinished) {
cnt++;
long millis = cnt;
int seconds = (int) (millis / 60);
setTime(cnt);
Log.d("Count:", ""+cnt);
}
#Override
public void onFinish() {
}
};
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final Snackbar snackbar = Snackbar.make(findViewById(R.id.root_layout), getTime(), Snackbar.LENGTH_INDEFINITE);
final FloatingActionButton fabAdd = (FloatingActionButton) findViewById(R.id.fabAdd);
final FloatingActionButton fabStop = (FloatingActionButton) findViewById(R.id.fabStop);
fabAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
t.start();
fabAdd.setVisibility(View.GONE);
fabStop.setVisibility(View.VISIBLE);
snackbar.show();
snackbar.setAction("CANCEL", new View.OnClickListener() {
#Override
public void onClick(View v) {
snackbar.dismiss();
fabAdd.setVisibility(View.VISIBLE);
fabStop.setVisibility(View.GONE);
}
});
}
});
fabStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
t.cancel();
snackbar.dismiss();
fabStop.setVisibility(View.GONE);
fabAdd.setVisibility(View.VISIBLE);
}
});
}
private String display;
public void setTime(int rawCount) {
int rc = rawCount;
int minutes = (rc - (rc % 60)) / 60;
int seconds = (rc % 60);
String mins = String.format(Locale.ENGLISH, "%02d", minutes);
String secs = String.format(Locale.ENGLISH, "%02d", seconds);
display = mins+ ":" +secs;
Log.d("CountTwo:",display);
getTime();
}
public String getTime() {
Log.d("Count getTime:", display);
return display;
}
Are you getting this message?
java.lang.NullPointerException: println needs a message
If yes it is because you try to log a null message like this:
Log.d("Count getTime:", display);
You have to initialize the display variable to have a value for the first run.
private String display = "";
I looked into it and the problem was that the String display was inaccessible to the Snackbar and also the Snackbar test was unable to update dynamically so I did both of those and made a few changes here and there and here's my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final CountDownTimer t;
t = new CountDownTimer( Long.MAX_VALUE , 1000) {
int cnt=0;
#Override
public void onTick(long millisUntilFinished) {
cnt++;
long millis = cnt;
int seconds = (int) (millis / 60);
setTime(cnt);
Log.d("Count:", ""+cnt);
}
#Override
public void onFinish() {
cnt = 0;
}
};
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
snackbar = Snackbar.make(findViewById(R.id.root_layout), "", Snackbar.LENGTH_INDEFINITE);
final FloatingActionButton fabAdd = (FloatingActionButton) findViewById(R.id.fabAdd);
final FloatingActionButton fabStop = (FloatingActionButton) findViewById(R.id.fabStop);
fabAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
t.start();
fabAdd.setVisibility(View.GONE);
fabStop.setVisibility(View.VISIBLE);
snackbar.show();
snackbar.setAction("CANCEL", new View.OnClickListener() {
#Override
public void onClick(View v) {
t.cancel();
t.onFinish();
// setTime(0);
snackbar.dismiss();
fabAdd.setVisibility(View.VISIBLE);
fabStop.setVisibility(View.GONE);
}
});
}
});
fabStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
t.cancel();
t.onFinish();
// setTime(0);
snackbar.dismiss();
fabStop.setVisibility(View.GONE);
fabAdd.setVisibility(View.VISIBLE);
}
});
}
/*
public void Duration() {
*//* Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
int count;
#Override
public void run() {
setTime(count);
count++;
Log.d("Count:", ""+count);
}
});
}
};*//* //Old code removed on 22Apr17#11:41PM
}*/ //Old code Duration method
String display="";
public void setTime(int rawCount) {
// int rc = rawCount;
int minutes = (rawCount - (rawCount % 60)) / 60;
int seconds = (rawCount % 60);
String mins = String.format(Locale.ENGLISH, "%02d", minutes);
String secs = String.format(Locale.ENGLISH, "%02d", seconds);
display = mins+ ":" +secs;
Log.d("CountTwo:",display);
snackbar.setText(display);
}
/*public String getTime() {
Log.d("Count getTime:", display);
return display;
}*/
In my app, i'm using two different CountDownTimers that have same values. I have two buttons to control them but when i press the button twice, it starting from the beginning. I want to keep its last value.
Here is my code:
t1 = new CountDownTimer(white, 1000) {
#Override
public void onTick(long l) {
btnWhite.setText("seconds remaining: " + l / 1000);
white = l;
}
#Override
public void onFinish() {
}
};
t2 = new CountDownTimer(black, 1000) {
#Override
public void onTick(long l) {
btnBlack.setText("seconds remaining: " + l / 1000);
black = l;
}
#Override
public void onFinish() {
}
};
btnBlack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
t1.start();
t2.cancel();
}
});
btnWhite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
t2.start();
t1.cancel();
}
});
I have tested this and it works!
I have two TextViews and two Buttons. The black button is next to the black text view and the white button is next to the white text view.
First I declare the important constants.
//contains the elapsed time for each of the timers
long blackElapsed=0,whiteElapsed=0;
//contains the total time with which we start new timers
long totalWhite = 30000;
long totalBlack = 30000;
Next I initialise the CountDownTimers. Whatever you put in here doesn't matter. I only have this so that the timers will be initialised with some value.
The reason is that they have to be initialised in order to be able to .cancel() them later in the OnClickListeners.
black = new CountDownTimer(totalWhite, 1000){
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
}
};
white = new CountDownTimer(totalBlack, 1000){
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
}
};
Finally the OnClickListeners for the buttons. (W is white textView and B is black textView and b is black button and w is white button)
w.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
black.cancel();
//using the elapsed time to start a new timer
totalBlack = totalBlack - blackElapsed;
//this preserves milliseconds by ticking every millisecond
white = new CountDownTimer(totalBlack, 1){
#Override
public void onTick(long l) {
B.setText(l+"");
blackElapsed=totalBlack-l; //updating the elapsed time
}
#Override
public void onFinish() {
}
}.start();
}
});
//we do a similar thing with the other player's button
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
white.cancel();
totalWhite = totalWhite - whiteElapsed;
black = new CountDownTimer(totalWhite, 1){
#Override
public void onTick(long l) {
W.setText(l+"");
whiteElapsed=totalWhite-l;
}
#Override
public void onFinish() {
}
}.start();
}
});
I have checked your code.
It is obvious because your timers initialised with default values. when you start again it won't take new values of white/black.
To achieve what you want you have to initialise timer with new values before starting it.
I have done some correction in your code. you can check that out.
Make Two methods
public void timerStart1(long timeLengthMilli) {
t1 = new CountDownTimer(timeLengthMilli, 1000) {
#Override
public void onTick(long l) {
isRunning1 = true;
tv1.setText("seconds remaining: " + l / 1000);
white = l;
}
#Override
public void onFinish() {
isRunning1 = false;
}
}.start();
}
public void timerStart2(long timeLengthMilli) {
t2 = new CountDownTimer(timeLengthMilli, 1000) {
#Override
public void onTick(long l) {
isRunning2 = true;
tv2.setText("seconds remaining: " + l / 1000);
black = l;
}
#Override
public void onFinish() {
isRunning2 = false;
}
}.start();
}
and set setOnClickListener like this
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!isRunning1) {
isRunning2 = false;
timerStart1(white);
if (t2 != null)
t2.cancel();
}
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!isRunning2) {
isRunning1 = false;
timerStart2(black);
if (t1 != null)
t1.cancel();
}
}
});
UPDATE :
Please check updated code and take these extra variables
boolean isRunning1 = false, isRunning2 = false;
Hope this will help you.
Happy Coding.
So I have 3 timers. For the first one I want only to appear once, because it's something like get ready timer.
For the second and third I want to appear as many times as user wants. Before timers start user must select number of times by pressing on + or - buttons which then set value of a TextView.
That's done with this code:
int counter = 0;
homeScreenPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dodajInterval();
homeScreenMinus.setEnabled(counter > 0);
}
});
homeScreenMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
oduzmiInterval();
homeScreenMinus.setEnabled(counter > 0);
}
});
}
private void oduzmiInterval() {
counter--;
brojIntervala.setText(Integer.toString(counter));
}
private void dodajInterval() {
counter++;
brojIntervala.setText(Integer.toString(counter));
}
And here's the code for timers:
public void homeScreenStart(View view) {
linearniLayoutSetup.setVisibility(View.GONE);
CountDownTimer firstCountDown = new CountDownTimer(seekBarTimerDelay.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
countDownTimerTrci();
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_trci));
}
}.start();
}
public void countDownTimerTrci() {
for (int i = 0; i < counter; i++) {
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
CountDownTimer secondCountDown = new CountDownTimer(seekBarIntervaliVisokogIntenziteta.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
imageViewTimerSlika.setImageResource(R.drawable.ic_timer_niski_intenzitet);
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_hodaj));
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
CountDownTimer thirdCountDown = new CountDownTimer(seekBarIntervaliNiskogIntenziteta.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
countDownTimerTrci();
}
}.start();
}
}.start();
}
}
As you can see, it's a method which is called when button is pressed and I wan't first timer to appear only once and that's why I didn't include it in foor loop.
First timer shows only once and that works, but other two timers keep repeating until I close the app.
Can someone tell me where the problem is?
Try this ,replace your countDownTimerTrci method with mine
public void countDownTimerTrci() {
if(counter>0) {
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
CountDownTimer secondCountDown = new CountDownTimer(seekBarIntervaliVisokogIntenziteta.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
imageViewTimerSlika.setImageResource(R.drawable.ic_timer_niski_intenzitet);
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_hodaj));
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
CountDownTimer thirdCountDown = new CountDownTimer(seekBarIntervaliNiskogIntenziteta.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
counter--;
textViewTimerVrijeme.setText("00:00");
countDownTimerTrci();
}
}.start();
}
}.start();
}
}