package in.futuretech.android.reportbatterycharge;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.BatteryManager;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ReportChargeService extends Service {
    private final BroadcastReceiver batteryChargeBroadcastReceiver = new BatteryChargeBroadcastReceiver(this);
    private static final String logTag = ReportChargeService.class.getSimpleName();

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        Log.i(logTag, "Service started");

        IntentFilter batteryChangedFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent batteryStatus = registerReceiver(batteryChargeBroadcastReceiver, batteryChangedFilter);

        reportBatteryState(batteryStatus);

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        // TODO: Can this identifier be saved in a location accessible from both manifest and here?
        Intent restartIntent = new Intent("in.futuretech.android.reportbatterycharge.RESTART_SERVICE");
        sendBroadcast(restartIntent);
        unregisterReceiver(batteryChargeBroadcastReceiver);

        Log.i(logTag, "Service destroyed");
        super.onDestroy();
    }

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

    private void reportBatteryState(Intent intent) {
        ReportChargeTaskParams taskParams = new ReportChargeTaskParams(intent, getDeviceId());
        Log.i(logTag, String.format("Current charge level: %f (Charging: %b)", taskParams.ChargePercent, taskParams.IsCharging));

        new ReportChargeTask().execute(taskParams);
    }

    @SuppressLint("HardwareIds")
    private String getDeviceId() {
        // To identify the device when multiple devices are reporting to the same service
        return Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
    }

    private class BatteryChargeBroadcastReceiver extends BroadcastReceiver {
        private final ReportChargeService reportChargeService;

        public BatteryChargeBroadcastReceiver(ReportChargeService reportChargeService) {
            this.reportChargeService = reportChargeService;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            reportChargeService.reportBatteryState(intent);
        }
    }

    private final class ReportChargeTaskParams {
        ReportChargeTaskParams(Intent intent, String deviceId) {
            DeviceId = deviceId;
            int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
            IsCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                    status == BatteryManager.BATTERY_STATUS_FULL;

            int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

            ChargePercent = level / (float) scale;
        }

        final float ChargePercent;
        final boolean IsCharging;
        final String DeviceId;
    }

    private class ReportChargeTask extends AsyncTask<ReportChargeTaskParams, Void, Void> {

        @Override
        protected Void doInBackground(ReportChargeTaskParams... params) {
            ReportChargeTaskParams actualParams = params[0];

            try {
                URL url = new URL(
                        String.format((Locale)null,
                                "http://192.168.2.5/report-charge/report.php?device=%s&charge=%f&charging=%b",
                                actualParams.DeviceId,
                                actualParams.ChargePercent,
                                actualParams.IsCharging));

                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                try {
                    int responseCode = connection.getResponseCode();
                    if (responseCode < 200) {
                        Log.w(logTag, String.format("Report service unexpected response code: %d", responseCode));
                    } else if (responseCode < 400) {
                        Log.i(logTag, String.format("Report service response code: %d", responseCode));
                    } else {
                        Log.w(logTag, String.format("Report service error code: %d", responseCode));
                    }
                } finally {
                    connection.disconnect();
                }
            } catch (MalformedURLException e) {
                Log.w(logTag, "Report service call failed: Invalid URL");
            } catch (IOException e) {
                Log.w(logTag, "Report service call failed: I/O error");
            }

            return null;
        }
    }
}

@@ -553,16 +553,68 @@
 Locale;%0A
+import java.util.Timer;%0Aimport java.util.TimerTask;%0A
 import j
@@ -933,24 +933,84 @@
 pleName();%0A%0A
+    private Intent batteryStatus;%0A    private Timer timer;%0A%0A
     @Overrid
@@ -1281,23 +1281,16 @@
         
-Intent 
 batteryS
@@ -1382,40 +1382,19 @@
     
-reportBatteryState(batteryStatus
+startTimer(
 );%0A%0A
@@ -1469,24 +1469,46 @@
 Destroy() %7B%0A
+        stopTimer();%0A%0A
         // T
@@ -1794,24 +1794,55 @@
 Receiver);%0A%0A
+        batteryStatus = null;%0A%0A
         Log.
@@ -1984,32 +1984,122 @@
 rn null;%0A    %7D%0A%0A
+    private void reportBatteryState() %7B%0A        reportBatteryState(batteryStatus);%0A    %7D%0A%0A
     private void
@@ -2669,32 +2669,580 @@
 OID_ID);%0A    %7D%0A%0A
+    private void startTimer() %7B%0A        final ReportChargeService that = this;%0A%0A        timer = new Timer();%0A        TimerTask timerTask = new TimerTask() %7B%0A            @Override%0A            public void run() %7B%0A                that.reportBatteryState();%0A            %7D%0A        %7D;%0A%0A        // Also report charge level every 15 minutes, regardless of changes%0A        timer.schedule(timerTask, 0, 15 * 60 * 1000);%0A    %7D%0A%0A    private void stopTimer() %7B%0A        if (timer != null) %7B%0A            timer.cancel();%0A            timer = null;%0A        %7D%0A    %7D%0A%0A
     private clas

Add timer to provide regular battery status updates