setImageRessource doesn't work in a timer android studio - java

I'm a beginner...
Why did my "setImageRessource" doesn't work?
The image "fiole" have to change at 10% and at 20% of the duration of the timer but on my phone, the image never change...
However, the text of the textViex is changed when the time equals the quarter of the duration.
public class XActivity extends AppCompatActivity {
int duree;
String duration;
int durationInt;
protected TextView tempsRestant;
protected ImageView fiole;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_X);
this.duree = 0;
this.duration = getIntent().getStringExtra("DURATION");
this.durationInt = Integer.parseInt(duration)*60;
this.tempsRestant=findViewById(R.id.tempsRestant);
this.fiole=findViewById(R.id.fiole);
final Timer modecTimer = new Timer();
modecTimer.schedule(new TimerTask() {
#Override
public void run() {
duree += 1;
if (duree==(durationInt/100)*10){
fiole.setImageResource(R.drawable.fiole10p);
}
if (duree==(durationInt/100)*20){
fiole.setImageResource(R.drawable.fiole20p);
}
if (duree==durationInt/4){
tempsRestant.setText("some text");
}
}
}
}, 1000, 1000);
}

Your setImageResource didn't work, because it needs to be run on UIThread
modecTimer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(() -> {
duree += 1;
if (duree==(durationInt/100)*10){
fiole.setImageResource(R.drawable.fiole10p);
}
if (duree==(durationInt/100)*20){
fiole.setImageResource(R.drawable.fiole20p);
}
if (duree==durationInt/4){
tempsRestant.setText("some text");
}
});
}
}, 1000, 1000);

Related

How to show a alert dialog when app is launched first time

