Countdown Timer on Android Java - android-studio

I have a quiz application which I have a function that a certain category will only be available once every 24hours in just 15mins. Now I am planning to put a timer same on the flash sale of the eCommerce Application.
Been looking on the internet but those timer are not fix and it will start again from the top if you refresh your Activity. anyone can give me some advice on this matter it will also base the timer for the server time not device time :)
I have found some here in stackoverflow. I want this countdown will always start at 11:15AM and will ends at 11:00AM on the following day and start the countdown again at 11:15AM. It would be better if I can use timezone also that even they change their device time the timer won`t be affected.
private void start_countdown_timer()
{
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy, HH:mm:ss");
formatter.setLenient(false);
String endTime = "18.09.2017, 15:05:36";
long milliseconds=0;
final CountDownTimer mCountDownTimer;
Date endDate;
try {
endDate = formatter.parse(endTime);
milliseconds = endDate.getTime();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
startTime = System.currentTimeMillis();
mCountDownTimer = new CountDownTimer(milliseconds, 1000) {
#Override
public void onTick(long millisUntilFinished) {
startTime=startTime-1;
Long serverUptimeSeconds =
(millisUntilFinished - startTime) / 1000;
String daysLeft = String.format("%d", serverUptimeSeconds / 86400);
//txtViewDays.setText(daysLeft);
Log.d("daysLeft",daysLeft);
String hoursLeft = String.format("%d", (serverUptimeSeconds % 86400) / 3600);
//txtViewHours.setText(hoursLeft);
Log.d("hoursLeft",hoursLeft);
String minutesLeft = String.format("%d", ((serverUptimeSeconds % 86400) % 3600) / 60);
//txtViewMinutes.setText(minutesLeft);
Log.d("minutesLeft",minutesLeft);
String secondsLeft = String.format("%d", ((serverUptimeSeconds % 86400) % 3600) % 60);
//txtViewSecond.setText(secondsLeft);
Log.d("secondsLeft",secondsLeft);
}
#Override
public void onFinish() {
}
}.start();
}

You can store your timer state in local storage (eg. shared preference ) at the time of refreshing your activity. You need to do it activity life cycle onPause method. Then in onResume method, you need to check the timer state whether it is already started or not and update the timer based on that.

Related

Best way to count how much time user spend on your app (Kotlin)

I want to count the time that the user spent in my app then store it and when the user uses the app again we add the new time
there are multiple activities in my app and I'm using MVVM so I think it's best to put the logic in the MVVM
the problem is how to count time
any ideas??
In the view's onStart() tell the view model to start counting time, and in onStop() tell it to stop and persist it.
In the view model, when told to start counting time, store the value of System.currentTimeMillis() in a property. When told to stop, subtract that value from another call to System.currentTimeMillis() and persist it to the model by adding it to the previously recorded value retrieved from the model.
Edit based on comment:
Here's how you can use a coroutine to create a counter that updates a LiveData periodically. Since delays in coroutines aren't perfectly precise, I have it fire four times a second to prevent the timer from noticeably losing or gaining a second from time to time.
private val _secondsUpTime = MutableLiveData<Int>()
val secondsUpTime: LiveData<Int> = _secondsUpTime
private var startTime = -1L
private var counterJob: Job? = null
fun notifyAppStarted() {
startTime = System.currentTimeMillis()
counterJob = viewModelScope.launch {
val lastPersistedLifetime = repo.lifetimeMillis
while (true) {
val totalTime = System.currentTimeMillis() - startTime + lastPersistedLifetime
_secondsUpTime.value = (totalTime / 1000).toInt()
delay(250)
}
}
}
fun notifyAppStopped() {
if (startTime < 0) {
Log.e(TAG, "Tried to notify app stopped without notifying app started first.")
return
}
counterJob?.cancel()
val totalTime = System.currentTimeMillis() - startTime + repo.lifetimeMillis
repo.lifetimeMillis = totalTime // persist to the repository
}

How to filter on Apache Edgent and also show the values which were filtered?

I am using Apache Edgent (Java framework) to poll values from a HCSR04 ultrasonic sensor on a Raspberry Pi every 3 seconds. I use a filter to not get values from 50cm to 80cm.
UltrasonicStream sensor = new UltrasonicStream();
DirectProvider dp = new DirectProvider();
Topology topology = dp.newTopology();
TStream<Double> tempReadings = topology.poll(sensor, 3, TimeUnit.SECONDS);
TStream<Double> filteredReadings = tempReadings.filter(reading -> reading < 50 || reading > 80);
System.out.println("filter added: tempReadings.filter(reading -> reading < 50 || reading > 80);");
filteredReadings.print();
dp.submit(topology);
I want to show some message when the values are filtered. When the values do not match with my filter I can poll them, but when they match I am not returning, that is ok. However, I want just to show that a value was filtered using Apache Edgent libraries. I know that I can do something on the public double get() method, but I wonder if I could do this trick with some method of the Apache Edgent.
public class UltrasonicStream implements Supplier {
private static final long serialVersionUID = -6511218542753341056L;
private static GpioPinDigitalOutput sensorTriggerPin;
private static GpioPinDigitalInput sensorEchoPin;
private static final GpioController gpio = GpioFactory.getInstance();
private double currentDistance = -1.0;
/**
* The HCSR04 Ultrasonic sensor is connected on the physical pin 16 and 18 which
* correspond to the GPIO 04 and 05 of the WiringPi library.
*/
public UltrasonicStream() {
// Trigger pin as OUTPUT
sensorTriggerPin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_04);
// Echo pin as INPUT
sensorEchoPin = gpio.provisionDigitalInputPin(RaspiPin.GPIO_05, PinPullResistance.PULL_DOWN);
}
/**
* This is the override method of the Supplier interface from Apache Edgent
*/
#Override
public Double get() {
try {
System.out.print("Distance in centimeters: ");
currentDistance = getDistance();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return currentDistance;
}
/**
* Retrieve the distance measured by the HCSR04 Ultrasonic sensor connected on a
* Raspberry Pi 3+B
*
* #return the distance in centimeters
* #throws InterruptedException
*/
public double getDistance() throws InterruptedException {
double distanceCM = -1;
try {
// Thread.sleep(2000);
sensorTriggerPin.high(); // Make trigger pin HIGH
Thread.sleep((long) 0.01);// Delay for 10 microseconds
sensorTriggerPin.low(); // Make trigger pin LOW
// Wait until the ECHO pin gets HIGH
while (sensorEchoPin.isLow()) {
}
// Store the current time to calculate ECHO pin HIGH time.
long startTime = System.nanoTime();
// Wait until the ECHO pin gets LOW
while (sensorEchoPin.isHigh()) {
}
// Store the echo pin HIGH end time to calculate ECHO pin HIGH time.
long endTime = System.nanoTime();
distanceCM = ((((endTime - startTime) / 1e3) / 2) / 29.1);
// Printing out the distance in centimeters
// System.out.println("Distance: " + distanceCM + " centimeters");
return distanceCM;
} catch (InterruptedException e) {
e.printStackTrace();
}
return distanceCM;
}
}
You can use TStream.split() to create two streams: one whose tuples match your filter predicate and one for those that don't. You can then do whatever you want with either stream. e.g. TStream.peek(t -> System.out.println("excluded: " + t)), or TStream.print(...)
I implemented like this:
UltrasonicStream sensor = new UltrasonicStream();
DirectProvider dp = new DirectProvider();
Topology topology = dp.newTopology();
TStream<Double> tempReadings = topology.poll(sensor, 3, TimeUnit.SECONDS);
TStream<Double> filteredReadings = tempReadings.filter(reading -> {
boolean threshold = reading < 20 || reading > 80;
if (!threshold) {
System.out.println(String.format("Threshold reached: %s cm", reading));
}
return threshold;
});
filteredReadings.print();
dp.submit(topology);

How to return a value from void in android

Hello I m new to android development I m developing an app which requires to get the hour and minute from timePicker so I did like this to get it:
public class MainActivity extends Activity {
TimePicker timePicker;
int hour, changedHour;
int minute, changedMinute;
TextView tv, tv1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.textView1);
tv1 = (TextView) findViewById(R.id.textView2);
timePicker = (TimePicker) findViewById(R.id.timePicker1);
setCurrentTime();
timePicker.setOnTimeChangedListener(new OnTimeChangedListener() {
#Override
public void onTimeChanged(TimePicker arg0, int hourOfDay,
int minuteOf) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "Time set!",
Toast.LENGTH_SHORT).show();
changedHour = hourOfDay;
changedMinute = minuteOf;
tv.setText("Hour of Day is " + changedHour + " and Minute is "
+ changedMinute);
}
});
tv1.setText("Hour of Day is " + changedHour + " and Minute is "
+ changedMinute);
}
public void setCurrentTime() {
// TODO Auto-generated method stub
final Calendar c = Calendar.getInstance();
hour = c.get(Calendar.HOUR_OF_DAY);
minute = c.get(Calendar.MINUTE);
timePicker.setCurrentHour(hour);
timePicker.setCurrentMinute(minute);
}`
The problem is here
changedHour = hourOfDay;
changedMinute = minuteOf;
tv.setText("Hour of Day is " + changedHour + " and Minute is "
+ changedMinute);
I got the changed time and I set it like hour would be in hourOfDay = changedHour and same for minute now outside the method when I m trying to use the variables the problem is its set to 0 HERE
tv1.setText("Hour of Day is " + changedHour + " and Minute is "
+ changedMinute);
Please help me!
You never actually assign to the changedHour or changedMinute variables before you print them using tv1.setText, since it's very likely that onTimeChanged hasn't ever fired by that point. For this reason, they'll have their default values of 0, since they haven't been assigned anything else yet.
Anyway, you can't return values out of a void function. By definition, void is a lack of a type.
How to fix this depends on how exactly you want the code to work. The path of least resistance would be to set changedHour and changedMinute from within setCurrentTime, e.g.
public void setCurrentTime() {
// TODO Auto-generated method stub
final Calendar c = Calendar.getInstance();
hour = c.get(Calendar.HOUR_OF_DAY);
minute = c.get(Calendar.MINUTE);
// NEW CODE
changedHour = hour;
changedMinute = minute;
// END NEW CODE
timePicker.setCurrentHour(hour);
timePicker.setCurrentMinute(minute);
}
You could return the hour and minute through some other mechanism (return a struct or use out parameters), but given that you update changedHour/Minute in your onTImeChanged callback, it probably wouldn't fit well with the existing flow.
On a re-read though, this could all just be because you're using the wrong variable in tv1.setText. You assign to the class variables hour and minute in setCurrentTime, so you could just print those rather than changedHour and changedMinute, e.g.
tv1.setText("Hour of Day is " + hour + " and Minute is "
+ minute);

