Android issue - Using handler while taking picture - android

I am trying to show the total image taking time(timer) to the user in my android application.
What I did:
I am starting the Handler when the fragment starts. (i.e) I have started the handler in my "onCreateView" method as like below.
MainFragment:
private long startTime = 0L;
private long timeInMillies = 0L;
private long timeSwap = 0L;
private long finalTime = 0L;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.capture,
container, false);
TextView textview = (TextView)rootView.findViewById(R.id.timer);
startTime = SystemClock.uptimeMillis();
Handler myHandler = new Handler();
Runnable updateTimer = new Runnable() {
public void run() {
timeInMillies = SystemClock.uptimeMillis() - startTime;
finalTime = timeSwap + timeInMillies;
int seconds = (int) (finalTime / 1000);
seconds = seconds % 60;
int milliseconds = (int) (finalTime % 1000);
milliseconds = milliseconds % 60 ;
textview.setText(String.format("%02d", seconds) + ":" + String.format("%02d", milliseconds) + "s");
myHandler.postDelayed(this, 0);
}
};
myHandler.postDelayed(updateTimer, 0);
.
.
.
return rootView;
}
What I want:
The handler is running well and timer runs without delaying like(00.00, 00.01, 00.02, 00.03, 00.04, ......, 10.32) until I start to call the "camera.takePicture(null, null, pictureCallback);". Once I call the "camera.takePicture" the timer shows the time with some sec delay(00.00, 00.01, 00.02, 00.03, delay, 02.30, 02.31, 02.32, delay, 04.03, 04.04, ......)
#Override
public void onResume() {
super.onResume();
.
.
.
camera.takePicture(null, null, pictureCallback);
}
What would be the problem? Did anyone face this issue? How do I fix this issue?

Related

How to get the value of a handler/runnable timer?

I'm currently using a runnable and handler to have a timer which updates a textview every second.
public class TimerFragment extends Fragment {
TextView tvTimer;
long startTime = 0;
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int)(millis/1000);
int minutes = seconds / 60;
seconds = seconds % 60;
tvTimer.setText(String.format("%d:%02d", minutes, seconds));
timerHandler.postDelayed(this,500);
}
};
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_timer, null);
tvTimer = (TextView)view.findViewById(R.id.tvTimer);
Button btn = (Button)view.findViewById(R.id.btn1);
btn.setText("Start");
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Button b = (Button) v;
if (b.getText().equals("Stop")){
timerHandler.removeCallbacks(timerRunnable);
b.setText("Start Monitoring");
}
else {
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
b.setText("Stop");
Toast.makeText(getActivity(),"Monitoring started.",Toast.LENGTH_SHORT).show();
}
}
});
return view;
}
}
How do i get the value of the timer? Like for example, showing a toast when the text becomes "0:15". I want to be able to get the value so I can use it. The function I have in mind is having the user set a time and have a toast or notification pop up when the timer passes through that time (like 15 or 30 seconds). But right now what I want to know is how to get the value of the timer. Thanks!
You should use a CountDownTimer to set a countdown based on interval set by you and it will stop when the time has come in future
CountDownTimer(long millisInFuture, long countDownInterval)
// Example : I've set countdown for 30 seconds
CountDownTimer countDownTimer = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
text_view.setText(millisUntilFinished / 1000 + " " + "Sec");
}
public void onFinish() {
// implement your code customization here after interval is over
text_view.setText("time over!");
}
}.start();
For more insights refer the Android Developer reference for CountDownTimer

how do i add miliseconds option in this code?

I am learning android. I made this stopwatch app work from my reference book.It only shows Hour:minutes:seconds but I want to add milliseconds right to the seconds.how do I do that.
code::-
public class StopWatchActivity extends AppCompatActivity {
int seconds;
boolean running;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stop_watch);
runTimer();
}
public void startTimer(View view){
running = true;
}
public void stopTimer(View view){
running = false;
}
public void resetTimer(View view){
running = true;
seconds = 0;
}
public void runTimer(){
final TextView textView = (TextView) findViewById(R.id.timer);
final Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
int hours = seconds / 3600;
int minutes = (seconds % 3600) / 60;
int sec = seconds % 60;
String time = String.format("%d:%02d:%02d", hours,
minutes,sec);
textView.setText(time);
if(running) {
seconds++;
}
handler.postDelayed(this, 1000);
}
});
}
}
The first step would be to change the field seconds to milliSeconds because you want to keep track of that TimeUnit.
When restarting your handler with handler.postDelayed(this, 1000); define 1 millisecond as delay instead of 1000 (= 1 Second) like this handler.postDelayed(this, 1); then you just need to adjust your calculations and you are done :-)
An easier solution would be:
Instead of saving the elapsed seconds in your activity, save the time that the timer started (e.g. startTime)
Then, in your handler's runnable, get the current time and subtract the start time to find the elapsed time.
Pseudocode:
long startTimeNanos
public void runTimer() {
startTime = new Date()
final Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
long currentTime = System.nanoTime()
long elapsedNanos = currentTime - startTimeNanos
// calculate seconds and millis
// and set the textview text
handler.postDelayed(this, 1000);
}
});
}
This way, you can change the time that the handler fires and it won't affect anything else.

how to continue timer in app when come back from onRestart state

