I'm working on a fragment that includes a timer and a counter. The initial timer value is an edit text. When the timer reaches 0, I want to calculate a rate (# displayed on counter/edit text input.) I've tried to convert both values to doubles, but it seems I went wrong somewhere. When the timer reaches 0, the rate displays "infinity." Any help would be greatly appreciated!
IDs
package com.example.datacollector;
import android.content.ClipData;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import androidx.annotation.NonNull;
import java.util.Locale;
public class fragmentrate extends Fragment {
private EditText edit_text_input;
private TextView text_view_countdown;
private TextView text_view_frequency;
private TextView text_view_rate;
private TextView rate_equals;
private Button button_start_pause;
private Button button_reset;
private Button button_set;
private Button button_frequency;
private Button button_reset_frequency;
private CountDownTimer countDownTimer;
private boolean mTimerRunning;
private long mStartTimeInMillis;
private long mTimeLeftInMillis = mStartTimeInMillis;
private long mEndTime;
private int mCounter;
private double denominator;
View View;
public View onCreateView(#NonNull LayoutInflater inflater, #NonNull ViewGroup container, #NonNull Bundle savedInstanceState) {
View = inflater.inflate(R.layout.rate_fragment, container, false);
text_view_countdown = View.findViewById(R.id.text_view_countdown);
button_start_pause = View.findViewById(R.id.button_start_pause);
button_reset = View.findViewById(R.id.button_reset);
button_frequency = View.findViewById(R.id.button_frequency);
button_reset_frequency = View.findViewById(R.id.button_reset_frequency);
edit_text_input = View.findViewById(R.id.edit_text_input);
button_set = View.findViewById(R.id.button_set);
text_view_frequency = View.findViewById(R.id.text_view_frequency);
text_view_rate = View.findViewById(R.id.text_view_rate);
rate_equals = View.findViewById(R.id.rate_equals);
Counter
button_frequency.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
mCounter ++;
text_view_frequency.setText(Integer.toString(mCounter));
}
});
button_reset_frequency.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
mCounter = 0;
text_view_frequency.setText(Integer.toString(mCounter));
}
});
Timer and rate calculation
button_set.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
String input = edit_text_input.getText().toString();
if (input.length() == 0) {
Toast.makeText(getActivity(), "Fill it in, loser", Toast.LENGTH_SHORT).show();
return;
}
long millisInput = Long.parseLong(input) * 60000;
if (millisInput == 0) {
Toast.makeText(getActivity(), "Please enter a positive number", Toast.LENGTH_SHORT).show();
return;
}
setTime(millisInput);
edit_text_input.setText("");
}
});
button_start_pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
button_reset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
if(mTimerRunning) {
resetTimer();
} else{
resetTimer();
}
}
});
return View;
}
private void setTime(long milliseconds) {
mStartTimeInMillis = milliseconds;
resetTimer();
}
private void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
countDownTimer = new CountDownTimer(mTimeLeftInMillis, 100) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
button_start_pause.setText("Start");
button_start_pause.setVisibility(android.view.View.INVISIBLE);
button_reset.setVisibility(android.view.View.VISIBLE);
try {
double denominator = Integer.parseInt(edit_text_input.getText().toString());
}
catch (NumberFormatException e)
{
double denominator = 0;
}
double rate = ((double)mCounter/denominator);
text_view_rate.setText(Double.toString(rate));
}
}.start();
mTimerRunning = true;
button_start_pause.setText("Pause");
}
private void pauseTimer() {
countDownTimer.cancel();
mTimerRunning = false;
updateCountDownText();
button_start_pause.setText("Start");
}
private void resetTimer() {
if (mTimerRunning) {
countDownTimer.cancel();
mTimeLeftInMillis = (mStartTimeInMillis + 1000);
updateWatchInterface();
startTimer();
} else {
}
mTimeLeftInMillis = (mStartTimeInMillis);
updateCountDownText();
updateWatchInterface();
button_reset.setVisibility(android.view.View.VISIBLE);
button_start_pause.setVisibility(android.view.View.VISIBLE);
}
private void updateCountDownText() {
int minutes = (int) (mTimeLeftInMillis/1000)/60;
int seconds = (int) (mTimeLeftInMillis/1000)%60;
String timeLeftFormatted = String.format(Locale.getDefault(),
timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds));
text_view_countdown.setText(timeLeftFormatted);
}
private void updateWatchInterface() {
if (mTimerRunning) {
edit_text_input.setVisibility(android.view.View.INVISIBLE);
button_set.setVisibility(android.view.View.INVISIBLE);
button_reset.setVisibility(android.view.View.VISIBLE);
button_start_pause.setText("Pause");
} else {
edit_text_input.setVisibility(android.view.View.VISIBLE);
button_set.setVisibility(android.view.View.VISIBLE);
button_reset.setVisibility(android.view.View.VISIBLE);
button_start_pause.setText("Start");
if (mTimeLeftInMillis <100) {
button_start_pause.setVisibility(android.view.View.INVISIBLE);
} else {
button_start_pause.setVisibility(android.view.View.VISIBLE);
}
}
}
#Override
public void onStop() {
super.onStop();
SharedPreferences preferences = this.getActivity().getSharedPreferences("prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putLong("startTimeInMillis", mStartTimeInMillis);
editor.putLong("millisLeft", mTimeLeftInMillis);
editor.putBoolean("timerRunning", mTimerRunning);
editor.putLong("endTime", mEndTime);
editor.apply();
if(countDownTimer !=null); {
countDownTimer.cancel();
}
}
#Override
public void onStart() {
super.onStart();
SharedPreferences preferences = this.getActivity().getSharedPreferences("prefs", Context.MODE_PRIVATE);
mStartTimeInMillis = preferences.getLong("startTimeInMillis", 0);
mTimeLeftInMillis = preferences.getLong("millisLeft", mStartTimeInMillis);
mTimerRunning = preferences.getBoolean("timerRunning", false);
updateCountDownText();
updateWatchInterface();
if (mTimerRunning) {
mEndTime = preferences.getLong("endTime", 0);
mTimeLeftInMillis = mEndTime - System.currentTimeMillis();
if (mTimeLeftInMillis <0) {
mTimeLeftInMillis = 0;
mTimerRunning = false;
updateCountDownText();
updateWatchInterface();
} else {
startTimer();
}
}
}
You are specifically capturing a NumberFormatException, setting the denominator to zero, and then you're dividing by that number. By design, your result will be Infinity.
Quoting from the Java 8 JLS:
Division of a nonzero finite value by a zero results in a signed infinity. The sign is determined by the rule stated above.
https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.17.2
Related
I'm working on a fragment that includes two timers that take user input. Timer B is linked to timer A such that when timer A is started, so is timer B. The purpose of timer A is to count down once. The purpose of timer B is to count down, beep once at 0, reset to the original value, and repeat. The problem I'm having is that when timer B reaches 0, it doesn't reset and start counting down right away. The timer seems to be delayed further by calling ToneGenerator. This results in the two timers becoming more and more out of sync each time timer B resets.
For example, say timer A is set to 10 seconds and timer B is set to 2 seconds.
-The timers are started-
timer A:10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
timer B: 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1
The timer only beeps 3 times (when timer B is at 0,) when it should beep 5 times (5 sets of 2 second intervals = 10 seconds: the value of timer A.) In other words, I'd like timer B to beep when timer A is at 8, 6, 4, 2, and 0.
How might I accomplish this?
I've consulted the forums, YT, and have tried playing around with the value for millisInFuture.
Fragment
public class fragmentdro extends Fragment {
private EditText session_edit_text;
private EditText dro_edit_text;
private TextView session_text_view;
private TextView dro_text_view;
private Button session_start_button;
private Button dro_start_button;
private Button session_reset_button;
private Button dro_reset_button;
private Button session_set_button;
private Button dro_set_button;
private CountDownTimer sessionTimer;
private CountDownTimer droTimer;
private boolean SessionTimerRunning;
private boolean DROTimerRunning;
private long SessionStartTimeInMillis;
private long DROStartTimeInMillis;
private long SessionTimeLeftInMillis = SessionStartTimeInMillis;
private long DROTimeLeftInMillis = DROStartTimeInMillis;
private long SessionEndTime;
private long DROEndTime;
View View;
public View onCreateView(#NonNull LayoutInflater inflater, #NonNull ViewGroup container, #NonNull Bundle savedInstanceState) {
View = inflater.inflate(R.layout.dro_fragment, container, false);
session_edit_text = View.findViewById(R.id.session_edit_text);
dro_edit_text = View.findViewById(R.id.dro_edit_text);
session_text_view = View.findViewById(R.id.session_text_view);
dro_text_view = View.findViewById(R.id.dro_text_view);
session_start_button = View.findViewById(R.id.session_start_button);
dro_start_button = View.findViewById(R.id.dro_start_button);
session_reset_button = View.findViewById(R.id.session_reset_button);
dro_reset_button = View.findViewById(R.id.dro_reset_button);
session_set_button = View.findViewById(R.id.session_set_button);
dro_set_button = View.findViewById(R.id.dro_set_button);
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
ToneGenerator toneGenerator = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
Timer A
session_set_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
String Sessioninput = session_edit_text.getText().toString();
if (Sessioninput.length() == 0) {
Toast.makeText(getActivity(), "Fill it in", Toast.LENGTH_SHORT).show();
return;
}
long millisInput = Long.parseLong(Sessioninput) * 1000;
if (millisInput == 0) {
Toast.makeText(getActivity(), "Please enter a positive number", Toast.LENGTH_SHORT).show();
return;
}
setSessionTime(millisInput);
session_edit_text.setText("");
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
}
});
session_start_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
if (SessionTimerRunning) {
pauseSessionTimer();
resetDROTimer();
} else {
startSessionTimer();
startDROTimer();
}
}
});
session_reset_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
if (SessionTimerRunning) {
resetSessionTimer();
} else {
resetSessionTimer();
}
}
});
public void setSessionTime(long milliseconds) {
SessionStartTimeInMillis = milliseconds;
resetSessionTimer();
}
public void startSessionTimer() {
SessionEndTime = System.currentTimeMillis() + SessionTimeLeftInMillis;
sessionTimer = new CountDownTimer(SessionTimeLeftInMillis, 100) {
#Override
public void onTick(long millisUntilFinished) {
SessionTimeLeftInMillis = millisUntilFinished;
updateSessionText();
}
#Override
public void onFinish() {
SessionTimerRunning = false;
session_start_button.setText("Start");
session_start_button.setVisibility(android.view.View.INVISIBLE);
session_reset_button.setVisibility(android.view.View.VISIBLE);
}
}.start();
SessionTimerRunning = true;
session_start_button.setText("Pause");
}
public void pauseSessionTimer() {
sessionTimer.cancel();
droTimer.cancel();
SessionTimerRunning = false;
DROTimerRunning = false;
session_start_button.setText("Start");
updateSessionText();
}
public void resetSessionTimer() {
if (SessionTimerRunning) {
sessionTimer.cancel();
SessionTimeLeftInMillis = (SessionStartTimeInMillis);
updateSessionInterface();
startSessionTimer();
} else {
SessionTimeLeftInMillis = (SessionStartTimeInMillis);
updateSessionText();
updateSessionInterface();
session_reset_button.setVisibility(android.view.View.VISIBLE);
session_start_button.setVisibility(android.view.View.VISIBLE);
}
}
public void updateSessionText() {
int minutes = (int) (SessionTimeLeftInMillis/1000/60);
int seconds = (int) (SessionTimeLeftInMillis/1000)%60;
String timeLeftFormatted = String.format(Locale.getDefault(),
timeLeftFormatted = String.format(Locale.getDefault(), "%2d:%02d", minutes, seconds));
session_text_view.setText(timeLeftFormatted);
}
public void updateSessionInterface() {
if (SessionTimerRunning) {
session_edit_text.setVisibility(android.view.View.INVISIBLE);
session_set_button.setVisibility(android.view.View.INVISIBLE);
session_reset_button.setVisibility(android.view.View.VISIBLE);
session_start_button.setText("Pause");
} else {
session_edit_text.setVisibility(android.view.View.VISIBLE);
session_set_button.setVisibility(android.view.View.VISIBLE);
session_reset_button.setVisibility(android.view.View.VISIBLE);
session_start_button.setText("Start");
}
}
Timer B
dro_set_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
String DROinput = dro_edit_text.getText().toString();
if (DROinput.length() == 0) {
Toast.makeText(getActivity(), "Fill it in", Toast.LENGTH_SHORT).show();
return;
}
long millisInput = Long.parseLong(DROinput) * 1000;
if (millisInput == 0) {
Toast.makeText(getActivity(), "Please enter a positive number", Toast.LENGTH_SHORT).show();
return;
}
setDROTime(millisInput);
dro_edit_text.setText("");
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
}
});
dro_start_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
if (DROTimerRunning) {
pauseDROTimer();
} else {
startDROTimer();
}
}
});
dro_reset_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
if (DROTimerRunning) {
resetDROTimer();
} else {
resetDROTimer();
}
}
});
return View;
}
public void setDROTime(long milliseconds) {
DROStartTimeInMillis = milliseconds;
resetDROTimer();
}
public void startDROTimer() {
DROEndTime = System.currentTimeMillis() + DROTimeLeftInMillis;
droTimer = new CountDownTimer(DROTimeLeftInMillis, 100) {
#Override
public void onTick(long millisUntilFinished) {
DROTimeLeftInMillis = millisUntilFinished;
updateDROText();
}
#Override
public void onFinish() {
ToneGenerator toneGenerator = new ToneGenerator(AudioManager.STREAM_ALARM, 400);
toneGenerator.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200);
DROTimerRunning = false;
DROTimeLeftInMillis = DROStartTimeInMillis;
updateDROText();
updateDROInterface();
startDROTimer();
}
}.start();
DROTimerRunning = true;
dro_start_button.setText("Pause");
}
public void pauseDROTimer() {
droTimer.cancel();
DROTimerRunning = false;
dro_start_button.setText("Start");
updateDROText();
}
public void resetDROTimer() {
if (DROTimerRunning) {
droTimer.cancel();
DROTimeLeftInMillis = (DROStartTimeInMillis);
updateDROInterface();
startDROTimer();
} else {
DROTimeLeftInMillis = (DROStartTimeInMillis);
updateDROText();
updateDROInterface();
dro_reset_button.setVisibility(android.view.View.VISIBLE);
dro_start_button.setVisibility(android.view.View.VISIBLE);
}
}
public void updateDROText() {
int seconds = (int) (DROTimeLeftInMillis/1000)%60;
String timeLeftFormatted = String.format(Locale.getDefault(),
timeLeftFormatted = String.format(Locale.getDefault(), ":%02d", seconds));
dro_text_view.setText(timeLeftFormatted);
}
public void updateDROInterface() {
if (DROTimerRunning) {
dro_edit_text.setVisibility(android.view.View.INVISIBLE);
dro_set_button.setVisibility(android.view.View.INVISIBLE);
dro_reset_button.setVisibility(android.view.View.VISIBLE);
dro_start_button.setText("Pause");
} else {
dro_edit_text.setVisibility(android.view.View.VISIBLE);
dro_set_button.setVisibility(android.view.View.VISIBLE);
dro_reset_button.setVisibility(android.view.View.VISIBLE);
dro_start_button.setText("Start");
}
}
#Override
public void onStop() {
super.onStop();
SharedPreferences preferences = this.getActivity().getSharedPreferences("prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putLong("SessionStartTimeInMillis", SessionStartTimeInMillis);
editor.putLong("DROStartTimeInMillis", DROStartTimeInMillis);
editor.putLong("MillisLeft", SessionTimeLeftInMillis);
editor.putLong("DROMillisLeft", DROTimeLeftInMillis);
editor.putBoolean("TimerRunning", SessionTimerRunning);
editor.putBoolean("DROTimerRunning", DROTimerRunning);
editor.putLong("EndTime", SessionEndTime);
editor.putLong("DROEndTime", DROEndTime);
if (sessionTimer !=null); {
sessionTimer.cancel();
}
}
#Override
public void onStart() {
super.onStart();
SharedPreferences preferences = this.getActivity().getSharedPreferences("prefs", Context.MODE_PRIVATE);
SessionStartTimeInMillis = preferences.getLong("SessionStartTimeInMillis", 0);
SessionTimeLeftInMillis = preferences.getLong("MillisLeft", SessionTimeLeftInMillis);
SessionTimerRunning = preferences.getBoolean("TimerRunning", false);
DROStartTimeInMillis = preferences.getLong("DROStartTimeInMillis", 0);
DROTimeLeftInMillis = preferences.getLong("DROMillisLeft", DROTimeLeftInMillis);
DROTimerRunning = preferences.getBoolean("DROTimerRunning", false);
updateSessionText();
updateSessionInterface();
updateDROText();
updateDROInterface();
if (SessionTimerRunning) {
SessionEndTime = preferences.getLong("EndTime", 0);
SessionTimeLeftInMillis = SessionEndTime - System.currentTimeMillis();
if (SessionTimeLeftInMillis <0) {
SessionTimeLeftInMillis = 0;
SessionTimerRunning = false;
} else {
startSessionTimer();
}
}
if (DROTimerRunning) {
DROEndTime = preferences.getLong("EndTime", 0);
DROTimeLeftInMillis = DROEndTime - System.currentTimeMillis();
if (DROTimeLeftInMillis <0) {
DROTimeLeftInMillis = 0;
DROTimerRunning = false;
} else {
startDROTimer();
}
}
}
}
I have a timer that I want to loop as soon as it reaches 0.
Resetting the timer in onFinish() seems to be slower than manually resetting the timer via the timer's reset button.
When the timer finishes, it doesn't restart until "0" has shown for a second (maybe at the end of the tick,) effectively adding an extra second to the timer that I don't want.
How can I make this timer restart the instant "0" is displayed?
Imports and fragment
package com.example.datacollector;
import android.content.Context;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import java.util.Locale;
public class fragmentdro extends Fragment {
private EditText session_edit_text;
private EditText dro_edit_text;
private TextView session_text_view;
private TextView dro_text_view;
private Button session_start_button;
private Button dro_start_button;
private Button session_reset_button;
private Button dro_reset_button;
private Button session_set_button;
private Button dro_set_button;
private CountDownTimer sessionTimer;
private CountDownTimer droTimer;
private boolean SessionTimerRunning;
private boolean DROTimerRunning;
private long SessionStartTimeInMillis;
private long DROStartTimeInMillis;
private long SessionTimeLeftInMillis = SessionStartTimeInMillis;
private long DROTimeLeftInMillis = DROStartTimeInMillis;
private long SessionEndTime;
private long DROEndTime;
View View;
public View onCreateView(#NonNull LayoutInflater inflater, #NonNull ViewGroup container, #NonNull Bundle savedInstanceState) {
View = inflater.inflate(R.layout.dro_fragment, container, false);
session_edit_text = View.findViewById(R.id.session_edit_text);
dro_edit_text = View.findViewById(R.id.dro_edit_text);
session_text_view = View.findViewById(R.id.session_text_view);
dro_text_view = View.findViewById(R.id.dro_text_view);
session_start_button = View.findViewById(R.id.session_start_button);
dro_start_button = View.findViewById(R.id.dro_start_button);
session_reset_button = View.findViewById(R.id.session_reset_button);
dro_reset_button = View.findViewById(R.id.dro_reset_button);
session_set_button = View.findViewById(R.id.session_set_button);
dro_set_button = View.findViewById(R.id.dro_set_button);
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
ToneGenerator toneGenerator = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
Buttons
dro_set_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
String DROinput = dro_edit_text.getText().toString();
if (DROinput.length() == 0) {
Toast.makeText(getActivity(), "Fill it in", Toast.LENGTH_SHORT).show();
return;
}
long millisInput = Long.parseLong(DROinput) * 1000;
if (millisInput == 0) {
Toast.makeText(getActivity(), "Please enter a positive number", Toast.LENGTH_SHORT).show();
return;
}
setDROTime(millisInput);
dro_edit_text.setText("");
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
}
});
dro_start_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
if (DROTimerRunning) {
pauseDROTimer();
} else {
startDROTimer();
}
}
});
dro_reset_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
if (DROTimerRunning) {
resetDROTimer();
} else {
resetDROTimer();
}
}
});
return View;
}
Timer
public void setDROTime(long milliseconds) {
DROStartTimeInMillis = milliseconds;
resetDROTimer();
}
public void startDROTimer() {
DROEndTime = System.currentTimeMillis() + DROTimeLeftInMillis;
final int[] secondsLeft = {0};
droTimer = new CountDownTimer(DROTimeLeftInMillis, 100) {
#Override
public void onTick(long ms) {
if (Math.round((float)ms/1000.0f) != secondsLeft[0])
{
secondsLeft[0] = (int) (Math.round((float)ms)/1000.0f);
}
DROTimeLeftInMillis = ms;
updateDROText();
}
#Override
public void onFinish() {
dro_text_view.setText("0");
DROTimerRunning = false;
DROTimeLeftInMillis = DROStartTimeInMillis + 1000;
updateDROText();
updateDROInterface();
startDROTimer();
}
}.start();
DROTimerRunning = true;
dro_start_button.setText("Pause");
}
public void pauseDROTimer() {
droTimer.cancel();
DROTimerRunning = false;
dro_start_button.setText("Start");
updateDROText();
}
public void resetDROTimer() {
if (DROTimerRunning) {
droTimer.cancel();
DROTimeLeftInMillis = (DROStartTimeInMillis + 1000);
updateDROInterface();
startDROTimer();
} else {
DROTimeLeftInMillis = (DROStartTimeInMillis);
updateDROText();
updateDROInterface();
dro_reset_button.setVisibility(android.view.View.VISIBLE);
dro_start_button.setVisibility(android.view.View.VISIBLE);
}
}
public void updateDROText() {
int seconds = (int) (DROTimeLeftInMillis/1000)%60;
String timeLeftFormatted = String.format(Locale.getDefault(),
timeLeftFormatted = String.format(Locale.getDefault(), ":%02d", seconds));
dro_text_view.setText(timeLeftFormatted);
}
public void updateDROInterface() {
if (DROTimerRunning) {
dro_edit_text.setVisibility(android.view.View.INVISIBLE);
dro_set_button.setVisibility(android.view.View.INVISIBLE);
dro_reset_button.setVisibility(android.view.View.VISIBLE);
dro_start_button.setText("Pause");
} else {
dro_edit_text.setVisibility(android.view.View.VISIBLE);
dro_set_button.setVisibility(android.view.View.VISIBLE);
dro_reset_button.setVisibility(android.view.View.VISIBLE);
dro_start_button.setText("Start");
}
}
Prefs
#Override
public void onStop() {
super.onStop();
SharedPreferences preferences = this.getActivity().getSharedPreferences("prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putLong("SessionStartTimeInMillis", SessionStartTimeInMillis);
editor.putLong("DROStartTimeInMillis", DROStartTimeInMillis);
editor.putLong("MillisLeft", SessionTimeLeftInMillis);
editor.putLong("DROMillisLeft", DROTimeLeftInMillis);
editor.putBoolean("TimerRunning", SessionTimerRunning);
editor.putBoolean("DROTimerRunning", DROTimerRunning);
editor.putLong("EndTime", SessionEndTime);
editor.putLong("DROEndTime", DROEndTime);
if (sessionTimer !=null); {
sessionTimer.cancel();
}
}
#Override
public void onStart() {
super.onStart();
SharedPreferences preferences = this.getActivity().getSharedPreferences("prefs", Context.MODE_PRIVATE);
SessionStartTimeInMillis = preferences.getLong("SessionStartTimeInMillis", 0);
SessionTimeLeftInMillis = preferences.getLong("MillisLeft", SessionTimeLeftInMillis);
SessionTimerRunning = preferences.getBoolean("TimerRunning", false);
DROStartTimeInMillis = preferences.getLong("DROStartTimeInMillis", 0);
DROTimeLeftInMillis = preferences.getLong("DROMillisLeft", DROTimeLeftInMillis);
DROTimerRunning = preferences.getBoolean("DROTimerRunning", false);
updateSessionText();
updateSessionInterface();
updateDROText();
updateDROInterface();
if (SessionTimerRunning) {
SessionEndTime = preferences.getLong("EndTime", 0);
SessionTimeLeftInMillis = SessionEndTime - System.currentTimeMillis();
if (SessionTimeLeftInMillis <0) {
SessionTimeLeftInMillis = 0;
SessionTimerRunning = false;
} else {
startSessionTimer();
}
}
if (DROTimerRunning) {
DROEndTime = preferences.getLong("EndTime", 0);
DROTimeLeftInMillis = DROEndTime - System.currentTimeMillis();
if (DROTimeLeftInMillis <0) {
DROTimeLeftInMillis = 0;
ToneGenerator toneGenerator = new ToneGenerator(AudioManager.STREAM_ALARM, 200);
toneGenerator.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 100);
DROTimerRunning = false;
} else {
startDROTimer();
}
}
}
}
You can add an extra 100 ms to your DROTimeLeftInMillis
so it should look like: new CountDownTimer(DROTimeLeftInMillis + 100, 100) { ..
because the onTick method doesn't call immediately, it called a few milliseconds after, so by adding the 100 ms it should deal with the delay and give you the result you expect.
I am making a timer as part of my app. I followed a tutorial, and made some modifications to the program to better suit my needs. However, when I run the app, I get the default value of the timerTextView (defined in xml), or just random numbers. What is going wrong?
Update: Here is the coomplete code for the activity:
public class Main7Activity extends AppCompatActivity {
private TextView countDownText;
private CountDownTimer countDownTimer;
//private long timeLeftInMilliseconds = 1000*60*60*24*7*1;
public TextView textView3;
public TextView textView4;
public TextView textView5;
public TextView textView6;
public long timeLeftInMilliseconds;
//private int daysToGo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main7);
textView3 = (TextView) findViewById(R.id.testText);
textView4 = (TextView) findViewById(R.id.testText2);
textView5 = (TextView) findViewById(R.id.testText3);
textView6 = (TextView) findViewById(R.id.testText4);
//textView3.setText(Integer.toString(Main6Activity.progress2));
Calendar now = Calendar.getInstance();
textView3.setText("LMP date : " + Main6Activity.textView.getText());
int currentDayOfYear = now.get(Calendar.DAY_OF_YEAR);
//Day of year is the LMP date
now.set(Calendar.DAY_OF_YEAR, Main6Activity.progress2);
int lmpDate = now.get(Calendar.DAY_OF_YEAR);
//Day of year is due date
now.add(Calendar.DAY_OF_YEAR, 7*40);
textView4.setText("Due Date: " + now.get(Calendar.DATE) + "-"
+ (now.get(Calendar.MONTH) + 1) + "-" + now.get(Calendar.YEAR));
int dueDate = now.get(Calendar.DAY_OF_YEAR);
if (dueDate < 365 && lmpDate > 82){
dueDate = dueDate + (365);
}
if (lmpDate<82 && lmpDate>49){
dueDate = dueDate + lmpDate;
}
if (lmpDate<50) {
textView5.setText("Congratulations on Delivery");
}
else {
textView5.setText(Integer.toString(dueDate));
}
//textView5.setText(now.getTime().toString());
//int currentDayOfYear = Calendar.DAY_OF_YEAR;
int daysToGo = dueDate - currentDayOfYear;
textView6.setText(Integer.toString(daysToGo));
timeLeftInMilliseconds = 1000*60*60*24*daysToGo;
countDownText = (TextView) findViewById(R.id.weeks);
startTimer();
}
public void startTimer(){
countDownTimer = new CountDownTimer(timeLeftInMilliseconds, 1000) {
#Override
public void onTick(long millisUntilFinished) {
timeLeftInMilliseconds = millisUntilFinished;
updateTimer();
}
#Override
public void onFinish() {
}
}.start();
}
public void updateTimer(){
int weeks = (int) timeLeftInMilliseconds / 604800000;
int days = (int) (timeLeftInMilliseconds % 604800000) / 86400000;
//int hours = (int) (timeLeftInMilliseconds % 86400000) / 3600000;
//int minutes = (int) (timeLeftInMilliseconds % 3600000) / 60000;
int seconds = (int) (timeLeftInMilliseconds % 60000) / 1000;
String timeLeftText;
timeLeftText = "";
if (weeks < 10) timeLeftText += "0";
timeLeftText += weeks;
timeLeftText += ":";
if (days < 10) timeLeftText += "0";
timeLeftText += days;
//timeLeftText += ":";
//if (hours < 10) timeLeftText += "0";
//timeLeftText += hours;
//timeLeftText += ":";
//timeLeftText += minutes;
//timeLeftText += ":";
if (seconds < 10) timeLeftText += "0";
timeLeftText += seconds;
countDownText.setText(timeLeftText);
}
public void editInfo(View v){
Intent intent = new Intent(Main7Activity.this, Main6Activity.class);
startActivity(intent);
}
}
I also need the timer to run in the background. Will this code do that?
Thanks.
Try to declare those variables :
Handler countHandler ;
Runnable countRunnable ;
private final long INTERVAL = 1000 ; // this the interval period which the timer will be triggered each time
Then change your method like this :
public void startTimer(){
countHandler = new Handler() ;
countRunnable = new Runnable() {
#Override
public void run() {
updateTimer();
timeLeftInMilliseconds= timeLeftInMilliseconds - INTERVAL ;
if(timeLeftInMilliseconds>=0){
countHandler.postDelayed(this, INTERVAL) ;
} else {
cancelTimer(); // here timer is finished
}
}
} ;
countHandler.post(countRunnable) ;
}
public void cancelTimer(){
countHandler.removeCallbacks(countRunnable);
}
Try the code below.
Timer_Service.java
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.util.Log;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class Timer_Service extends Service {
public static String str_receiver = "your_package_name.receiver";
private Handler mHandler = new Handler();
Calendar calendar;
SimpleDateFormat simpleDateFormat;
String strDate;
Date date_current, date_diff;
SharedPreferences mpref;
SharedPreferences.Editor mEditor;
private Timer mTimer = null;
public static final long NOTIFY_INTERVAL = 1000;
Intent intent;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mEditor = mpref.edit();
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);
intent = new Intent(str_receiver);
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
strDate = simpleDateFormat.format(calendar.getTime());
Log.e("strDate", strDate);
twoDatesBetweenTime();
}
});
}
}
public String twoDatesBetweenTime() {
try {
date_current = simpleDateFormat.parse(strDate);
} catch (Exception e) {
}
try {
date_diff = simpleDateFormat.parse(mpref.getString("data", ""));
} catch (Exception e) {
}
try {
long diff = date_current.getTime() - date_diff.getTime();
int int_hours = Integer.valueOf(mpref.getString("hours", ""));
long int_timer = TimeUnit.HOURS.toMillis(int_hours);
long long_hours = int_timer - diff;
long diffSeconds2 = long_hours / 1000 % 60;
long diffMinutes2 = long_hours / (60 * 1000) % 60;
long diffHours2 = long_hours / (60 * 60 * 1000) % 24;
if (long_hours > 0) {
String str_testing = diffHours2 + ":" + diffMinutes2 + ":" + diffSeconds2;
Log.e("TIME", str_testing);
fn_update(str_testing);
} else {
mEditor.putBoolean("finish", true).commit();
mTimer.cancel();
}
} catch (Exception e) {
mTimer.cancel();
mTimer.purge();
}
return "";
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("Service finish", "Finish");
}
private void fn_update(String str_time) {
intent.putExtra("time", str_time);
sendBroadcast(intent);
}
}
Your Timer.java activity:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Timer extends AppCompatActivity implements View.OnClickListener {
private Button btn_start, btn_cancel;
private TextView tv_timer;
String date_time;
Calendar calendar;
SimpleDateFormat simpleDateFormat;
EditText et_hours;
SharedPreferences mpref;
SharedPreferences.Editor mEditor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
init();
}
private void init() {
btn_start = (Button) findViewById(R.id.btn_timer);
tv_timer = (TextView) findViewById(R.id.tv_timer);
et_hours = (EditText) findViewById(R.id.et_hours);
btn_cancel = (Button) findViewById(R.id.btn_cancel);
btn_start.setOnClickListener(this);
btn_cancel.setOnClickListener(this);
mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mEditor = mpref.edit();
try {
String str_value = mpref.getString("data", "");
if (str_value.matches("")) {
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
} else {
if (mpref.getBoolean("finish", false)) {
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
} else {
et_hours.setEnabled(false);
btn_start.setEnabled(false);
tv_timer.setText(str_value);
}
}
} catch (Exception e) {
}
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_timer:
if (et_hours.getText().toString().length() > 0) {
int int_hours = Integer.valueOf(et_hours.getText().toString());
if (int_hours <= 24) {
et_hours.setEnabled(false);
btn_start.setEnabled(false);
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
date_time = simpleDateFormat.format(calendar.getTime());
mEditor.putString("data", date_time).commit();
mEditor.putString("hours", et_hours.getText().toString()).commit();
Intent intent_service = new Intent(getApplicationContext(), Timer_Service.class);
startService(intent_service);
} else {
Toast.makeText(getApplicationContext(), "Please select the value below 24 hours", Toast.LENGTH_SHORT).show();
}
/*
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);*/
} else {
Toast.makeText(getApplicationContext(), "Please select value", Toast.LENGTH_SHORT).show();
}
break;
case R.id.btn_cancel:
Intent intent = new Intent(getApplicationContext(), Timer_Service.class);
stopService(intent);
mEditor.clear().commit();
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
break;
}
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String str_time = intent.getStringExtra("time");
tv_timer.setText(str_time);
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(broadcastReceiver, new IntentFilter(Timer_Service.str_receiver));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
}
Your activity_timer.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/et_hours"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:hint="Hours"
android:inputType="time" />
<Button
android:id="#+id/btn_timer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/btn_cancel"
android:text="Start Timer" />
<Button
android:id="#+id/btn_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="cancel timer" />
<TextView
android:id="#+id/tv_timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="00:00:00"
android:textColor="#000000"
android:textSize="25dp" />
</RelativeLayout>
Resource reference: this link.
You need to do some modifications according to your requirement. The countdown will continue even if you close the app.
I have small problem. My problem is auto refresh to list messages.
How can instantly check data such as WhatsApp ?
If you would like to automatically update data came from.
I do not know exactly how I can do , so I'm waiting for your help .
Code
MessagingActivity.java
package com.socialnetwork.activities;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.os.Vibrator;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.socialnetwork.R;
import com.socialnetwork.adapters.MessagesAdapter;
import com.socialnetwork.animation.ViewAudioProxy;
import com.socialnetwork.api.APIService;
import com.socialnetwork.api.ChatAPI;
import com.socialnetwork.api.UsersAPI;
import com.socialnetwork.data.MessagesItem;
import com.socialnetwork.data.userItem;
import com.socialnetwork.helpers.M;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public class MessagingActivity extends AppCompatActivity implements OnClickListener {
public Intent mIntent = null;
private MediaRecorder recorder = null;
private String outFile = null;
private TextView recordTimeText;
private ImageButton audioSendButton;
private View recordPanel;
private View slideText;
private float startedDraggingX = -1;
private float distCanMove = dp(80);
private long startTime = 0L;
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
private Timer timer;
public int RECIPIENT_ID = 0,
CONVERSATION_ID = 0;
public LinearLayoutManager layoutManager;
private EditText messageField;
private String messageBody, USERNAME;
private MessagesAdapter messageAdapter;
private List<MessagesItem> mMessages = new ArrayList<MessagesItem>();
public BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Extract data included in the Intent
Bundle data = intent.getBundleExtra("data");
if (Integer.parseInt(data.getString("ownerID")) == RECIPIENT_ID) {
MessagesItem newMsg = new MessagesItem();
newMsg.setOwnerName(data.getString("ownerName"));
newMsg.setId(Integer.parseInt(data.getString("id")));
newMsg.setMessage(data.getString("message"));
newMsg.setDate(data.getString("date"));
newMsg.setOwnerUsername(data.getString("ownerUsername"));
newMsg.setOwnerPicture(data.getString("ownerPicture"));
newMsg.setOwnerID(Integer.parseInt(data.getString("ownerID")));
newMsg.setConversationID(Integer.parseInt(data.getString("conversationID")));
addMessage(newMsg);
} else {
Intent resultIntent = new Intent(MessagingActivity.this, MessagingActivity.class);
resultIntent.putExtra("data", intent);
M.showNotification(MessagingActivity.this, resultIntent,
data.getString("ownerUsername"),
data.getString("message"),
Integer.parseInt(data.getString("conversationID")));
}
}
};
private RecyclerView messagesList;
private LinearLayout attachLayout;
private RelativeLayout recordPannel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (M.getToken(this) == null) {
Intent mIntent = new Intent(this, LoginActivity.class);
startActivity(mIntent);
finish();
} else {
setContentView(R.layout.messaging);
initializer();
if (getIntent().hasExtra("conversationID")) {
CONVERSATION_ID = getIntent().getExtras().getInt("conversationID");
}
if (getIntent().hasExtra("recipientID")) {
RECIPIENT_ID = getIntent().getExtras().getInt("recipientID");
}
getUser();
getMessages();
}
}
public void initializer() {
messagesList = (RecyclerView) findViewById(R.id.listMessages);
messageAdapter = new MessagesAdapter(this, mMessages);
messagesList.setAdapter(messageAdapter);
//
layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.setStackFromEnd(true);
messagesList.setLayoutManager(layoutManager);
messageField = (EditText) findViewById(R.id.messageField);
attachLayout = (LinearLayout) findViewById(R.id.attachLayout);
recordPannel = (RelativeLayout) findViewById(R.id.record_pannel);
recordPanel = findViewById(R.id.record_panel);
recordTimeText = (TextView) findViewById(R.id.recording_time_text);
slideText = findViewById(R.id.slideText);
audioSendButton = (ImageButton) findViewById(R.id.chat_audio_send_button);
TextView textView = (TextView) findViewById(R.id.slideToCancelTextView);
textView.setText("Slide To Cancel");
//including toolbar and enabling the home button
Toolbar toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
findViewById(R.id.attachBtn).setOnClickListener(this);
findViewById(R.id.sendBtn).setOnClickListener(this);
findViewById(R.id.micBtn).setOnClickListener(this);
audioSendButton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) slideText
.getLayoutParams();
params.leftMargin = dp(30);
slideText.setLayoutParams(params);
ViewAudioProxy.setAlpha(slideText, 1);
startedDraggingX = -1;
startRecording();
audioSendButton.getParent()
.requestDisallowInterceptTouchEvent(true);
recordPanel.setVisibility(View.VISIBLE);
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP
|| motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {
startedDraggingX = -1;
stopRecording();
recordPannel.setVisibility(View.GONE);
} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
float x = motionEvent.getX();
if (x < -distCanMove) {
stopRecording();
}
x = x + ViewAudioProxy.getX(audioSendButton);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) slideText
.getLayoutParams();
if (startedDraggingX != -1) {
float dist = (x - startedDraggingX);
params.leftMargin = dp(30) + (int) dist;
slideText.setLayoutParams(params);
float alpha = 1.0f + dist / distCanMove;
if (alpha > 1) {
alpha = 1;
} else if (alpha < 0) {
alpha = 0;
}
ViewAudioProxy.setAlpha(slideText, alpha);
}
if (x <= ViewAudioProxy.getX(slideText) + slideText.getWidth()
+ dp(30)) {
if (startedDraggingX == -1) {
startedDraggingX = x;
distCanMove = (recordPanel.getMeasuredWidth()
- slideText.getMeasuredWidth() - dp(48)) / 2.0f;
if (distCanMove <= 0) {
distCanMove = dp(80);
} else if (distCanMove > dp(80)) {
distCanMove = dp(80);
}
}
}
if (params.leftMargin > dp(30)) {
params.leftMargin = dp(30);
slideText.setLayoutParams(params);
ViewAudioProxy.setAlpha(slideText, 1);
startedDraggingX = -1;
}
}
view.onTouchEvent(motionEvent);
return true;
}
});
}
private void getUser() {
UsersAPI mUsersAPI = APIService.createService(UsersAPI.class, M.getToken(this));
mUsersAPI.getUser(RECIPIENT_ID, new Callback<userItem>() {
#Override
public void success(userItem userItem, retrofit.client.Response response) {
if (userItem.getName() != null) {
getSupportActionBar().setTitle(userItem.getName());
} else {
getSupportActionBar().setTitle(userItem.getUsername());
}
}
#Override
public void failure(RetrofitError error) {
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
messageAdapter.stop();
}
public void getMessages() {
M.showLoadingDialog(this);
ChatAPI mChatAPI = APIService.createService(ChatAPI.class, M.getToken(this));
mChatAPI.getMessages(CONVERSATION_ID, RECIPIENT_ID, 1, new Callback<List<MessagesItem>>() {
#Override
public void success(List<MessagesItem> messagesItems, Response response) {
mMessages = messagesItems;
messageAdapter.setMessages(messagesItems);
M.hideLoadingDialog();
}
#Override
public void failure(RetrofitError error) {
M.hideLoadingDialog();
M.L(getString(R.string.ServerError));
}
});
}
private void sendMessage() {
messageBody = messageField.getText().toString().trim();
if (!messageBody.isEmpty()) {
ChatAPI mChatAPI = APIService.createService(ChatAPI.class, M.getToken(this));
mChatAPI.addMessage(messageBody, CONVERSATION_ID, RECIPIENT_ID, new Callback<MessagesItem>() {
#Override
public void success(MessagesItem messagesItem, Response response) {
if (messagesItem != null) {
mMessages.add(messagesItem);
messageAdapter.setMessages(mMessages);
messagesList.smoothScrollToPosition(mMessages.size());
messageField.setText("");
} else {
M.T(MessagingActivity.this, getString(R.string.SomethingWentWrong));
}
}
#Override
public void failure(RetrofitError error) {
M.T(MessagingActivity.this, getString(R.string.ServerError));
}
});
}
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.attachBtn) {
if (attachLayout.getVisibility() == View.GONE) {
attachLayout.setVisibility(View.VISIBLE);
} else {
attachLayout.setVisibility(View.GONE);
}
if (recordPannel.getVisibility() == View.VISIBLE) {
recordPannel.setVisibility(View.GONE);
}
} else if (v.getId() == R.id.sendBtn) {
sendMessage();
} else if (v.getId() == R.id.micBtn) {
attachLayout.setVisibility(View.GONE);
recordPannel.setVisibility(View.VISIBLE);
}
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mMessageReceiver, new IntentFilter("update_messages_list"));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mMessageReceiver);
}
public void addMessage(MessagesItem newMsg) {
mMessages.add(newMsg);
messageAdapter.setMessages(mMessages);
messagesList.smoothScrollToPosition(mMessages.size());
}
private void startRecording() {
try {
startRecordingAudio();
} catch (IOException e) {
e.printStackTrace();
}
startTime = SystemClock.uptimeMillis();
timer = new Timer();
MyTimerTask myTimerTask = new MyTimerTask();
timer.schedule(myTimerTask, 1000, 1000);
vibrate();
}
private void stopRecording() {
if (timer != null) {
timer.cancel();
}
if (recordTimeText.getText().toString().equals("00:00")) {
return;
}
recordTimeText.setText("00:00");
vibrate();
Toast.makeText(getApplicationContext(), "Stop Recording", Toast.LENGTH_SHORT).show();
stopRecordingAudio();
}
public void startRecordingAudio() throws IOException {
Toast.makeText(getApplicationContext(), "Start Recording...", Toast.LENGTH_SHORT).show();
SimpleDateFormat timeStampFormat = new SimpleDateFormat(
"yyyy-MM-dd-HH.mm.ss");
String fileName = "audio_" + timeStampFormat.format(new Date())
+ ".mp3";
outFile = "/sdcard/";// Environment.getExternalStorageDirectory().getAbsolutePath();
stopRecordingAudio();
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(outFile + fileName);
recorder.setOnErrorListener(errorListener);
recorder.setOnInfoListener(infoListener);
recorder.prepare();
recorder.start();
}
public void stopRecordingAudio() {
if (recorder != null) {
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}
}
private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
#Override
public void onError(MediaRecorder mr, int what, int extra) {
Toast.makeText(MessagingActivity.this, "Error: " + what + ", " + extra, Toast.LENGTH_SHORT).show();
}
};
private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
#Override
public void onInfo(MediaRecorder mr, int what, int extra) {
Toast.makeText(MessagingActivity.this, "Warning: " + what + ", " + extra, Toast.LENGTH_SHORT).show();
}
};
private void vibrate() {
// TODO Auto-generated method stub
try {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(200);
} catch (Exception e) {
e.printStackTrace();
}
}
public static int dp(float value) {
return (int) Math.ceil(1 * value);
}
class MyTimerTask extends TimerTask {
#Override
public void run() {
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
final String hms = String.format(
"%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(updatedTime)
- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS
.toHours(updatedTime)),
TimeUnit.MILLISECONDS.toSeconds(updatedTime)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS
.toMinutes(updatedTime)));
long lastsec = TimeUnit.MILLISECONDS.toSeconds(updatedTime)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS
.toMinutes(updatedTime));
System.out.println(lastsec + " hms " + hms);
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
if (recordTimeText != null)
recordTimeText.setText(hms);
} catch (Exception e) {
// TODO: handle exception
}
}
});
}
}
}
MessagesFragment.java
public class MessagesFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
public RecyclerView conversationList;
public ConversationsAdapter mConversationsAdapter;
public List<ConversationItem> mConversations = new ArrayList<ConversationItem>();
public Intent mIntent = null;
public int currentPage = 1;
public LinearLayoutManager layoutManager;
private View mView;
private SwipeRefreshLayout mSwipeRefreshLayout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_messages, container, false);
conversationList = (RecyclerView) mView
.findViewById(R.id.conversationsList);
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(R.string.title_messages);
initializeView();
conversationList.setOnScrollListener(new HidingScrollListener(layoutManager) {
#Override
public void onHide() {
}
#Override
public void onShow() {
}
#Override
public void onLoadMore(int currentPage) {
setCurrentPage(currentPage);
getConversations();
}
});
mSwipeRefreshLayout = (SwipeRefreshLayout) mView.findViewById(R.id.swipeMessages);
mSwipeRefreshLayout.setOnRefreshListener(this);
getConversations();
return mView;
}
public void initializeView() {
mConversationsAdapter = new ConversationsAdapter(getActivity(),
mConversations);
conversationList.setAdapter(mConversationsAdapter);
layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
conversationList.setLayoutManager(layoutManager);
}
public void getConversations() {
M.showLoadingDialog(getActivity());
ChatAPI mChatAPI = APIService.createService(ChatAPI.class, M.getToken(getActivity()));
mChatAPI.getConversations(getCurrentPage(), new Callback<List<ConversationItem>>() {
#Override
public void success(List<ConversationItem> conversationItems, retrofit.client.Response response) {
M.L(response.getBody().mimeType());
mConversationsAdapter.setConversations(conversationItems);
M.hideLoadingDialog();
if (mSwipeRefreshLayout.isRefreshing()) {
mSwipeRefreshLayout.setRefreshing(false);
}
}
#Override
public void failure(RetrofitError error) {
M.hideLoadingDialog();
}
});
}
#Override
public void onRefresh() {
setCurrentPage(1);
getConversations();
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
}
WhatsApp is not instant check. It's is more like:
Screen off, check 10x after 30s, next 10x after 1m, next 3x after 5m and so on. and start again if the screen turns off again. WhatsApp is checkin in the background also when you close the app. They are using a service.
i'm using youtubeApi (https://developers.google.com/youtube/android/player/downloads/), I'm looking for a solution for put an onclick listener on the videos on the VideoWall..
package com.android.youbho.Activities;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayer.PlayerStyle;
import com.google.android.youtube.player.YouTubePlayerFragment;
import com.google.android.youtube.player.YouTubeThumbnailLoader;
import com.google.android.youtube.player.YouTubeThumbnailView;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.android.youbho.Utils.Constant;
import com.android.youbho.Utils.FlippingView;
import com.android.youbho.Utils.ImageWallView;
#SuppressLint("NewApi") public class VideoWallActivity extends Activity implements
FlippingView.Listener,
YouTubePlayer.OnInitializedListener,
YouTubeThumbnailView.OnInitializedListener{
private static final int RECOVERY_DIALOG_REQUEST = 1;
/** The player view cannot be smaller than 110 pixels high. */
private static final float PLAYER_VIEW_MINIMUM_HEIGHT_DP = 110;
private static final int MAX_NUMBER_OF_ROWS_WANTED = 4;
// Example playlist from which videos are displayed on the video wall
private static final String PLAYLIST_ID = "PLBA95EAD360E2B0D1";
private static final int INTER_IMAGE_PADDING_DP = 5;
// YouTube thumbnails have a 16 / 9 aspect ratio
private static final double THUMBNAIL_ASPECT_RATIO = 16 / 9d;
private static final int INITIAL_FLIP_DURATION_MILLIS = 100;
private static final int FLIP_DURATION_MILLIS = 500;
private static final int FLIP_PERIOD_MILLIS = 2000;
private ImageWallView imageWallView;
private Handler flipDelayHandler;
private FlippingView flippingView;
private YouTubeThumbnailView thumbnailView;
private YouTubeThumbnailLoader thumbnailLoader;
private YouTubePlayerFragment playerFragment;
private View playerView;
private YouTubePlayer player;
private Dialog errorDialog;
private int flippingCol;
private int flippingRow;
private int videoCol;
private int videoRow;
private boolean nextThumbnailLoaded;
private boolean activityResumed;
private State state;
private static final int id_videoPlayer=99;
private enum State {
UNINITIALIZED,
LOADING_THUMBNAILS,
VIDEO_FLIPPED_OUT,
VIDEO_LOADING,
VIDEO_CUED,
VIDEO_PLAYING,
VIDEO_ENDED,
VIDEO_BEING_FLIPPED_OUT,
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
Toast.makeText(getApplicationContext(), "lol:" + position, Toast.LENGTH_LONG).show();
return view;
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB) #SuppressLint("NewApi") #Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
state = State.UNINITIALIZED;
ViewGroup viewFrame = new FrameLayout(this);
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int maxAllowedNumberOfRows = (int) Math.floor((displayMetrics.heightPixels / displayMetrics.density) / PLAYER_VIEW_MINIMUM_HEIGHT_DP);
int numberOfRows = Math.min(maxAllowedNumberOfRows, MAX_NUMBER_OF_ROWS_WANTED);
int interImagePaddingPx = (int) displayMetrics.density * INTER_IMAGE_PADDING_DP;
int imageHeight = (displayMetrics.heightPixels / numberOfRows) - interImagePaddingPx;
int imageWidth = (int) (imageHeight * THUMBNAIL_ASPECT_RATIO);
imageWallView = new ImageWallView(this, imageWidth, imageHeight, interImagePaddingPx);
viewFrame.addView(imageWallView, MATCH_PARENT, MATCH_PARENT);
thumbnailView = new YouTubeThumbnailView(this);
thumbnailView.initialize(Constant.DEVELOPER_KEY, this);
flippingView = new FlippingView(this, this, imageWidth, imageHeight);
flippingView.setFlipDuration(INITIAL_FLIP_DURATION_MILLIS);
viewFrame.addView(flippingView, imageWidth, imageHeight);
playerView = new FrameLayout(this);
playerView.setId(id_videoPlayer);
playerView.setVisibility(View.INVISIBLE);
viewFrame.addView(playerView, imageWidth, imageHeight);
playerFragment = YouTubePlayerFragment.newInstance();
playerFragment.initialize(Constant.DEVELOPER_KEY, this);
getFragmentManager().beginTransaction().add(id_videoPlayer, playerFragment).commit();
flipDelayHandler = new FlipDelayHandler();
setContentView(viewFrame);
}
#Override
public void onInitializationSuccess(YouTubeThumbnailView thumbnailView, YouTubeThumbnailLoader thumbnailLoader) {
thumbnailView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "lol! ", Toast.LENGTH_LONG).show();
}
});
this.thumbnailLoader = thumbnailLoader;
thumbnailLoader.setOnThumbnailLoadedListener(new ThumbnailListener());
maybeStartDemo();
}
#Override
public void onInitializationFailure(YouTubeThumbnailView thumbnailView, YouTubeInitializationResult errorReason) {
if (errorReason.isUserRecoverableError()) {
if (errorDialog == null || !errorDialog.isShowing()) {
errorDialog = errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST);
errorDialog.show();
}
} else {
String errorMessage = String.format( errorReason.toString());
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
}
}
#Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasResumed) {
VideoWallActivity.this.player = player;
player.setPlayerStyle(PlayerStyle.CHROMELESS);
player.setPlayerStateChangeListener(new VideoListener());
maybeStartDemo();
}
#Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult errorReason) {
if (errorReason.isUserRecoverableError()) {
if (errorDialog == null || !errorDialog.isShowing()) {
errorDialog = errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST);
errorDialog.show();
}
} else {
String errorMessage = String.format( errorReason.toString());
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
}
}
private void maybeStartDemo() {
if (activityResumed && player != null && thumbnailLoader != null && state.equals(State.UNINITIALIZED)) {
thumbnailLoader.setPlaylist(PLAYLIST_ID); // loading the first thumbnail will kick off demo
state = State.LOADING_THUMBNAILS;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RECOVERY_DIALOG_REQUEST) {
// Retry initialization if user performed a recovery action
if (errorDialog != null && errorDialog.isShowing()) {
errorDialog.dismiss();
}
errorDialog = null;
playerFragment.initialize(Constant.DEVELOPER_KEY, this);
thumbnailView.initialize(Constant.DEVELOPER_KEY, this);
}
}
#Override
protected void onResume() {
super.onResume();
activityResumed = true;
if (thumbnailLoader != null && player != null) {
if (state.equals(State.UNINITIALIZED)) {
maybeStartDemo();
} else if (state.equals(State.LOADING_THUMBNAILS)) {
loadNextThumbnail();
} else {
if (state.equals(State.VIDEO_PLAYING)) {
player.play();
}
flipDelayHandler.sendEmptyMessageDelayed(0, FLIP_DURATION_MILLIS);
}
}
}
#Override
protected void onPause() {
flipDelayHandler.removeCallbacksAndMessages(null);
activityResumed = false;
super.onPause();
}
#Override
protected void onDestroy() {
if (thumbnailLoader != null) {
thumbnailLoader.release();
}
super.onDestroy();
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB) private void flipNext() {
if (!nextThumbnailLoaded || state.equals(State.VIDEO_LOADING)) {
return;
}
if (state.equals(State.VIDEO_ENDED)) {
flippingCol = videoCol;
flippingRow = videoRow;
state = State.VIDEO_BEING_FLIPPED_OUT;
} else {
Pair<Integer, Integer> nextTarget = imageWallView.getNextLoadTarget();
flippingCol = nextTarget.first;
flippingRow = nextTarget.second;
}
flippingView.setX(imageWallView.getXPosition(flippingCol, flippingRow));
flippingView.setY(imageWallView.getYPosition(flippingCol, flippingRow));
flippingView.setFlipInDrawable(thumbnailView.getDrawable());
flippingView.setFlipOutDrawable(imageWallView.getImageDrawable(flippingCol, flippingRow));
imageWallView.setImageDrawable(flippingCol, flippingRow, thumbnailView.getDrawable());
imageWallView.hideImage(flippingCol, flippingRow);
flippingView.setVisibility(View.VISIBLE);
flippingView.flip();
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB) #Override
public void onFlipped(FlippingView view) {
imageWallView.showImage(flippingCol, flippingRow);
flippingView.setVisibility(View.INVISIBLE);
if (activityResumed) {
loadNextThumbnail();
if (state.equals(State.VIDEO_BEING_FLIPPED_OUT)) {
state = State.VIDEO_FLIPPED_OUT;
} else if (state.equals(State.VIDEO_CUED)) {
videoCol = flippingCol;
videoRow = flippingRow;
playerView.setX(imageWallView.getXPosition(flippingCol, flippingRow));
playerView.setY(imageWallView.getYPosition(flippingCol, flippingRow));
imageWallView.hideImage(flippingCol, flippingRow);
playerView.setVisibility(View.VISIBLE);
player.play();
state = State.VIDEO_PLAYING;
} else if (state.equals(State.LOADING_THUMBNAILS) && imageWallView.allImagesLoaded()) {
state = State.VIDEO_FLIPPED_OUT; // trigger flip in of an initial video
flippingView.setFlipDuration(FLIP_DURATION_MILLIS);
flipDelayHandler.sendEmptyMessage(0);
}
}
}
private void loadNextThumbnail() {
nextThumbnailLoaded = false;
if (thumbnailLoader.hasNext()) {
thumbnailLoader.next();
} else {
thumbnailLoader.first();
}
}
/**
* A handler that periodically flips an element on the video wall.
*/
#SuppressLint("HandlerLeak")
private final class FlipDelayHandler extends Handler {
#Override
public void handleMessage(Message msg) {
flipNext();
sendEmptyMessageDelayed(0, FLIP_PERIOD_MILLIS);
}
}
/**
* An internal listener which listens to thumbnail loading events from the
* {#link YouTubeThumbnailView}.
*/
private final class ThumbnailListener implements YouTubeThumbnailLoader.OnThumbnailLoadedListener {
#Override
public void onThumbnailLoaded(YouTubeThumbnailView thumbnail, String videoId) {
nextThumbnailLoaded = true;
if (activityResumed) {
if (state.equals(State.LOADING_THUMBNAILS)) {
flipNext();
} else if (state.equals(State.VIDEO_FLIPPED_OUT)) {
// load player with the video of the next thumbnail being flipped in
state = State.VIDEO_LOADING;
player.cueVideo(videoId);
}
}
}
#Override
public void onThumbnailError(YouTubeThumbnailView thumbnail, YouTubeThumbnailLoader.ErrorReason reason) {
loadNextThumbnail();
}
}
private final class VideoListener implements YouTubePlayer.PlayerStateChangeListener {
#Override
public void onLoaded(String videoId) {
state = State.VIDEO_CUED;
}
#Override
public void onVideoEnded() {
state = State.VIDEO_ENDED;
imageWallView.showImage(videoCol, videoRow);
playerView.setVisibility(View.INVISIBLE);
}
#Override
public void onError(YouTubePlayer.ErrorReason errorReason) {
if (errorReason == YouTubePlayer.ErrorReason.UNEXPECTED_SERVICE_DISCONNECTION) {
// player has encountered an unrecoverable error - stop the demo
flipDelayHandler.removeCallbacksAndMessages(null);
state = State.UNINITIALIZED;
thumbnailLoader.release();
thumbnailLoader = null;
player = null;
} else {
state = State.VIDEO_ENDED;
}
}
// ignored callbacks
#Override
public void onVideoStarted() { }
#Override
public void onAdStarted() { }
#Override
public void onLoading() { }
}
}
In this way, there are a list of videos in the playlist, each video will start automatically when the first is finished. I need to click each video in the wall for start it
You can add an onClickListener to the ImageViews in the ImageWallView.java class, something like this:
for (int col = 0; col < numberOfColumns; col++) {
for (int row = 0; row < numberOfRows; row++) {
int elementIdx = getElementIdx(col, row);
if (images[elementIdx] == null) {
ImageView thumbnail = new ImageView(context);
thumbnail.setLayoutParams(new LayoutParams(imageWidth, imageHeight));
images[elementIdx] = thumbnail;
unInitializedImages.add(elementIdx);
thumbnail.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ImageWallView.this.context.startActivity(YouTubeIntents.createPlayVideoIntentWithOptions(
ImageWallView.this.context, (String)v.getTag(), true, false));
}
});
}
addView(images[elementIdx]);
}
}
Then you will need to add the video id as the tag in YouTubeThumbnailView in VideoWallActivity.java
Hope that helps
You can use ImageView OnClickListener as suggested in previous answer: (onSizeChanged in ImageWallView.java)
for (int col = 0; col < numberOfColumns; col++) {
for (int row = 0; row < numberOfRows; row++) {
int elementIdx = getElementIdx(col, row);
if (images[elementIdx] == null) {
ImageView thumbnail = new ImageView(context);
thumbnail.setLayoutParams(new LayoutParams(imageWidth, imageHeight));
images[elementIdx] = thumbnail;
unInitializedImages.add(elementIdx);
thumbnail.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ImageWallView.this.context.startActivity(YouTubeIntents.createPlayVideoIntentWithOptions(
ImageWallView.this.context, (String)v.getTag(), true, false));
}
});
}
addView(images[elementIdx]);
}
}
Then you need to store video id to the calling view of ImageWallView . (set and get tag is also used to store objects between views).
To get the child view of ImageWallView, use imageWallView.getChildAt(index). index is the position of ImageView which is clicked on ImageWallView. to get this index, use getElementIdx(col,row). You need to make this method public in ImageWallView.java.
EDITED
To use the Video ID of current thumbnail, Store the VideoID in onFlipped event. This is because onThumbnailLoaded the VideoID of next thumbnail available which immediately get Flipped and available on IamgeWallView. As VideoID is not available in onFlipped event, use it from onThumbnailLoaded event
Here it is:
Declare below string in class
private String strThumbnailVideoId;
set VideoID in onThumbnailLoaded event (in VideoWallActivity.java) into strThumbnailVideoId. This video ID will be of next thumbnail which will be flipped.
#Override
public void onThumbnailLoaded(YouTubeThumbnailView thumbnail, String videoId) {
nextThumbnailLoaded = true;
strThumbnailVideoId = videoId;
if (activityResumed) {
if (state.equals(State.LOADING_THUMBNAILS)) {
flipNext();
} else if (state.equals(State.VIDEO_FLIPPED_OUT)) {
// load player with the video of the next thumbnail being flipped in
state = State.VIDEO_LOADING;
player.cueVideo(videoId);
}
}
}
Now set the strThumbnailVideoId in onFlipped as a ImageWallView tag.
#Override
public void onFlipped(FlippingView view) {
imageWallView.showImage(flippingCol, flippingRow);
flippingView.setVisibility(View.INVISIBLE);
imageWallView.getChildAt(imageWallView.getElementIdx(flippingCol, flippingRow)).setTag(strThumbnailVideoId);
......
......