2010-03-13 6 views
21

Estoy tratando de recopilar estadísticas de uso de energía para el teléfono Android G1. Estoy interesado en conocer los valores de Voltaje y Corriente, y luego poder recopilar estadísticas como se informa en este PDF.Obtener los valores actuales de la batería para el teléfono Android

Puedo obtener el valor de voltaje de la batería registrándose para que un receptor intente reciba la Transmisión para ACTION_BATTERY_CHANGED. Pero el problema es que Android no expone el valor de la corriente a través de esta interfaz SDK.

Una forma Probé es a través de la interfaz sysfs, donde puedo ver el valor actual de la batería de adb shell, con el siguiente comando

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

Pero eso también sólo funciona si el teléfono está conectado a través de la interfaz USB. Si desconecto el teléfono, veo el valor de batt_corrent como '0'. No estoy seguro de por qué el valor de la corriente informada es cero. Debería ser más que cero, ¿verdad?

¿Alguna sugerencia/indicador para obtener el valor actual de la batería? También por favor corrígeme si estoy equivocado.

+1

Es posible que desee ver la presentación de eso en YouTube. Estuve allí, y parece recordar que el Sr. Sharkey mencionó algo sobre tener un hardware especial para esas mediciones. – CommonsWare

+0

Sí, menciona al final de la presentación que la medición de la corriente se debe hacer a través de hardware electrónico, el software no puede ayudar. ¿Sabes exactamente cómo funciona la interfaz sysfs y si es posible podemos obtener datos de eso? Gracias por indicarme video. –

+0

[Aquí hay] (http://androidcommunity.com/forums/f7/battery-value-in-andriod-22236/) algún código de muestra que podrías probar. –

Respuesta

2

Después de varios experimentos y ayuda de varios otros grupos, descubrí que no hay forma de obtener valor de la corriente de la batería a través del software solamente (ya que no es compatible con h/w). La única forma que encontré fue medir la corriente que fluye a través de la batería mediante un multímetro.

+0

¿No hace esto el trabajo? http://developer.android.com/training/monitoring-device-state/battery-monitoring.html#CurrentLevel – fredcrs

+0

Consulta las respuestas de @Kevin (y voss) para empezar. ;) –

13

Podrías simplemente mirar el código fuente para el Widget actual. Tiene una ruta codificada para donde ciertas plataformas almacenan los valores actuales.

/* 
* 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; 
    } 
} 
+1

Mi GNex con Slimkat tiene el nivel de potencia en/sys/class/power_supply/battery/capacity, aunque probablemente no se utilice aquí, ya que es el valor%, no actual. Curiosamente, ninguno de los archivos enumerados está en mi dispositivo. – user169771

+0

Esta es la licencia de GNU. ¿Hay una licencia más agradable que se use para un código similar? Además, ¿hay alguna manera de cubrir todos los dispositivos? –

0

mayoría de las baterías utilizan la corriente que fluye de la batería para determinar el%, aunque es raramente disponible para desarrolladores de!

Requeriría un kernel modificado en esos dispositivos.

Esto es cierto para el Galaxy S2 que tienen las virutas que miden dicho flujo de corriente. Pero está "desactivado" en el kernel común. Lo que significa que se eliminó de la interfaz sysfs y solo la batería lo usa internamente.

Sin embargo, puedes probar la aplicación Battery Monitor Widget de Market, admite muchos teléfonos y calculará la corriente de mA cuando no esté disponible. Soporte para nuevos teléfonos y métodos se agregan de forma regular para mejorar las lecturas.

En el Galaxy Nexus, el chip actual se eliminó por completo, ya que la batería ahora utiliza un cálculo avanzado para determinar el%, que no necesita datos actuales. Los resultados es que el teléfono no tiene una curva de aprendizaje (

1

probar este código, puede ser que sería de ayuda completa para usted:

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); 

     } 
    }; 

en la clase principal de este registro usando:

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

usando esta función, obtenga la Corriente de temperatura de voltaje en todos los dispositivos.

en OnCreate para registrar receptor de radiodifusión

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

y crear Broadcast receptor

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; 
} 
+0

¿Hay alguna manera de saber si el valor "actual" es lo suficientemente bueno, lento o demasiado bajo para cargar (por lo tanto, el dispositivo en realidad pierde potencia)? ¿si es así, cómo? Además, ¿funcionará este método en todos los dispositivos? ¿Qué son los métodos "getHealthString", "getStatusString", "getPlugTypeString"? –

+0

¿Qué es los métodos "getHealthString", "getStatusString", "getPlugTypeString"? He editado mis métodos de respuesta agregada – Sumit

+0

Gracias. ¿Puedes responder las otras preguntas también? También noté que para mi dispositivo, el valor "actual" siempre es 0. ¿Por qué? –

2

me encontré con este código en Intel sitio de desarrolladores de 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(); 
      } 
     } 
    }; 
0

Para% de la carga de la batería actual, puede usar la siguiente

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); 
2

API 21 en adelante podemos obtener la corriente instantánea de la batería en microamperios, como un número entero. Developer docs

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"); 

Usando mBatteryManager se puede obtener la lectura de corriente instantánea.

Dispositivo de medición Potencia y consumo de energía de lectura y las propiedades disponibles en dispositivos NEXUS. Android open source docs

Cuestiones relacionadas