BekaKK
BekaKK

Reputation: 2243

Monitor battery level from Service

I am trying to monitor the current battery status using a Service. I wrote some code and I can show the battery level using the log once but I want to monitor the battery level according to a timer every 5 seconds.

public class ServiceStatusUpdate extends Service {
    GPSTracker gps;

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        while (true) {
            new Handler().postDelayed(new Runnable() {
                public void run() {
                    batteryLevel();
                    Log.e("Status changed", "Status changed");
                }
            }, 5000);
            return START_STICKY;
        }
    }

    private void batteryLevel() {
        BroadcastReceiver batteryLevelReceiver = new BroadcastReceiver() {
            public void onReceive(Context context, Intent intent) {
                context.unregisterReceiver(this);
                int rawlevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
                int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
                int level = -1;
                if (rawlevel >= 0 && scale > 0) {
                    level = (rawlevel * 100) / scale;
                }
                Log.e("Batarry status iss", level + "mm");
            }
        };
        IntentFilter batteryLevelFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(batteryLevelReceiver, batteryLevelFilter);
        return;
    }
}

MainActivity.java:

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService(new Intent(this, ServiceStatusUpdate.class));
    }
}

manifest.xml source:

  <receiver
        android:name=".OnBootReceiver"
        android:enabled="true"
        android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

    <service
        android:name=".ServiceStatusUpdate"
        android:enabled="true" />

OnBootReceiver:

public class OnBootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
            //int batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
            Intent serviceLauncher = new Intent(context, ServiceStatusUpdate.class);

            context.startService(serviceLauncher);
        }
    }
}

I am also trying to send an HTTP request every /xxx times. The HTTP request will include some text, the battery status, and latitude and longitude.

I know how to send the request with parameters, but my service is working only once.

Upvotes: 1

Views: 1601

Answers (1)

George Mulligan
George Mulligan

Reputation: 11903

You are unregistering the batteryLevelReceiver after the first time it receives a broadcast. Remove this line from onReceive to continue to receive broadcasts:

context.unregisterReceiver(this);

Also, you probably only want to register and unregister your broadcast receiver once when the server is created/destroyed so you should register in onCreate and unregister in onDestroy.

Here is some code that should be very close to what you want. Note that all of this will run on the UI thread currently.

public class ServiceStatusUpdate extends Service {

    private static final int CHECK_BATTERY_INTERVAL = 5000;

    private GPSTracker gps;
    private double batteryLevel;
    private Handler handler;

    private BroadcastReceiver batInfoReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent batteryIntent) {
            int rawlevel = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

            if (rawlevel >= 0 && scale > 0) {
                batteryLevel = (rawlevel * 100.0) / scale;
            }

            Log.e("Battery status is", batteryLevel + "mm");
        }
    };

    private Runnable checkBatteryStatusRunnable = new Runnable() {
        @Override
        public void run() {
            //DO WHATEVER YOU WANT WITH LATEST BATTERY LEVEL STORED IN batteryLevel HERE...

            // schedule next battery check
            handler.postDelayed(checkBatteryStatusRunnable, CHECK_BATTERY_INTERVAL);
            Log.e("Battery status is", batteryLevel + "mm cached");
        }
    };

    @Override
    public void onCreate() {
        handler = new Handler();
        handler.postDelayed(checkBatteryStatusRunnable, CHECK_BATTERY_INTERVAL);
        registerReceiver(batInfoReceiver,
                new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    }

    @Override
    public void onDestroy() {
        unregisterReceiver(batInfoReceiver);
        handler.removeCallbacks(checkBatteryStatusRunnable);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }
}

Upvotes: 1

Related Questions