Recent

Author Topic: LAMW Timer service  (Read 457 times)

Segator

  • Jr. Member
  • **
  • Posts: 97
    • https://github.com/Nenirey
LAMW Timer service
« on: September 13, 2020, 09:17:51 pm »
Hi @jmpessoa, it's possible to implement a jtimerservice based on jtimer?, the proposed is keep the app running and do general tasks in the background usind the broadcast from the timer service like jdownloadservice but continuously.

jmpessoa

  • Hero Member
  • *****
  • Posts: 1603
Re: LAMW Timer service
« Reply #1 on: September 13, 2020, 09:39:04 pm »

Can you, please,  point out some java/android example?
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

Segator

  • Jr. Member
  • **
  • Posts: 97
    • https://github.com/Nenirey
Re: LAMW Timer service
« Reply #2 on: September 13, 2020, 11:08:54 pm »
i think that it's possible using de jdownloadservice service and replace the downloaded funtion with the jtimer component, i don't see any example but you can based on jdownloadservice not download anything only send a broadcast with the ontimer event.

Segator

  • Jr. Member
  • **
  • Posts: 97
    • https://github.com/Nenirey
Re: LAMW Timer service
« Reply #3 on: September 14, 2020, 04:25:21 pm »
Hi i found this example on https://gist.github.com/mjohnsullivan/403149218ecb480e7759

Example of how to create a long running timer service that survives activity destruction by moving to the foreground, and back to the background when a new activity bind to it.

