Monitoring battery use • • • • • • New app, BatteryMonitor Add permission: BATTERY_STATS The battery is monitored by receiving broadcasts of battery state information Register to receive broadcasts In onCreate add – IntentFilter batteryLevelFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); – registerReceiver(batteryLevelReceiver, batteryLevelFilter); Add broadcast receiver as activity member variable. – 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("DEBUG","Battery Level Remaining: " + level + "%"); – } – }; • run Show more battery things • • • Add member variable – TextView textView; – String batteryStr = new String(); Add TextView to layout – Set Misc.LayoutHeight = fill_parent – Set Misc.LayoutWidth = fill_parent In onCreate, add – textView = (TextView)findViewById(R.id.TextView01); – textView.setMovementMethod(new ScrollingMovementMethod()); • In batteryLevelReceiver.onReceive, add to beginning – batteryStr += "------------------------------------------------\n"; – Calendar calendar = new GregorianCalendar(); – batteryStr += "time: "+calendar.get(Calendar.HOUR)+":"+calendar.get(Calendar.MINUTE)+":"+calendar.get(Calendar.SECOND)+" \n"; • Change Log.e("DEBUG","Battery Level Remaining: " + level + "%");, to – batteryStr += "Battery Level Remaining: " + level + "%\n"; • At the end of batteryLevelReceiver.onReceive, add – textView.setText(batteryStr); • Run – Plug and unplug until textview is full and check that view is scrollable Battery plugged state • In batteryLevelReceiver.onReciever, before textView.setText…, add – int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); – switch (plugged) { – case 0: – batteryStr += "unplugged\n"; – break; – case BatteryManager.BATTERY_PLUGGED_AC: – batteryStr += "Plugged into AC\n"; – break; – case BatteryManager.BATTERY_PLUGGED_USB: – batteryStr += "Plugged into USB\n"; – break; – default: batteryStr += "unknown plugged state\n"; – } • • • • • • • • • • • • • • • • • • • • • Battery status int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); switch (status) { case BatteryManager.BATTERY_STATUS_CHARGING: batteryStr += "battery is charging\n"; break; case BatteryManager.BATTERY_STATUS_DISCHARGING: batteryStr += "battery is discharging\n"; break; case BatteryManager.BATTERY_STATUS_FULL: batteryStr += "battery is full\n"; break; case BatteryManager.BATTERY_STATUS_NOT_CHARGING: batteryStr += "battery is not charging\n"; break; case BatteryManager.BATTERY_STATUS_UNKNOWN : batteryStr += "battery status is unknown\n"; break; default: batteryStr += "battery status should not happen\n"; break; } Battery type, temperature, voltage, • String tech = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY); • batteryStr += "technology: " + tech +"\n"; • int temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1); • batteryStr += "temp: " + temp+"\n"; • int voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1); • batteryStr += "voltage: " + voltage+"\n"; • • • • • • • • • • • • • • • • • • • • • • • • • • • • Battery health int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH,-1); switch (health) { /*case BatteryManager.BATTERY_HEALTH_COLD: batteryStr += "health = cold\n"; break; //in documentation, but not supported */ case BatteryManager.BATTERY_HEALTH_DEAD: batteryStr += "health = dead\n"; break; case BatteryManager.BATTERY_HEALTH_GOOD: batteryStr += "health = good\n"; break; case BatteryManager.BATTERY_HEALTH_OVERHEAT: batteryStr += "health = overheat\n"; break; case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: batteryStr += "health = over voltage\n"; break; case BatteryManager.BATTERY_HEALTH_UNKNOWN: batteryStr += "health = unknown\n"; break; case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: batteryStr += "health = unspecified failure\n"; break; default: batteryStr += "health state: should not happen\n"; break; } More fun with battery level • Let’s estimate battery charge/discharge rate • Add member variables – long lastTime = 0; – double lastLevel; • After level is computed, add – double rate = 0; – double terminationTime=0; – if (lastTime!=0) { • rate = (level - lastLevel)/(calendar.getTimeInMillis()-lastTime)*1000.0; • if (rate>0) { – terminationTime = (100-level)/rate/3600; – batteryStr += "charged in "+terminationTime+" hours\n"; • } • if (rate<0) { – terminationTime = -level/rate/3600; – batteryStr += "discharged in "+terminationTime+" hours\n"; • } – } – lastTime = calendar.getTimeInMillis(); – lastLevel = level; Battery Monitor Service • Make new class – BatteryMonitorService – Derived from android.app.Service • To manifest, add service, i.e, – In Application tab • Application nodes, add • Select radio button “Create a new element at the top level, in application” • Select “service” • Select ok – With the new service highlighted, • In name (on the right), add – BatteryMonitorService • Or, select “browse” and (wait) and select BatteryMonitorService In BatteryMonitorService • • @Override public void onCreate() { – – – super.onCreate(); Log.d("BatteryMonitorService","Created"); IntentFilter batteryLevelFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); • • } • • private final Binder binder = new LocalBinder(); public class LocalBinder extends Binder { registerReceiver(batteryLevelReceiver, batteryLevelFilter); – BatteryMonitorService getService() { • • – • • • • Log.d("BatteryMonitorService","localbinder"); return BatteryMonitorService.this; } } Change onBind, to @Override public IBinder onBind(Intent intent) { – – // TODO Auto-generated method stub return binder; • } • • @Override public void onDestroy() { – – – • } super.onDestroy(); Log.d("BatteryMonitorService","Destroyed"); unregisterReceiver(batteryLevelReceiver); In BatteryMonitorService • Move broadcast receiver from activity to service • Move member variables – String batteryStr = new String(); – long lastTime = 0; – double lastLevel; • BroadcastReceiver batteryLevelReceiver = new BroadcastReceiver() { • public void onReceive(Context context, Intent intent) { • …… In BatteryMonitor • • • Start service. In OnCreate, add – startService(new Intent(this, BatteryMonitorService.class)); – bindService(new Intent(this, BatteryMonitorService.class), connectionToMyService, BIND_AUTO_CREATE); Add member variable – boolean started = false; After onCreate, add – private BatteryMonitorService batteryMonitorService = null; – private ServiceConnection connectionToMyService = new ServiceConnection() { • @Override • public void onServiceConnected(ComponentName className, IBinder rawBinder) { – batteryMonitorService = ((BatteryMonitorService.LocalBinder)rawBinder).getService(); – started = true; • } • @Override • public void onServiceDisconnected(ComponentName name) { – batteryMonitorService = null; – started = false; • } – }; In BatteryMonitor • We need to get the batteryStr from the service and post it on the textview. – We can use a intent to send the message to get the string – IntentFilter intentFilter = new IntentFilter(); – intentFilter.addAction("edu.udel.eleg454.NewBatteryMonitorStringIsReady"); – registerReceiver(new BroadcastReceiver() { • public void onReceive(Context context, Intent intent) { – Log.d("DEBUG","Received intent "+intent); – textView.setText(batteryMonitorService.batteryStr); • } – },intentFilter); • • • Let’s get the string when the UI becomes active after being out of focus @Override public void onResume() { – super.onResume(); – if (started) { • textView.setText(batteryMonitorService.batteryStr); – } } // note: batteryMonitorService is only valid after the connection with the service has been established. See connectionToMyService • • In BatteryMonitorService • At the end of BroadcastReceiver batteryLevelReceiver = new BroadcastReceiver() { …. – Remove – textView.setText(batteryStr); • Add – Intent broadcastIntent = new Intent(); – broadcastIntent.setAction("edu.udel.eleg454.NewBatteryMonitorStringIsReady"); – sendBroadcast(broadcastIntent); • Run and play with gps on, wifi, etc. and see impact on battery usage