I have two audio files in my app. When the app is launched the first time and when the user plays the first audio for the first time, I want to show a dialog, but afterwards never show it again.
When the user clicks OK, then only the dialog will disappear.
I have only created the XML of the dialog because I don't know how to show a layout when the app is launched the first time.
MainActivity.java here the player1 (Media Player) and play1 (ImageView as the button to play the audio) is for the first audio where the dialog has to be shown.
public class MainActivity extends AppCompatActivity {
MediaPlayer player1, player2;
SeekBar seekBar1, seekBar2;
TextView currentTime1, currentTime2;
TextView remainingTime1, remainingTime2;
ImageView play1, play2;
int totalTime1, totalTime2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// PlayButton * The ButtonClick is in the last if you want to jump directly there *
play1 = findViewById(R.id.playbtn);
play2 = findViewById(R.id.playbtn2);
// TimeLables
currentTime1 = findViewById(R.id.currentTime1);
currentTime2 = findViewById(R.id.currentTime2);
remainingTime1 = findViewById(R.id.totalTime1);
remainingTime2 = findViewById(R.id.totalTime2);
// MediaPlayer
player1 = MediaPlayer.create(this, R.raw.dog_howl);
player2 = MediaPlayer.create(this, R.raw.dog_bark);
player1.setLooping(false);
player1.seekTo(0);
totalTime1 = player1.getDuration();
player2.setLooping(false);
player2.seekTo(0);
totalTime2 = player2.getDuration();
//SeekBar
seekBar1 = findViewById(R.id.seekbar1);
seekBar2 = findViewById(R.id.seekbar2);
seekBar1.setMax(totalTime1);
seekBar2.setMax(totalTime2);
seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
player1.seekTo(progress);
seekBar1.setProgress(progress);
currentTime1.setText(createTimerLable1(progress));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
player2.seekTo(i);
seekBar2.setProgress(i);
currentTime2.setText(createTimerLable2(i));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
new Thread(() -> {
while (player1 != null) {
try {
Message msg = new Message();
msg.what = player1.getCurrentPosition();
handler1.sendMessage(msg);
Thread.sleep(1000000000);
} catch (InterruptedException ignored) {
}
}
}).start();
new Thread(() -> {
while (player2 != null) {
try {
Message msg = new Message();
msg.what = player2.getCurrentPosition();
handler2.sendMessage(msg);
Thread.sleep(1000000000);
} catch (InterruptedException ignored) {
}
}
}).start();
// Admob Banner Ad
MobileAds.initialize(this, initializationStatus -> {
});
AdView mAdView = findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
}
#SuppressLint("HandlerLeak")
private final Handler handler1 = new Handler() {
#Override
public void handleMessage(#NonNull Message msg) {
int currentPosition1 = msg.what;
//Update SeekBar
seekBar1.setProgress(currentPosition1);
// Update Timelable
String totTime1 = createTimerLable1(player1.getDuration());
remainingTime1.setText(totTime1);
}
};
#SuppressLint("HandlerLeak")
private final Handler handler2 = new Handler() {
#Override
public void handleMessage(#NonNull Message msg) {
int currentPosition2 = msg.what;
// Update SeekBar
seekBar2.setProgress(currentPosition2);
// Update Timelable
String totTime2 = createTimerLable2(player2.getDuration());
remainingTime2.setText(totTime2);
}
};
public String createTimerLable1(int duration) {
String timerLabel = "";
int min = duration / 1000 / 60;
int sec = duration / 1000 % 60;
timerLabel += min + ":";
if (sec < 10) timerLabel += "0";
timerLabel += sec;
return timerLabel;
}
public String createTimerLable2(int duration) {
String timerLabel = "";
int min = duration / 1000 / 60;
int sec = duration / 1000 % 60;
timerLabel += min + ":";
if (sec < 10) timerLabel += "0";
timerLabel += sec;
return timerLabel;
}
public void playBtnClick1(View view) {
if (player2.isPlaying()) {
player2.pause();
play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
if (!player1.isPlaying()) {
// Stoping
player1.start();
play1.setImageResource(R.drawable.ic_baseline_pause_circle_filled_24);
} else {
// Playing
player1.pause();
play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
}
public void playBtnClick2(View view) {
if (player1.isPlaying()) {
player1.pause();
play1.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
if (!player2.isPlaying()) {
// Stoping
player2.start();
play2.setImageResource(R.drawable.ic_baseline_pause_circle_filled_24);
} else {
// Playing
player2.pause();
play2.setImageResource(R.drawable.ic_baseline_play_circle_filled_24);
}
}
}
As #blackapps suggested, You will save the information about the user in SharedPreferences. You will save whether you have displayed the dialog and whether user's has played audio for first time or not.
To save or get the details from SharedPreferences,
You can follow this SO answer for storing strings, int, boolean etc.
You can follow this SO answer for storing custom objects.

Stop running livedata task on activity stop

I'm trying to understand a right way to work with viewmodel & livedata.
I created a simple app which started timer when activity start.
When activity destroyed - timer continues running and on restart activity created a second timer and now we have two running timers - it's a potential memory leak ?
How a right way to stop our "task" on stop\destroy activity ?
My code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding mActivityMainBinding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(mActivityMainBinding.getRoot());
MainActivityViewModel mainActivityViewModel =
new ViewModelProvider(this).get(MainActivityViewModel.class);
Observer<Integer> liveDataObserver = integer ->
mActivityMainBinding.tvCounter.setText("Elapsed : "+integer+ " s");
mainActivityViewModel.getLiveData().observe(this, liveDataObserver);
getLifecycle().addObserver((LifecycleEventObserver) (source, event) ->
Log.d("mylog", event.name()));
} }
MainActivityViewModel .java
public class MainActivityViewModel extends ViewModel {
private MutableLiveData<Integer> mutableLiveData = new MainActivityLiveData<>();
private static int BEGIN_AFTER = 1000, INTERVAL = 5000;
private static int counter = 0;
public MainActivityViewModel() {
startTimer();
}
private void startTimer() {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.d("mylog", timer.toString() + " " + ++counter);
mutableLiveData.postValue(counter);
}
}, BEGIN_AFTER, INTERVAL);
}
public MutableLiveData<Integer> getLiveData() {
return mutableLiveData;
} }
MainActivityLiveData.java
public class MainActivityLiveData<T> extends MutableLiveData<T> {
#Override
protected void onActive() {
Log.d("mylog", "onActive");
}
#Override
protected void onInactive() {
Log.d("mylog", "onInactive");
}}
You need to stop the timer inside onClear() of viewModel. for that you have to make it a global variable .
public class MainActivityViewModel extends ViewModel {
private MutableLiveData<Integer> mutableLiveData = new MainActivityLiveData<>();
private Timer timer = new Timer();
private static int BEGIN_AFTER = 1000, INTERVAL = 5000;
private static int counter = 0;
public MainActivityViewModel() {
startTimer();
}
private void startTimer() {
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.d("mylog", timer.toString() + " " + ++counter);
mutableLiveData.postValue(counter);
}
}, BEGIN_AFTER, INTERVAL);
}
public MutableLiveData<Integer> getLiveData() {
return mutableLiveData;
}
#Override
protected void onCleared() {
super.onCleared();
stopTimer();
}
private void stopTimer(){
if(timer != null) {
timer.cancel();
timer.purge();
timer = null;
}
}
}

