Android G1 Phoneの電力使用統計を収集しようとしています。電圧と電流の値を知りたいので、この [ 〜#〜] pdf [〜#〜] 。
ACTION_BATTERY_CHANGEDのブロードキャストを受信するインテントレシーバーに登録することで、バッテリー電圧の値を取得できます。しかし、問題はAndroidはこのSDKインターフェースを通じてcurrentの値を公開しないことです。
私が試した方法の1つはsysfsインターフェイス経由で、次のコマンドを使用してadbシェルからバッテリー電流値を表示できます
$cat /sys/class/power_supply/battery/batt_current
449
ただし、これも電話機がUSBインターフェイスを介して接続されている場合にのみ機能します。電話を切断すると、batt_currentの値が「0」と表示されます。報告される電流の値がゼロである理由がわかりません。ゼロよりも大きいはずですよね?
バッテリー電流値を取得するための提案/ポインタはありますか?また、間違っている場合は修正してください。
他のさまざまなグループからのいくつかの実験と支援の後、ソフトウェアのみでバッテリ電流値を取得する方法がないことがわかりました(h/wではサポートされていないため)。私が見つけた唯一の方法は、バッテリーを流れる電流をマルチメーターで測定することでした。
現在のウィジェットのソースコードを見るだけで済みます。特定のプラットフォームが現在の値を保存する場所へのハードコードされたパスがあります。
/*
* 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;
}
}
API 21以降では、瞬間的なバッテリー電流をマイクロアンペア単位で整数として取得できます。 開発者ドキュメント
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を使用すると、瞬時の電流測定値を取得できます。
デバイスの電力を測定し、電力消費を読み取り、NEXUSデバイスで利用可能なプロパティを読み取ります。 Androidオープンソースドキュメント
この関数を使用すると、すべてのデバイスで電圧温度電流が取得されます。
onCreateでブロードキャストレシーバーを登録する
this.registerReceiver(this.BatteryInfo, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
ブロードキャストレシーバーを作成する
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;
}
intelでこのコードを見つけましたAndroid開発者サイト
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();
}
}
};
このコードを試してください、それはあなたのための完全な助けになるかもしれません:
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));
ほとんどのバッテリーは、バッテリーから流れ出る電流を使用して%を決定しますが、開発者が利用できることはめったにありません!
これらのデバイスで変更されたカーネルが必要になります。
これは、そのような電流を測定するチップを搭載したGalaxy S2にも当てはまります!しかし、それはストックカーネルでは「無効化」されています。つまり、sysfsインターフェースから削除され、バッテリーによって内部的にのみ使用されます。
それにもかかわらず、マーケットのアプリバッテリーモニターウィジェットを試すことができます。これは多くの電話をサポートし、利用できない場合にmA電流を推定します。測定値を改善するために、新しい電話とメソッドのサポートが定期的に追加されます。
Galaxy Nexusでは、バッテリーが現在のデータを必要としない%を決定するために高度な計算を使用するようになったため、現在のチップは完全に削除されました。その結果、その電話には学習曲線がありません(
バッテリー電流%充電の場合、次を使用できます。
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);