2010-09-07 15 views
39

Ho un ricevitore di broadcast nel mio programma per arrivare reagire al livello della batteria in questo modo:Ottenere il livello della batteria prima del ricevitore di broadcast risponde per Intent.ACTION_BATTERY_CHANGED

private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){ 
    @Override 
    public void onReceive(Context arg0, Intent intent) { 
     int level = intent.getIntExtra("level", 0); 
     // do something... 
    } 
} 

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

Tuttavia questo codice deve aspettare per lo stato della batteria a essere aggiornato quindi se si dispone di un elemento della GUI che deve essere impostato in base al livello della batteria, è necessario attendere che si verifichi un evento della batteria. C'è un modo per spingere questo per farlo funzionare o semplicemente eseguire un codice per vedere qual è il livello della batteria nell'ultima trasmissione?

risposta

35

C'è un modo per spingere questo per farlo funzionare o semplicemente eseguire del codice di vedere ciò che il livello della batteria era in l'ultima trasmissione?

È possibile chiamare registerReceiver() con il tuo IntentFilter e nullBroadcastReceiver per ottenere l'ultimo broadcast Intent. Funziona perché ACTION_BATTERY_CHANGED è una cosiddetta "trasmissione appiccicosa", che descrivo un po 'di più in this StackOverflow question-and-answer.

+3

Il ricevitore che ho nella domanda viene chiamato non appena viene creato, ma non l'ho notato perché ho reinizializzato le variabili dopo di esso. – stealthcopter

+0

Otterrà il applicationContext come descritto di seguito per rendere questa chiamata causare problemi? Ho il problema che il mio ricevitore di radiodiffusione non è autorizzato a registrarsi per intenti, anche se passo in null. Qual è la soluzione corretta a questo problema? –

+6

@Mayra: 'getApplicationContext()' dovrebbe andare bene qui, in particolare se stai provando a farlo da un 'BroadcastReceiver'. – CommonsWare

80

Questo è il modo per ottenere il livello della batteria, senza la registrazione di un ricevitore:

Intent batteryIntent = context.getApplicationContext().registerReceiver(null, 
        new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 
int rawlevel = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); 
double scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); 
double level = -1; 
if (rawlevel >= 0 && scale > 0) { 
    level = rawlevel/scale; 
} 

Si può usare un BroadcastReceiver nulla a causa della natura appiccicosa della trasmissione.

Esso utilizza la getApplicationContext() trucco in caso ci si trova in un ricevitore intento e ottenere l'eccezione:

android.content.ReceiverCallNotAllowedException: componenti IntentReceiver non sono permesso di registrarsi per ricevere intenti

+0

In determinate situazioni (come l'esecuzione in un servizio di sistema), getApplicationContext() restituirà null. In questo caso la chiamata deve essere: context.registerReceiver (null, new IntentFilter (Intent.ACTION_BATTERY_CHANGED)); – hemisphire

+1

@hemisphire ha scritto "In determinate situazioni (come l'esecuzione in un servizio di sistema), getApplicationContext() restituirà null". Non penso sia sempre vero Forse dipende dal tipo di servizio. – Tom

+1

Perfetto! Posso farlo senza servizio ora. – thecr0w

2
// Put this Code into your MainActivity 

private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context c, Intent i) { 
     int level = i.getIntExtra("level", 0); 
     ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar); 
     pb.setProgress(level); 
     TextView tv = (TextView) findViewById(R.id.textfield); 
     tv.setText("Battery Level: " + Integer.toString(level) + "%"); 
    } 

}; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    registerReceiver(mBatInfoReceiver, new IntentFilter(
      Intent.ACTION_BATTERY_CHANGED)); 
} 
+0

potrebbe essere necessario annullare la registrazione di questo ricevitore anche in onPause im annullamento della registrazione ma questo sta creando l'errore 01-11 15: 08: 21.711: E/AndroidRuntime (31730): Causato da: java.lang.IllegalArgumentException: Destinatario non registrato: [email protected] – user3233280

1

Io uso questo metodo per ottenere il livello della batteria senza ricevere aggiornamenti.

public float getMyBatteryLevel() { 
     Intent batteryIntent = this.getApplicationContext().registerReceiver(null, 
     new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 
     return batteryIntent.getIntExtra("level", -1); 
} 
5
public static String batteryLevel(Context context) 
    { 
     Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 
     int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); 
     int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100); 
     int percent = (level*100)/scale; 
     return String.valueOf(percent) + "%"; 
    } 
0

Si prega di essere consapevoli, che l'intento si ottiene da registerReceiver chiamata

Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 

può essere null. Quindi, per favore, fai un controllo prima di utilizzare l'intento, ad es.

if(intent != null){ 
// do your stuff here... 
} 

Ho appena ottenuto un'eccezione di puntatore nullo, causando l'arresto anomalo dell'app!

Problemi correlati