Unable to set timer in Snackbar

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;
}*/

How can i Reset my Timer value meanwhile completion of timer?

I am trying to start a timer when activity created and be able to reset the timer back from zero if the same button is pressed but every time I press the button that initiates the set Interval it seems to be creating a new interval and not resetting the one that was already creating. Can someone help please? Here is my code
timer = (TextView) findViewById(R.id.timer_value);
Count = new CountDownTimer(time, 1000) {
public void onTick(long millisUntilFinished) {
timer.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
timer.setText("OUT OF TIME!");
if (time < 10000) {
time = 10000;
}
AlertDialog.Builder builder = new AlertDialog.Builder(
TicTacToe.this);
builder.setMessage("You are Out of Time").setPositiveButton(
"Replay", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// reset the game environment.
Count.onFinish();
// Count.cancel();
Count.start();
new_game(player_name_1);
}
});
AlertDialog alert = builder.create();
alert.show();
}
}.start();
you can use timers
//in global
Timer myTimer
/**
* its kills runnable
*/
public void stopTimer(){
//handler.removeCallbacks(null); //it resets all timer which handler holds
myTimer.cancel();
}
public void setTimer(int time){//give it 5 for 5 secs
final Runnable Update = new Runnable() {
public void run() {
//do sth
}
};
myTimer = new Timer();
myTimerTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
}, 1000, time*1000);
}
If you want to restart your timer, remove Count.onFinish();
Update:
I replaced AlertDialog with a new thread and here is the code that works on my emulator
public class MainActivity extends Activity
{
int time = 10000;
CountDownTimer Count;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView timer = (TextView) findViewById(R.id.timer);
Count = new CountDownTimer(time, 1000) {
public void onTick(long millisUntilFinished) {
timer.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
timer.setText("OUT OF TIME!");
if (time < 10000) {
time = 100000;
}
}
}.start();
}
public void buttonClicked(View view)
{
Log.i("Timer", "Resetting timer");
Count.cancel();
Count.start();
}
}

Use timertask to update clock each X seconds?

I'm trying to update my digital clock using timertask. I have created a function called updateClock() which sets the hours and minutes to the current time but I haven't been able to get it to run periodically. From what I've read in other answers one of the best options is to use timertask however I haven't been able to make any example I found online work inside an Android activity.
This is what I've written so far:
public class MainActivity extends Activity {
TextView hours;
TextView minutes;
Calendar c;
int cur_hours;
int cur_minutes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.clock_home);
hours = (TextView) findViewById(R.id.hours);
minutes = (TextView) findViewById(R.id.minutes);
updateClock();
}
public void updateClock() {
c = Calendar.getInstance();
hours.setText("" + c.get(Calendar.HOUR));
minutes.setText("" + c.get(Calendar.MINUTE));
}
public static void init() throws Exception {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
updateClock(); // ERROR
}
}, 0, 1 * 5000);
}
}
How can I make it work?
Use runOnUiThread for updating Ui from Timer Thread
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
MainActivity.this.runOnUiThread (new Runnable() {
public void run() {
updateClock(); // call UI update method here
}
}));
}
}, 0, 1 * 5000);
}
if you just need updates every minute, you can also listen to the ACTION_TIME_TICK broadcast event.
private boolean timeReceiverAttached;
private final BroadcastReceiver timeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateClock();
}
};
private Handler handler = new Handler();
#Override
protected void onResume() {
super.onResume();
updateClock();
if (!timeReceiverAttached) {
timeReceiverAttached = true;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
registerReceiver(timeReceiver, filter, null, handler);
}
}
#Override
protected void onPause() {
super.onPause();
if (timeReceiverAttached) {
unregisterReceiver(timeReceiver);
timeReceiverAttached = false;
}
}
OR, periodically post the Runnable to the Handler of UI thread. Also, pause and resume tasks to save battery.
public class MyActivity extends Activity {
private final Handler mHandler = new Handler();
private final Timer mTimer = new Timer();
#Override
protected void onResume() {
super.onResume();
mTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
//---update UI---
}
});
}
},0,5000);
}
#Override
protected void onPause() {
super.onPause();
mTimer.cancel();
}
}

Categories

Resources