i've created a small app of memory game. in that app i have created a timer that show the time that take the user to finish the game. my problem is that the timer freeze after i go to another page (like home screen) and back to the game- the time remain at the same time it was stopped.....(i khnow it related somehow to onRestarte() method but dont know what to do..) i want that the timer will continue at the same time it has been stopped. (like if the user have an incall in the middle of the game and then want to continue).
package com.example.kineret.memorygame;
public class Game4x4Activity extends AppCompatActivity implements View.OnClickListener{
TextView timerTextView;
long startTime = 0;
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
timerTextView.setText(String.format("%d:%02d", minutes, seconds));
timerHandler.postDelayed(this, 500);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game4x4);
timerTextView = (TextView) findViewById(R.id.timerTextView4x4);
}
#Override
public void onPause() {
super.onPause();
timerHandler.removeCallbacks(timerRunnable);
}
#Override
public void onClick(View view) {
if(newGame) {
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
newGame = false;
}
// rest of my code...
}
i have edited your code. plz try this
public class Game4x4Activity extends AppCompatActivity implements View.OnClickListener{
// make a new variable
static long elapsedTime = 0;
TextView timerTextView;
long startTime = 0;
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
// change here
long millis = (System.currentTimeMillis() - startTime) + elapsedTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
timerTextView.setText(String.format("%d:%02d", minutes, seconds));
timerHandler.postDelayed(this, 500);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game4x4);
timerTextView = (TextView) findViewById(R.id.timerTextView4x4);
}
#Override
public void onPause() {
// change here
elapsedTime = elapsedTime + (System.currentTimeMillis() - startTime);
timerHandler.removeCallbacks(timerRunnable);
super.onPause();
}
#Override
public void onResume() {
super.onResume();
// change here
if(!newGame) {
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
}
}
If the user gets a phone call your app will call onPause then if they finish their phone call and play your game your activity will get onResume called.
in onPause save the system time, in onResume get the latest system time. Take these away from each other (in onResume) and you will have the time that the user was not in your app, you can then add this to your timer before you restart it.
You may also have to persist this time with onSaveInstanceState at other points.

how to measure the time taken by activities in android

I am working on quiz type application and I want to calculate the time between some activities. for example, my level starts from activity A and ends at activity H. I want to calculate the time taken by all the activities. Can anyone please help me to count the time taken from the first activity to the ending activity?
Declare the variables
//counter of time since app started, a background task
private long mStartTime = 0L;
private TextView mTimeLabel;
//handler to handle the message to the timer task
private Handler mHandler = new Handler();
Start the timer in onCreate or onStart or your own method (click of button)
if(mStartTime==0L){
mStartTime=SystemClock.uptimeMillis();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask,100);
}
timer function
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
final long start = mStartTime;
long millis = SystemClock.uptimeMillis() - start;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
mTimeLabel.setText("" + minutes + ":"
+ String.format("%02d", seconds));
mHandler.postDelayed(this, 200);
}
};
when the app is minimized, pause the timer
#Override
protected void onPause() {
mHandler.removeCallbacks(mUpdateTimeTask);
super.onPause();
}
when the app is resumed, resume the timer
#Override
protected void onResume() {
super.onResume();
mHandler.postDelayed(mUpdateTimeTask, 100);
}

How to set the value of TextView in application?

Hi i want make a timer counter and i want the timer still counting and pause or stop when i click a button but now i can run the timer in app but i cannot set textView on fragment with the value of the timer
How can i set the text in text view ? so it will become a timer ?
here my code :
public class TimerFragment extends BaseFragment {
private ImageView btnPause, btnStop, iconCreditInfo, iconStockOpname, iconOrder, iconReturn;
private TextView timerValue, txtCreditInfo, txtStockOpname, txtOrder, txtReturn, namaClient, keterangan, dateValue;
private long startTime = 0L;
private Handler customHandler = new Handler();
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
private float textSizeBig, imgSizeBig, textSizeSmall, imgSizeSmall;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_timer, container, false);
initialize();
//start-time
/*
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);*/
btnPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// App.appInstance.startTimer();
/*App app = ((App) getActivity().getApplicationContext());
app.afficher();
timerValue.setText(app.getTimer().toString());*/
}
});
//make default icon and text size
creditInfoDefault();
orderDefault();
stockOpnameDefault();
returnDefault();
//set today date
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
Date date = new Date();
dateValue.setText(dateFormat.format(date).toString());
return rootView;
}
#Override
public void onPause() {
super.onPause();
// cancel();
}
#Override
public void onResume() {
super.onResume();
}
private Runnable updateTimerThread = new Runnable() {
public void run() {
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
timerValue.setText("" + mins + ":"
+ String.format("%02d", secs));
customHandler.postDelayed(this, 0);
}
};
}
Here the app code :
public class App extends Application {
public static App appInstance;
private SimpleDateFormat dateFormat;
private long startTime = 0L;
private Handler customHandler = new Handler();
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
private StringBuilder timer;
public StringBuilder getTimer() {
return timer;
}
public void setTimer(StringBuilder timer) {
this.timer = timer;
}
#Override
public void onCreate() {
super.onCreate();
appInstance = this;
dateFormat = new SimpleDateFormat("mm:ss");
}
public void afficher() {
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
timer.append("");
timer.append(mins);
timer.append(":");
timer.append(String.format("%02d", secs));
// Toast.makeText(getBaseContext(),mins).show();
/* timerValue.setText("" + mins + ":"
+ String.format("%02d", secs));*/
customHandler.postDelayed((Runnable) this, 0);
/*
handler.postDelayed(runnable,1000);*/
}
public void startTimer() {
runnable.run();
}
public void stopTimer() {
handler.removeCallbacks(runnable);
}
Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
}
};
}
You could use runOnUiThread.
I am assuming timerValue is your textView.
Inside your Thread :
your_activity.runOnUiThread(new Runnable() {
public void run() {
timerValue.setText("" + mins + ":"+String.format("%02d",secs));
}
});
Or you could use Chronometer widget. Check out this tutorial.

Categories

Resources