2010-09-07 28 views
39

J'ai un récepteur de radiodiffusion dans mon programme pour obtenir réagir au niveau de la batterie comme ceci:Obtenez le niveau de la batterie avant récepteur de radiodiffusion répond pour 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)); 

Cependant ce code doit attendre l'état de la batterie être mis à jour, donc si vous avez un élément GUI qui doit être défini en fonction du niveau de la batterie, il doit attendre qu'un événement de batterie se produise. Y a-t-il un moyen de pousser ça pour le faire fonctionner ou simplement d'exécuter du code pour voir quel était le niveau de batterie lors de la dernière diffusion?

Répondre

35

Existe-t-il un moyen de pousser cette fonctionnalité pour la faire fonctionner ou simplement d'exécuter du code pour voir quel était le niveau de la batterie la dernière diffusion?

Vous pouvez appeler registerReceiver() avec votre IntentFilter et un nullBroadcastReceiver pour obtenir la dernière diffusion Intent. Cela fonctionne parce que ACTION_BATTERY_CHANGED est une soi-disant "émission collante", que je décris un peu plus en this StackOverflow question-and-answer.

+3

Le récepteur que j'ai dans la question est effectivement appelé dès qu'il est créé que je n'ai tout simplement pas remarqué parce que j'ai réinitialisé les variables après elle. – stealthcopter

+0

Est-ce que obtenir l'applicationContext comme décrit ci-dessous pour faire cet appel causer des problèmes? J'ai le problème que mon récepteur de diffusion n'est pas autorisé à s'inscrire pour les intentions, même si je passe en null. Quelle est la bonne solution à ce problème? –

+6

@Mayra: 'getApplicationContext()' devrait être bien ici, en particulier si vous essayez de le faire à partir d'un 'BroadcastReceiver'. – CommonsWare

80

Voici comment obtenir le niveau de la batterie sans l'enregistrement d'un récepteur:

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

Il peut utiliser une BroadcastReceiver nulle en raison de la nature collante de l'émission.

Il utilise le getApplicationContext() trick au cas où vous êtes dans un récepteur intention et obtenir l'exception:

android.content.ReceiverCallNotAllowedException: composants IntentReceiver ne sont pas autorisés à inscrire pour recevoir intentions

+0

Dans certaines situations (comme l'exécution dans un service système), getApplicationContext() renverra null. Dans ce cas, l'appel doit être: context.registerReceiver (null, new IntentFilter (Intent.ACTION_BATTERY_CHANGED)); – hemisphire

+1

@hemisphire a écrit "Dans certaines situations (comme l'exécution dans un service système), getApplicationContext() renverra null". Je ne pense pas que ce soit toujours vrai. Peut-être que cela dépend du type de service. – Tom

+1

Parfait! Je peux le faire sans service maintenant. – 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

puis-je avoir besoin de se désabonner ce récepteur aussi bien dans onPause im unregistering mais cela crée une erreur 01-11 15: 08: 21.711: E/AndroidRuntime (31730): Causée par: java.lang.IllegalArgumentException: Receiver non enregistré: [email protected] – user3233280

1

J'utilise cette méthode pour obtenir le niveau de la batterie sans recevoir de mises à jour.

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

S'il vous plaît être conscient, que l'intention que vous obtenez de registerReceiver appel

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

peut être nulle. Alors s'il vous plaît faites une vérification avant d'utiliser l'intention, par ex.

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

Je viens de recevoir une exception de pointeur nul, provoquant le crash de l'application!