How can call keyPressed function after specific time?

i want to use keyPressed function in canvas class. but i do not want immediately call this function.
i try to use wait function but it cause an error ( i think it hasn't any use for this). what should i do?
keyPressed is called by the AMS (Application Management Software) when the user clicks a key. You cannot delay that.
But you can of course call keyPressed yourself as you want. If you want to call keyPressed 10 seconds from now, you should create a Thread with a timer and a loop that asks if 10 seconds has gone by now.
Something like this: (not tested)
class keyPressedAfterSeconds implemments Runnable {
MyCanvasObject myCanvas = null;
int seconds = 10; // Default
long startTime;
public keyPressedAfterSeconds(MyCanvasObject myCanvas, int seconds) {
this.myCanvas = myCanvas;
this.seconds = seconds;
new Thread(this).start();
}
public run() {
startTime = System.currentTimeMillis();
while(System.currentTimeMillis()-startTime<seconds*1000) {
try { // Wait 100 ms and ask again
Thread.sleep(100);
} catch (Exception e) {}
}
myCanvas.keyPressed(someKeycode);
}
}

Thread problem in Windows 7 Phone

Hi
I am working in windows 7 phone based app using silverlight. I have following methods in one of my UI classes, GameScreen.xaml. I am calling startTimer method in the constructor GameScreen. Problem is that when the updateTime method is called and
timeLabel.Text = "Time left: 00 : " + time;
line is executed, the program throws UnauthorizedAccessException on time variable.
private void startTimer()
{
timeThread = new Thread(new ThreadStart(startThread));
timeThread.Start();
}
public void startThread()
{
while (timeLeft > 0)
{
Thread.Sleep(1000);
updateTime();
if (timePassed % 10 == 0)
{
findNextBGResource();
changeBackgroundScene();
}
}
}
private void updateTime()
{
// update the view
String time = timeLeft.ToString();
if (timeLeft < 10)
{
time = "0" + time;
}
if (doUpdateTime && timeLeft >= 0)
{
timeLabel.Text = "Time left: 00 : " + time;
}
}
Can anyone please help me in this regard?
Best Regards...
Basically you can't modify the UI from anything other than the dispatcher thread. Two options:
Use Dispatcher.BeginInvoke to execute your ui-modifying code in the dispatcher thread
Use DispatcherTimer instead of starting a new thread and sleeping - that way the "tick" will occur in the UI thread already.
Are you sure it's on the time variable, not on timeLabel?
You can't usually edit the UI from other threads than the one that handles the UI.

Resources