package com.rai220.securityalarmbot.receivers; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.BatteryManager; import android.support.v4.util.Pair; import com.rai220.securityalarmbot.BotService; import com.rai220.securityalarmbot.R; import com.rai220.securityalarmbot.utils.ChargingType; import java.util.ArrayList; import java.util.List; /** * */ public class BatteryReceiver extends BroadcastReceiver { private BotService botService; private float mBatteryLevel; private String mPowerStatus; private boolean mIsCharging; private int lastTemperature = Integer.MIN_VALUE; private int lastSegmentNotify = -1; private boolean isSentBatteryLow = false; private List<Pair<Integer, Integer>> mSegments = new ArrayList<>(); public BatteryReceiver(BotService botService) { this.botService = botService; fillSegments(); } @Override public void onReceive(Context context, Intent intent) { String message = null; switch (intent.getAction()) { case Intent.ACTION_BATTERY_LOW: if (!isSentBatteryLow) { message = botService.getString(R.string.battery_low); isSentBatteryLow = true; } break; case Intent.ACTION_BATTERY_OKAY: isSentBatteryLow = false; break; case Intent.ACTION_POWER_DISCONNECTED: message = botService.getString(R.string.power_disconnected) + getStatus(); break; case Intent.ACTION_POWER_CONNECTED: message = botService.getString(R.string.power_connected); break; case Intent.ACTION_BATTERY_CHANGED: mBatteryLevel = getBatteryLevel(intent); mPowerStatus = getBatteryStatus(intent); ReceiverStorage.getInstance().setBatteryLevel(mBatteryLevel); int segment = getSegment(mBatteryLevel); if (segment < lastSegmentNotify) { String attention = mIsCharging ? botService.getString(R.string.battery_discharging) : ""; message = attention + getStatus(); } lastSegmentNotify = segment; break; } if (message != null) { botService.getTelegramService().sendMessageToAll(message); } } public String getStatus() { return String.format(botService.getString(R.string.battery_status), Float.toString(mBatteryLevel), mPowerStatus); } public Float getLastTemperature() { if (lastTemperature != Integer.MIN_VALUE) { return (float) lastTemperature / 10; } else { return null; } } private float getBatteryLevel(Intent intent) { int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); return Math.round((level / (float) scale) * 100f); } private String getBatteryStatus(Intent intent) { // Are we charging / charged? int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); mIsCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL; lastTemperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, Integer.MIN_VALUE); ReceiverStorage.getInstance().setBatteryTemperature(getLastTemperature()); // How are we charging? int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); ChargingType chargingType = ChargingType.getType(chargePlug); String chargeSource = chargingType != null ? chargingType.toString() : botService.getString(R.string.unknown); return mIsCharging ? String.format(botService.getString(R.string.charging), chargeSource) : botService.getString(R.string.discharging); } private void fillSegments() { int lowValue = 15; // maximal value, when battery low int segment = 20; // notify every segment's (percent) mSegments.add(new Pair<>(0, 5)); mSegments.add(new Pair<>(5, 10)); mSegments.add(new Pair<>(10, lowValue)); int segmentLength = mSegments.size(); int i = 100; while (i > lowValue) { int from = i - segment; if (from > lowValue) { mSegments.add(segmentLength, new Pair<>(from, i)); } else { mSegments.add(segmentLength, new Pair<>(lowValue, i)); } i -= segment; } } private boolean isIntoSegment(int segment, float value) { Pair<Integer, Integer> pair = null; try { pair = mSegments.get(segment); } catch (Exception ignore) { } return pair != null && (pair.first < value && value <= pair.second); } private int getSegment(float value) { for (Pair<Integer, Integer> pair : mSegments) { if (pair.first < value && value <= pair.second) { return mSegments.indexOf(pair); } } return 0; } }