I'm writing very simple app. It works OK, but when I hit a back key it crashes (Activity has leaked IntentReceiver that was originally registered here). This app should work in background. How to do it properly?
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
public class Bateria extends Activity implements OnClickListener, OnSeekBarChangeListener {
ProgressBar pbBatteryLevel;
TextView tvBatteryLevel;
TextView tvLeft;
RadioButton rbPercent;
RadioButton rbTime;
SeekBar sbSetLeft;
boolean percent; // true - percent, false - time
boolean informed;
int progress;
int MAX_TIME;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
PowerManager pM = (PowerManager) getSystemService(Context.POWER_SERVICE);
WakeLock wL = pM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "whatever");
long HOURS24 = 86400000;
super.onCreate(savedInstanceState);
wL.acquire(HOURS24);
setContentView(R.layout.main);
initialize();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
registerReceiver(batteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
private void initialize() {
// TODO Auto-generated method stub
SharedPreferences preferences = getSharedPreferences("SP_BATTERY", 0);
percent = preferences.getBoolean("percent", true);
progress = preferences.getInt("progress", 0);
informed = false;
MAX_TIME = 72*60;
pbBatteryLevel = (ProgressBar) findViewById(R.id.pbBatteryLevel);
tvBatteryLevel = (TextView) findViewById(R.id.tvBatteryLevel);
tvBatteryLevel.setTextSize(20);
tvLeft = (TextView) findViewById(R.id.tvLeft);
if(percent)
tvLeft.setText(String.valueOf(progress) + " %");
else{
int minutes = MAX_TIME*progress/100;
int hours = minutes / 60;
minutes -= hours*60;
tvLeft.setText(String.valueOf(hours) + "h " + String.valueOf(minutes) + "min");
}
rbPercent = (RadioButton) findViewById(R.id.rbPercent);
rbPercent.setOnClickListener(this);
rbPercent.setChecked(percent);
rbTime = (RadioButton) findViewById(R.id.rbTime);
rbTime.setOnClickListener(this);
rbTime.setChecked(!percent);
sbSetLeft = (SeekBar) findViewById(R.id.sbSetPercent);
sbSetLeft.setOnSeekBarChangeListener(this);
sbSetLeft.setProgress(progress);
registerReceiver(batteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
private BroadcastReceiver batteryInfoReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context c, Intent i) {
int level = i.getIntExtra("level", 0);
int voltage = i.getIntExtra("voltage", 0);
int temperature = i.getIntExtra("temperature", 0);
pbBatteryLevel.setProgress(level);
tvBatteryLevel.setText("Battery Level: " + Integer.toString(level)
+ "%" + "\n" + voltage + " mV " + temperature + " C");
if(level < progress && !informed){
//////////
Toast.makeText(getApplicationContext(), "BATTERY", Toast.LENGTH_LONG).show();
MediaPlayer mp = MediaPlayer.create(Bateria.this, R.raw.explosion);
mp.start();
//////////
informed = true;
}
else if(level >= progress){
informed = false;
}
}
};
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case(R.id.rbPercent):
percent = true;
tvLeft.setText(String.valueOf(progress) + " %");
break;
case(R.id.rbTime):
percent = false;
int minutes = MAX_TIME*progress/100;
int hours = minutes / 60;
minutes -= hours*60;
tvLeft.setText(String.valueOf(hours) + "h " + String.valueOf(minutes) + "min");
break;
}
SharedPreferences preferences = getSharedPreferences("SP_BATTERY", 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("percent", percent);
editor.commit();
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
if(percent)
tvLeft.setText(String.valueOf(progress) + " %");
else{
int minutes = MAX_TIME*progress/100;
int hours = minutes / 60;
minutes -= hours*60;
tvLeft.setText(String.valueOf(hours) + "h " + String.valueOf(minutes) + "min");
}
this.progress = progress;
SharedPreferences preferences = getSharedPreferences("SP_BATTERY", 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("progress", progress);
editor.commit();
informed = false;
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu);
MenuInflater blowUp = getMenuInflater();
blowUp.inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
System.exit(0);
return false;
}
}
First of all you need to unregister a registered BroadcastReceiver as appropriate. See here for more information: http://developer.android.com/reference/android/content/BroadcastReceiver.html
More important than that, you cannot develop an application running in background by just developing an Activity. You need to develop a Service for that. Check this link for an explanation of how to do it, along with API documentation: http://developer.android.com/reference/android/app/Service.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With