获取Android手机的电池电stream值

我正在尝试收集Android G1手机的用电量统计信息。 我有兴趣了解电压和电stream值,然后能够收集本PDF中报告的统计数据。

我能够通过注册一个意图接收器来接收ACTION_BATTERY_CHANGED的广播来获得电池电压的值。 但问题是,Android不通过这个SDK接口暴露当前值。

我尝试的一种方法是通过sysfs接口,在这里我可以使用以下命令查看来自adb shell的电池电stream值

$cat /sys/class/power_supply/battery/batt_current 449 

但是,只有手机通过USB接口连接,也是如此。 如果我断开电话,我看到batt_current的值为'0'。 我不确定为什么报告的电stream值为零。 它应该超过零,对不对?

任何build议/指针获取电池电stream值? 如果我错了也请纠正我。

您可以查看“当前”小部件的源代码。 它具有硬编码path,以便某些平台存储当前值。

 /* * Copyright (c) 2010-2011 Ran Manor * * This file is part of CurrentWidget. * * CurrentWidget is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CurrentWidget is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with CurrentWidget. If not, see <http://www.gnu.org/licenses/>. */ package com.manor.currentwidget.library; import java.io.File; import android.os.Build; import android.util.Log; public class CurrentReaderFactory { static public Long getValue() { File f = null; // htc desire hd / desire z / inspire? if (Build.MODEL.toLowerCase().contains("desire hd") || Build.MODEL.toLowerCase().contains("desire z") || Build.MODEL.toLowerCase().contains("inspire")) { f = new File("/sys/class/power_supply/battery/batt_current"); if (f.exists()) { return OneLineReader.getValue(f, false); } } // nexus one cyangoenmod f = new File("/sys/devices/platform/ds2784-battery/getcurrent"); if (f.exists()) { return OneLineReader.getValue(f, true); } // sony ericsson xperia x1 f = new File("/sys/devices/platform/i2c-adapter/i2c-0/0-0036/power_supply/ds2746-battery/current_now"); if (f.exists()) { return OneLineReader.getValue(f, false); } // xdandroid /*if (Build.MODEL.equalsIgnoreCase("MSM")) {*/ f = new File("/sys/devices/platform/i2c-adapter/i2c-0/0-0036/power_supply/battery/current_now"); if (f.exists()) { return OneLineReader.getValue(f, false); } /*}*/ // droid eris f = new File("/sys/class/power_supply/battery/smem_text"); if (f.exists()) { Long value = SMemTextReader.getValue(); if (value != null) return value; } // htc sensation / evo 3d f = new File("/sys/class/power_supply/battery/batt_attr_text"); if (f.exists()) { Long value = BattAttrTextReader.getValue(); if (value != null) return value; } // some htc devices f = new File("/sys/class/power_supply/battery/batt_current"); if (f.exists()) return OneLineReader.getValue(f, false); // nexus one f = new File("/sys/class/power_supply/battery/current_now"); if (f.exists()) return OneLineReader.getValue(f, true); // samsung galaxy vibrant f = new File("/sys/class/power_supply/battery/batt_chg_current"); if (f.exists()) return OneLineReader.getValue(f, false); // sony ericsson x10 f = new File("/sys/class/power_supply/battery/charger_current"); if (f.exists()) return OneLineReader.getValue(f, false); // Nook Color f = new File("/sys/class/power_supply/max17042-0/current_now"); if (f.exists()) return OneLineReader.getValue(f, false); return null; } } 

经过多次实验和其他团队的帮助,我发现没有办法通过软件获取电池电stream值(因为它不支持h / w)。 我发现的唯一方法就是用万用表测量stream过电池的电stream。

使用此function可以获得所有设备的电压温度电stream。

在OnCreate上注册广播接收者

  this.registerReceiver(this.BatteryInfo, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 

并创build广播接收器

  private BroadcastReceiver BatteryInfo = new BroadcastReceiver() { @Override public void onReceive(Context ctxt, Intent intent) { int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100); boolean isPresent = intent.getBooleanExtra("present", false); Bundle bundle = intent.getExtras(); String str = bundle.toString(); Log.i("Battery Info", str); if (isPresent) { int percent = (level * 100) / scale; technology.setText("Technology: "+bundle.getString("technology")); voltage.setText("Voltage: "+bundle.getInt("voltage")+"mV"); temp.setText("Temperature: "+bundle.getInt("temperature")); curent.setText("Current: "+bundle.getInt("current_avg")); health.setText("Health: "+getHealthString(health_)); charging.setText("Charging: "+getStatusString(status) + "(" +getPlugTypeString(pluggedType)+")"); battery_percentage.setText("" + percent + "%"); } else { battery_percentage.setText("Battery not present!!!"); } } }; private String getPlugTypeString(int plugged) { String plugType = "Unknown"; switch (plugged) { case BatteryManager.BATTERY_PLUGGED_AC: plugType = "AC"; break; case BatteryManager.BATTERY_PLUGGED_USB: plugType = "USB"; break; } return plugType; } private String getHealthString(int health) { String healthString = "Unknown"; switch (health) { case BatteryManager.BATTERY_HEALTH_DEAD: healthString = "Dead"; break; case BatteryManager.BATTERY_HEALTH_GOOD: healthString = "Good Condition"; break; case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: healthString = "Over Voltage"; break; case BatteryManager.BATTERY_HEALTH_OVERHEAT: healthString = "Over Heat"; break; case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: healthString = "Failure"; break; } return healthString; } private String getStatusString(int status) { String statusString = "Unknown"; switch (status) { case BatteryManager.BATTERY_STATUS_CHARGING: statusString = "Charging"; break; case BatteryManager.BATTERY_STATUS_DISCHARGING: statusString = "Discharging"; break; case BatteryManager.BATTERY_STATUS_FULL: statusString = "Full"; break; case BatteryManager.BATTERY_STATUS_NOT_CHARGING: statusString = "Not Charging"; break; } return statusString; } 

我在英特尔Android开发者网站上find了这个代码

 public class BatteryActivity extends Activity { private final String TAG = "SDP_BATTERY"; private final String DEGREE_UNICODE = "\u00B0"; private StringBuffer textBuffer = new StringBuffer(); // a text view to show the status of the battery private TextView mStatusTextView; // a text view to display the battery status icon private TextView mBatteryStatusIcon; /** Called when the activity is first created. */ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.battery); mBatteryStatusIcon = (TextView) this.findViewById(R.id.statusBattIcon); mStatusTextView = (TextView) this.findViewById(R.id.statusEditText); } /** * Once onResume is called, the activity has become visible (it is now "resumed"). Comes after onCreate */ protected void onResume() { super.onResume(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); Log.d(TAG, "Register battery status receiver."); registerReceiver(mBroadcastReceiver, filter); } /** * Another activity takes focus, so this activity goes to "paused" state */ protected void onPause() { super.onPause(); Log.d(TAG, "Unegister battery status receiver."); unregisterReceiver(mBroadcastReceiver); } /** * BroadcastReceiver is used for receiving intents (broadcasted messages) from the BatteryManager */ private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { private boolean isHealth = false; public void onReceive(Context context, Intent intent) { DecimalFormat formatter = new DecimalFormat(); String action = intent.getAction(); // store battery information received from BatteryManager if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { Log.d(TAG, "Received battery status information."); int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0); int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 0); boolean present = intent.getBooleanExtra( BatteryManager.EXTRA_PRESENT, false); int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0); int icon_small = intent.getIntExtra( BatteryManager.EXTRA_ICON_SMALL, 0); int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0); int voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0); int temperature = intent.getIntExtra( BatteryManager.EXTRA_TEMPERATURE, 0); String technology = intent .getStringExtra(BatteryManager.EXTRA_TECHNOLOGY); // display the battery icon that fits the current battery status (charging/discharging) mBatteryStatusIcon.setCompoundDrawablesWithIntrinsicBounds(icon_small, 0, 0, 0); // create TextView of the remaining information , to display to screen. String statusString = ""; switch (status) { case BatteryManager.BATTERY_STATUS_UNKNOWN: statusString = "unknown"; break; case BatteryManager.BATTERY_STATUS_CHARGING: statusString = "charging"; break; case BatteryManager.BATTERY_STATUS_DISCHARGING: statusString = "discharging"; break; case BatteryManager.BATTERY_STATUS_NOT_CHARGING: statusString = "not charging"; break; case BatteryManager.BATTERY_STATUS_FULL: statusString = "full"; break; } String healthString = ""; switch (health) { case BatteryManager.BATTERY_HEALTH_UNKNOWN: healthString = "unknown"; break; case BatteryManager.BATTERY_HEALTH_GOOD: healthString = "good"; isHealth = true; break; case BatteryManager.BATTERY_HEALTH_OVERHEAT: healthString = "overheat"; break; case BatteryManager.BATTERY_HEALTH_DEAD: healthString = "dead"; break; case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE: healthString = "over voltage"; break; case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE: healthString = "unspecified failure"; break; } String acString = ""; switch (plugged) { case BatteryManager.BATTERY_PLUGGED_AC: acString = "plugged AC"; break; case BatteryManager.BATTERY_PLUGGED_USB: acString = "plugged USB"; break; default: acString = "not plugged"; } textBuffer = new StringBuffer(); textBuffer.append("status:" + statusString + "\n"); formatter.applyPattern("#"); String levelStr = formatter.format( (float)level/scale * 100 ); textBuffer.append("level:" + levelStr + "% (out of 100)\n"); textBuffer.append("health:" + healthString + "\n"); textBuffer.append("present?:" + String.valueOf(present) + "\n"); textBuffer.append("plugged?:" + acString + "\n"); // voltage is reported in millivolts formatter.applyPattern(".##"); String voltageStr = formatter.format( (float)voltage/1000 ); textBuffer.append("voltage:" + voltageStr + "V\n"); // temperature is reported in tenths of a degree Centigrade (from BatteryService.java) formatter.applyPattern(".#"); String temperatureStr = formatter.format( (float)temperature/10 ); textBuffer.append("temperature:" + temperatureStr + "C" + DEGREE_UNICODE + "\n"); textBuffer.append("technology:" + String.valueOf(technology) + "\n"); mStatusTextView.setText(textBuffer.toString()); if (isHealth) { Log.d(TAG, "Battery health: " + healthString); Log.d(TAG, "UMSE_BATTERY_SUCCESSFULLY"); } else { Log.d(TAG, "UMSE_BATTERY_FAILED"); } Log.d(TAG, textBuffer.toString()); //finish(); } } }; 

从API 21开始,我们可以获得微安电stream的瞬时电stream,作为一个整数。 开发人员文档

 BatteryManager mBatteryManager = (BatteryManager) getSystemService(Context.BATTERY_SERVICE); Long avgCurrent = null, currentNow = null; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { avgCurrent = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_AVERAGE); currentNow = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW); } Log.d(TAG, "BATTERY_PROPERTY_CURRENT_AVERAGE = " + avgCurrent + "mAh"); Log.d(TAG, "BATTERY_PROPERTY_CURRENT_NOW = " + currentNow + "mAh"); 

使用mBatteryManager你可以得到瞬时电stream读数。

测量设备功率和读取功耗以及NEXUS设备上的可用属性。 Android开源文档

试试这个代码,可能会对你有帮助:

 private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){ @Override public void onReceive(Context arg0, Intent intent) { // TODO Auto-generated method stub //this will give you battery current status int level = intent.getIntExtra("level", 0); contentTxt.setText(String.valueOf(level) + "%"); int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); textView2.setText("status:"+status); boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL; textView3.setText("is Charging:"+isCharging); int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); textView4.setText("is Charge plug:"+chargePlug); boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; textView5.setText("USB Charging:"+usbCharge+" AC charging:"+acCharge); } }; 

在主要类中注册这个使用:

  this.registerReceiver(this.mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 

大多数电池使用stream出电池的电stream来确定百分比,尽pipe开发人员很less使用它!

需要在这些设备上修改内核。

在测量这种电stream的芯片上,Galaxy S2是这样的! 但是它在股票内核中是“停用”的。 这意味着它从sysfs接口中被删除,并且只在电池内部使用。

尽pipe如此,你可以尝试电池监视器从市场电子小部件的应用程序,它支持许多手机,并估计毫安电stream不可用时。 定期添加对新手机和方法的支持,以提高读数。

在Galaxy Nexus上,当前的芯片被完全删除,因为电池现在使用高级计算来确定%,而不需要当前的数据。 结果就是那个手机没有学习曲线(

对于电池电stream%充电,您可以使用以下内容

 IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); Intent batteryStatus = this.registerReceiver(null, ifilter); int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1); float batteryPct = level / (float)scale; TextView tView = (TextView) findViewById(R.id.textView2); tView.setText("Battery Status " + batteryPct);