Code: Pascal  [Select][+][-]
  1. //
  2. //  Copyright 2015  Google Inc. All Rights Reserved.
  3. //
  4. //    Licensed under the Apache License, Version 2.0 (the "License");
  5. //    you may not use this file except in compliance with the License.
  6. //    You may obtain a copy of the License at
  7. //
  8. //        http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. //    Unless required by applicable law or agreed to in writing, software
  11. //    distributed under the License is distributed on an "AS IS" BASIS,
  12. //    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. //    See the License for the specific language governing permissions and
  14. //    limitations under the License.
  15.  
  16. package com.example.google.timerservice;
  17.  
  18. import android.app.Notification;
  19. import android.app.PendingIntent;
  20. import android.app.Service;
  21. import android.content.ComponentName;
  22. import android.content.Intent;
  23. import android.content.ServiceConnection;
  24. import android.os.Binder;
  25. import android.os.Bundle;
  26. import android.os.Handler;
  27. import android.os.IBinder;
  28. import android.os.Message;
  29. import android.support.v4.app.NotificationCompat;
  30. import android.support.v7.app.AppCompatActivity;
  31. import android.util.Log;
  32. import android.view.View;
  33. import android.widget.Button;
  34. import android.widget.TextView;
  35.  
  36. import java.lang.ref.WeakReference;
  37.  
  38. /**
  39.  * Example activity to manage a long-running timer, which survives the destruction of the activity
  40.  * by using a foreground service and notification
  41.  *
  42.  * Add the following to the manifest:
  43.  * <service android:name=".MainActivity$TimerService" android:exported="false" />
  44.  */
  45.  
  46. public class TimerActivity extends AppCompatActivity {
  47.  
  48.     private static final String TAG = TimerActivity.class.getSimpleName();
  49.  
  50.     private TimerService timerService;
  51.     private boolean serviceBound;
  52.  
  53.     private Button timerButton;
  54.     private TextView timerTextView;
  55.  
  56.     // Handler to update the UI every second when the timer is running
  57.     private final Handler mUpdateTimeHandler = new UIUpdateHandler(this);
  58.    
  59.     // Message type for the handler
  60.     private final static int MSG_UPDATE_TIME = 0;
  61.  
  62.     protected void onCreate(Bundle savedInstanceState) {
  63.         super.onCreate(savedInstanceState);
  64.         setContentView(R.layout.activity_main);
  65.  
  66.         timerButton = (Button)findViewById(R.id.timer_button);
  67.         timerTextView = (TextView)findViewById(R.id.timer_text_view);
  68.     }
  69.  
  70.     @Override
  71.     protected void onStart() {
  72.         super.onStart();
  73.         if (Log.isLoggable(TAG, Log.VERBOSE)) {
  74.             Log.v(TAG, "Starting and binding service");
  75.         }
  76.         Intent i = new Intent(this, TimerService.class);
  77.         startService(i);
  78.         bindService(i, mConnection, 0);
  79.     }
  80.  
  81.     @Override
  82.     protected void onStop() {
  83.         super.onStop();
  84.         updateUIStopRun();
  85.         if (serviceBound) {
  86.             // If a timer is active, foreground the service, otherwise kill the service
  87.             if (timerService.isTimerRunning()) {
  88.                 timerService.foreground();
  89.             }
  90.             else {
  91.                 stopService(new Intent(this, TimerService.class));
  92.             }
  93.             // Unbind the service
  94.             unbindService(mConnection);
  95.             serviceBound = false;
  96.         }
  97.     }
  98.  
  99.     public void runButtonClick(View v) {
  100.         if (serviceBound && !timerService.isTimerRunning()) {
  101.             if (Log.isLoggable(TAG, Log.VERBOSE)) {
  102.                 Log.v(TAG, "Starting timer");
  103.             }
  104.             timerService.startTimer();
  105.             updateUIStartRun();
  106.         }
  107.         else if (serviceBound && timerService.isTimerRunning()) {
  108.             if (Log.isLoggable(TAG, Log.VERBOSE)) {
  109.                 Log.v(TAG, "Stopping timer");
  110.             }
  111.             timerService.stopTimer();
  112.             updateUIStopRun();
  113.         }
  114.     }
  115.  
  116.     /**
  117.      * Updates the UI when a run starts
  118.      */
  119.     private void updateUIStartRun() {
  120.         mUpdateTimeHandler.sendEmptyMessage(MSG_UPDATE_TIME);
  121.         timerButton.setText(R.string.timer_stop_button);
  122.     }
  123.  
  124.     /**
  125.      * Updates the UI when a run stops
  126.      */
  127.     private void updateUIStopRun() {
  128.         mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME);
  129.         timerButton.setText(R.string.timer_start_button);
  130.     }
  131.  
  132.     /**
  133.      * Updates the timer readout in the UI; the service must be bound
  134.      */
  135.     private void updateUITimer() {
  136.         if (serviceBound) {
  137.             timerTextView.setText(timerService.elapsedTime() + " seconds");
  138.         }
  139.     }
  140.  
  141.     /**
  142.      * Callback for service binding, passed to bindService()
  143.      */
  144.     private ServiceConnection mConnection = new ServiceConnection() {
  145.  
  146.         @Override
  147.         public void onServiceConnected(ComponentName className, IBinder service) {
  148.             if (Log.isLoggable(TAG, Log.VERBOSE)) {
  149.                 Log.v(TAG, "Service bound");
  150.             }
  151.             TimerService.RunServiceBinder binder = (TimerService.RunServiceBinder) service;
  152.             timerService = binder.getService();
  153.             serviceBound = true;
  154.             // Ensure the service is not in the foreground when bound
  155.             timerService.background();
  156.             // Update the UI if the service is already running the timer
  157.             if (timerService.isTimerRunning()) {
  158.                 updateUIStartRun();
  159.             }
  160.         }
  161.  
  162.         @Override
  163.         public void onServiceDisconnected(ComponentName name) {
  164.             if (Log.isLoggable(TAG, Log.VERBOSE)) {
  165.                 Log.v(TAG, "Service disconnect");
  166.             }
  167.             serviceBound = false;
  168.         }
  169.     };
  170.  
  171.     /**
  172.      * When the timer is running, use this handler to update
  173.      * the UI every second to show timer progress
  174.      */
  175.     static class UIUpdateHandler extends Handler {
  176.  
  177.         private final static int UPDATE_RATE_MS = 1000;
  178.         private final WeakReference<TimerActivity> activity;
  179.  
  180.         UIUpdateHandler(TimerActivity activity) {
  181.             this.activity = new WeakReference<>(activity);
  182.         }
  183.  
  184.         @Override
  185.         public void handleMessage(Message message) {
  186.             if (MSG_UPDATE_TIME == message.what) {
  187.                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
  188.                     Log.v(TAG, "updating time");
  189.                 }
  190.                 activity.get().updateUITimer();
  191.                 sendEmptyMessageDelayed(MSG_UPDATE_TIME, UPDATE_RATE_MS);
  192.             }
  193.         }
  194.     }
  195.  
  196.     /**
  197.      * Timer service tracks the start and end time of timer; service can be placed into the
  198.      * foreground to prevent it being killed when the activity goes away
  199.      */
  200.     public static class TimerService extends Service {
  201.  
  202.         private static final String TAG = TimerService.class.getSimpleName();
  203.  
  204.         // Start and end times in milliseconds
  205.         private long startTime, endTime;
  206.  
  207.         // Is the service tracking time?
  208.         private boolean isTimerRunning;
  209.  
  210.         // Foreground notification id
  211.         private static final int NOTIFICATION_ID = 1;
  212.  
  213.         // Service binder
  214.         private final IBinder serviceBinder = new RunServiceBinder();
  215.  
  216.         public class RunServiceBinder extends Binder {
  217.             TimerService getService() {
  218.                 return TimerService.this;
  219.             }
  220.         }
  221.  
  222.         @Override
  223.         public void onCreate() {
  224.             if (Log.isLoggable(TAG, Log.VERBOSE)) {
  225.                 Log.v(TAG, "Creating service");
  226.             }
  227.             startTime = 0;
  228.             endTime = 0;
  229.             isTimerRunning = false;
  230.         }
  231.  
  232.         @Override
  233.         public int onStartCommand(Intent intent, int flags, int startId) {
  234.             if (Log.isLoggable(TAG, Log.VERBOSE)) {
  235.                 Log.v(TAG, "Starting service");
  236.             }
  237.             return Service.START_STICKY;
  238.         }
  239.  
  240.         @Override
  241.         public IBinder onBind(Intent intent) {
  242.             if (Log.isLoggable(TAG, Log.VERBOSE)) {
  243.                 Log.v(TAG, "Binding service");
  244.             }
  245.             return serviceBinder;
  246.         }
  247.  
  248.         @Override
  249.         public void onDestroy() {
  250.             super.onDestroy();
  251.             if (Log.isLoggable(TAG, Log.VERBOSE)) {
  252.                 Log.v(TAG, "Destroying service");
  253.             }
  254.         }
  255.  
  256.         /**
  257.          * Starts the timer
  258.          */
  259.         public void startTimer() {
  260.             if (!isTimerRunning) {
  261.                 startTime = System.currentTimeMillis();
  262.                 isTimerRunning = true;
  263.             }
  264.             else {
  265.                 Log.e(TAG, "startTimer request for an already running timer");
  266.             }
  267.         }
  268.  
  269.         /**
  270.          * Stops the timer
  271.          */
  272.         public void stopTimer() {
  273.             if (isTimerRunning) {
  274.                 endTime = System.currentTimeMillis();
  275.                 isTimerRunning = false;
  276.             }
  277.             else {
  278.                 Log.e(TAG, "stopTimer request for a timer that isn't running");
  279.             }
  280.         }
  281.  
  282.         /**
  283.          * @return whether the timer is running
  284.          */
  285.         public boolean isTimerRunning() {
  286.             return isTimerRunning;
  287.         }
  288.  
  289.         /**
  290.          * Returns the  elapsed time
  291.          *
  292.          * @return the elapsed time in seconds
  293.          */
  294.         public long elapsedTime() {
  295.             // If the timer is running, the end time will be zero
  296.             return endTime > startTime ?
  297.                     (endTime - startTime) / 1000 :
  298.                     (System.currentTimeMillis() - startTime) / 1000;
  299.         }
  300.  
  301.         /**
  302.          * Place the service into the foreground
  303.          */
  304.         public void foreground() {
  305.             startForeground(NOTIFICATION_ID, createNotification());
  306.         }
  307.  
  308.         /**
  309.          * Return the service to the background
  310.          */
  311.         public void background() {
  312.             stopForeground(true);
  313.         }
  314.  
  315.         /**
  316.          * Creates a notification for placing the service into the foreground
  317.          *
  318.          * @return a notification for interacting with the service when in the foreground
  319.          */
  320.         private Notification createNotification() {
  321.             NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
  322.                     .setContentTitle("Timer Active")
  323.                     .setContentText("Tap to return to the timer")
  324.                     .setSmallIcon(R.mipmap.ic_launcher);
  325.  
  326.             Intent resultIntent = new Intent(this, TimerActivity.class);
  327.             PendingIntent resultPendingIntent =
  328.                     PendingIntent.getActivity(this, 0, resultIntent,
  329.                             PendingIntent.FLAG_UPDATE_CURRENT);
  330.             builder.setContentIntent(resultPendingIntent);
  331.  
  332.             return builder.build();
  333.         }
  334.     }
  335.  
  336. }

Segator

  • Jr. Member
  • **
  • Posts: 97
    • https://github.com/Nenirey
Re: LAMW Timer service
« Reply #4 on: September 15, 2020, 11:23:29 pm »
i am go to try modify the jtimer with the jdownloadservice method and class to improve a jtimerservice  :-[

jmpessoa

  • Hero Member
  • *****
  • Posts: 1603
Re: LAMW Timer service
« Reply #5 on: September 16, 2020, 04:33:41 am »

Yes,

mimic "jdownloadservice" can be more easy!
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

Segator

  • Jr. Member
  • **
  • Posts: 97
    • https://github.com/Nenirey
Re: LAMW Timer service
« Reply #6 on: September 17, 2020, 03:53:31 pm »
I make some progress, i have a concept test attached here, but i have some questions, when you use other service like USSD service and do this:

Code: Pascal  [Select][+][-]
  1. jBroadcastReceiver1.Unregister();

the service is stopped?, auto destroy? or just you no listen then anymore?.

jmpessoa

  • Hero Member
  • *****
  • Posts: 1603
Re: LAMW Timer service
« Reply #7 on: September 17, 2020, 06:59:17 pm »

Quote
or just you no listen then anymore?.

Yes.
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

 

TinyPortal © 2005-2018