Question

I am working on a BlackBerry App that sends a message to the server when the battery level reaches 10%. This is implemented by calling getBatteryStatus() method in the constructor where getBatteryStatus() does the following:

public static void getBatteryStatus() {

      timerBattery = new Timer(); 
      taskBattery = new TimerTask() {
          public void run() {
              UiApplication.getUiApplication().invokeLater(new Runnable() {
                  public void run() {
                      if (DeviceInfo.getBatteryLevel()==10) {
                         try{
                            String freeText="Battery level at 10%";
                            sendBatteryStatus(freeText);
                         }catch(Exception e){}
                      }
                  }
              });
          }
      };

      timerBattery.scheduleAtFixedRate(taskBattery, 0, 20000);
}

The sendBatteryStatus sends the message to the server and cancels the timer. This in effect has sent the message once to the server as requested.

However, what if the user starts charging its handset with the App running as it was (without the constructor being called again)? How will the timer then restart? How will I be able to send the message to the server again next time?

What is the best mechanism to prevent sending multiple messages of battery level at 10% and in effect send a message ONLY once followed by messages being sent again when the battery level is at 10% the next time?

If I do not cancel the timer once the message is sent, the message to the server is sent more than once.

Was it helpful?

Solution

I actually think you would be better off if you got rid of your timer entirely. I don't think a timer will efficiently give you everything you want here.

Luckily, BlackBerry has the SystemListener interface. Implement it like this:

public final class BatteryListener implements SystemListener {

    /** the last battery level we were notified of */
    private int _lastLevel = 0;
    /** the battery percentage at which we send an event */
    private int _threshold = 10;

    public BatteryListener() {
        Application.getApplication().addSystemListener(this);
    }

    public void setThreshold(int value) {
        _threshold = value;
    }

    /** call this to stop listening for battery status */
    public void stopListening() {
        Application.getApplication().removeSystemListener(this);
    }

    private boolean levelChanged(int status) {
        return (status & DeviceInfo.BSTAT_LEVEL_CHANGED) == DeviceInfo.BSTAT_LEVEL_CHANGED;
    }

    public void batteryStatusChange(int status) {
        if (levelChanged(status)) {
            int newLevel = DeviceInfo.getBatteryLevel();
            if (newLevel <= _threshold && _lastLevel > _threshold) {
                // we have just crossed the threshold, with battery draining
                sendBatteryStatus("Battery level at " +
                                  new Integer(newLevel) + "%!");
            }
            _lastLevel = newLevel;
        }
    }

    public void batteryGood() { /** nothing to do */ }      
    public void batteryLow() { /** nothing to do */ }       
    public void powerOff() { /** nothing to do */ }     
    public void powerUp() { /** nothing to do */ }  
}

Then, you can just create and keep one instance of this class, whenever you want your app to start monitoring the battery for you. It will send a message if the battery level drops to 10%. If the user later starts charging again, and then stops charging, and drains past 10% again, another server message will be sent.

private BatteryListener listener;

and

listener = new BatteryListener();   // start monitoring

Obviously, in the above class, you'll either have to add your sendBatteryStatus() method to the class, or pass that class an object who implements the sendBatteryStatus() method.

Note: I would also recommend that you not send your notification to the server on the main thread. You don't show the implementation of sendBatteryStatus(), so maybe you already are. But if not, please use a background thread to notify your server, so the UI isn't frozen.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top