I'm looking for a way to make the Chronometer in Android (preferably 1.6 and upwards) show 10ths of a second while counting up.
Is it possible to do this? If not, is there a free (and preferably open source) library that does the same? Failing that I'll write my ow开发者_Python百科n, but I'd rather use someone else's!
Android's default chronometer widget does not support millisecond formatting.
I have modified the Chronometer widget source code in order to show milliseconds. Download it from github.
Is it possible to do this?
Not really. You could pass a format string that shows tenths of a second, but the Chronometer
itself only updates every second. The update frequency is baked into the code.
If not, is there a free (and preferably open source) library that does the same?
The Chronometer
source is available under the Apache License 2.0, so you can modify it to suit. Find all occurrences of 1000
and change them to 100
, and you're probably most of the way there.
Bear in mind that this Chronometer
can be used in an activity but not an app widget, since customized View
classes are not supported by the app widget framework.
I created an instance of a class that I built inside the Activity
. This new class was an extension of the Android CountDownTimer
class(add the implemented methods)
Here in the constructor you can add the duration in milliseconds and the interval to be 1/10 of a second, that is 100 milliseconds. In the onTick
method, the commands are executed every 1/100th of a second for the given duration. That should work.
TimeCounter is a library that does exactly the same. You won't have to worry about adding and subtracting time when you pause/resume your stop-watch. I am sure this will make your day.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tiempo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" />
<Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start" />
<Button
android:id="@+id/stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
package ar.com.magiapensada.apps.dayoftheweek;
import androidx.appcompat.app.AppCompatActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
public static final int NANOSECONDS_CONVERT = 1000000000;
public static final int MICROSECONDS_CONVERT = 1000;
public static final int SEXAGESIMA_CONVERT = 60;
public static final int SEXAGESIMA_FORMAT_CONVERT = 2;
public static final String BROADCAST_TIME_UPDATE = "BROADCAST_TIME_UPDATE";
private Button start;
private TextView tiempo;
private long inicio;
private Long terminado=null;
private boolean running=false;
private Button stop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.tiempo = (TextView) findViewById(R.id.tiempo);
this.start = (Button) findViewById(R.id.start);
this.stop = (Button) findViewById(R.id.stop);
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent intent) {
String action = intent.getAction();
if (action.equals(BROADCAST_TIME_UPDATE)) {
if ( terminado != null){
String cronometro = getCronometroValue(terminado);
tiempo.setText(cronometro);
terminado=null;
}else{
String cronometro = getCronometroValue(System.nanoTime());
tiempo.setText(cronometro);
}
}
}
};
registerReceiver(broadcastReceiver, new IntentFilter(BROADCAST_TIME_UPDATE));
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MainActivity.this.inicio = System.nanoTime();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
running=true;
terminado=null;
while(running){
sendBroadcast();
}
sendBroadcast();
}
});
t.start();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
terminado = System.nanoTime();
running=false;
}
});
}
private void sendBroadcast() {
Intent intent = new Intent(BROADCAST_TIME_UPDATE);
MainActivity.this.sendBroadcast(intent);
}
private String getCronometroValue(long actual) {
long dif = actual - MainActivity.this.inicio;
long segundos = dif/ NANOSECONDS_CONVERT;
long mili = dif - (segundos*NANOSECONDS_CONVERT);
mili = mili/ MICROSECONDS_CONVERT;
long minutos = segundos / SEXAGESIMA_CONVERT;
segundos = segundos % SEXAGESIMA_CONVERT;
String segString = formatSexagesima(segundos);
String minutosString = formatSexagesima(minutos);
String cronometro = minutosString + ":" + segString + ":" + mili;
return cronometro;
}
private String formatSexagesima(long value ){
return String.format("%0" + SEXAGESIMA_FORMAT_CONVERT + "d", value);
}
}
I have found the way after lots and lots of research. I don't know if it's effective or not, because the truth is that the Emulator crashes after about 10 seconds, but on the phone it runs just fine, and that does it for me. It looks something like this:
import android.os.Handler;
public class Chronometer extends Activity {
private Handler mHandler = new Handler();
public void actions() {
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 1); //1 is the number of milliseconds you want the text to be updated
}
Runnable mUpdateTimeTask = new Runnable() {
public void run() {
i++;
txt.setText(formatTime(i)); // formatTime is just for make it readable in HH:MM:SS:MS, but I assume you already have this
mHandler.postDelayed(this, 1);
}
};
}
精彩评论