Android - activity leaked IntentReceiver

I am writing a very simple application. It works fine, but when I click on the back key, it crashes (activity leaked into the IntentReceiver, which was originally registered here). This application should work in the background. How to do it right?

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;
    }
}
+5
source share
1 answer

First of all, you need to unregister the registered BroadcastReceiver, if necessary. See here for more information: http://developer.android.com/reference/android/content/BroadcastReceiver.html

, , , Activity. . , , , API: http://developer.android.com/reference/android/app/Service.html

+4

All Articles