Introduction
A non-visible extension that acts like a stopwatch in your app and is accurate to 1/1000 of a second (one millisecond).
Doesn't work when screen on.
Package name: com.gordonlu.stopwatch
Version: 1
Release date: 2022-03-30T07:30:00Z
Documentation
Event blocks
Timer
This event is fired when the timer has gone off.
Parameters: minutes = number (int), seconds = number (int), milliseconds = number (int)
Method blocks
IsRunning
Checks whether the stopwatch is currently running.
Returns: boolean
Pause
Pauses the stopwatch so that after one millisecond, the event will not be fired anymore. You will have to resume the timer to continue firing.
Resume
Resumes the stopped stopwatch.
Start
Starts the timer so that after one millisecond, the Timer event will be fired.
Stop
Stops the timer so that after one millisecond, the event will not be fired anymore. When this is called, the extension will fire one last Timer event for 0 minutes, 0 seconds and 0 milliseconds. To time again, you will have to start the timer again.
Why this extension?
The Clock component has been used for years by AI2 developers. Although it is useful, it is only accurate to at least 1/100th of a second. This extension is accurate to 1/1000th of a second, which is one millisecond.
Tests
Tested successfully on:
-
aiStarter emulator, Android 2.2.
-
Google Pixel 2, Android 6.
-
Google Pixel 2, Android 7.1.
-
Xiaom 5G NE, Android 11.
-
Google Pixel 5, Android 13.
Downloads
AIX:
com.gordonlu.stopwatch.aix (8.4 KB)
AIA: StopWatch.aia (11.8 KB)
What's inside the AIA file?
-
4 buttons for start, pause, resume and stop.
-
1 clock accurate to 1/10th of a second to check the state of whether the stopwatch is running.
-
the stopwatch extension.
-
1 label to show the stopwatch progress.
Open Source
Taken from here.
Here you go.
package com.gordonlu.stopwatch;
import android.app.Activity;
import android.content.Context;
import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;
import com.google.appinventor.components.runtime.EventDispatcher;
import android.os.Handler;
import android.os.SystemClock;
import java.lang.Runnable;
@DesignerComponent(
version = 1,
description = "A non-visible extension that acts like a stopwatch in your app and is accurate to 1/1000 of a second (one millisecond).<br><br>Made by Gordon Lu (AICODE).",
category = ComponentCategory.EXTENSION,
nonVisible = true,
iconName = "https://docs.google.com/drawings/d/e/2PACX-1vQCI87PHLBF0jb8QWyYmIRQSjjNW3EFXf-qpsWCvBYkUQ9vEgPAB8SpxcMpblxNpbIYrjCjLrRLIU2c/pub?w=16&h=16")
@SimpleObject(external = true)
//Libraries
@UsesLibraries(libraries = "")
//Permissions
@UsesPermissions(permissionNames = "")
public class Stopwatch extends AndroidNonvisibleComponent {
//Activity and Context
private Context context;
private Activity activity;
long MillisecondTime, StartTime, TimeBuff, UpdateTime = 0L ;
boolean paused = true;
int Seconds, Minutes, MilliSeconds;
Handler handler = new Handler();
public Stopwatch(ComponentContainer container){
super(container.$form());
this.activity = container.$context();
this.context = container.$context();
}
@SimpleFunction(description = "Starts the timer.")
public void Start() {
StartTime = SystemClock.uptimeMillis();
handler.postDelayed(runnable, 0);
paused = false;
}
@SimpleFunction(description = "Pauses the timer.")
public void Pause() {
TimeBuff += MillisecondTime;
handler.removeCallbacks(runnable);
paused = true;
}
@SimpleFunction(description = "Resumes the paused timer.")
public void Resume() {
Start();
paused = false;
}
@SimpleFunction(description = "Stops and resets the timer.")
public void Stop() {
Pause();
MillisecondTime = 0L;
StartTime = 0L;
TimeBuff = 0L;
UpdateTime = 0L;
Seconds = 0;
Minutes = 0;
MilliSeconds = 0;
Timer(0, 0, 0);
paused = true;
}
@SimpleEvent(description = "This event is fired when the timer has gone off.")
public void Timer(int minutes, int seconds, int milliseconds) {
EventDispatcher.dispatchEvent(this, "Timer", minutes, seconds, milliseconds);
}
@SimpleFunction(description = "Checks whether the stopwatch is currently running.")
public boolean IsRunning() {
return !paused;
}
public Runnable runnable = new Runnable() {
public void run() {
MillisecondTime = SystemClock.uptimeMillis() - StartTime;
UpdateTime = TimeBuff + MillisecondTime;
Seconds = (int) (UpdateTime / 1000);
Minutes = Seconds / 60;
Seconds = Seconds % 60;
MilliSeconds = (int) (UpdateTime % 1000);
Timer(Minutes, Seconds, MilliSeconds);
handler.postDelayed(runnable, 0);
}
};
}
Rate my extension!
- Good extension!
- Bad extension.
Made with Niotron IDE.
Kindly PM me if you have any questions! Also, if you like my extension, please like it! It takes some effort for me to make it...
Votes and likes tell me the general user feedback of my extension. If you read this extension, please take 20 seconds to drop by and give a vote / like!
If you have any features that you want to add and you know the code, PM me or directly reply below using the button.
Gordon Lu