Search code examples
javaandroidbroadcastreceiver

Broadcast receiver leaked


I am trying to send a broadcast receiver from a service and i have a issue, the receiver leak and i don't know why.

Here is the code:

public class CameraCapture extends AppCompatActivity {
    static final int REQUEST_IMAGE_CAPTURE = 30;
    String URL;
    VolleyService mVolleyService;
    IResult mResultCallback = null;
    final String POSTREQUEST = "POSTCALL";
    Map<String, String> params;
    String token;

    BroadcastReceiver receiver;
    IntentFilter filter;
    MyReceiver reciver;

    boolean mBounded;
    GoogleLocation mlocation;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        token = checkForToken();
        URL = "http://10.0.2.2:3000/fotos/Tulipa";

        filter = new IntentFilter("com.myapp.LOCATION_CHANGED");
        reciver = new MyReceiver();
        registerReceiver(reciver,filter);

        String imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/picture.jpg";
        File imageFile = new File(imageFilePath);
        Uri imageFileUri = Uri.fromFile(imageFile); // convert path to Uri

        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_IMAGE_CAPTURE);

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        Intent mIntent = new Intent(this, GoogleLocation.class);
        bindService(mIntent, mConnection, BIND_AUTO_CREATE);
    }

    public void onResume() {
        super.onResume();
        Log.d("RESUME","RESUME");
        reciver = new MyReceiver();
        registerReceiver(reciver, filter);
    }

    public void onPause() {
        super.onPause();
        if(reciver != null){
            unregisterReceiver(reciver);
            reciver= null;
        }

    }

    public void onStop() {
        super.onStop();
        if(mBounded) {
            unbindService(mConnection);
            mBounded = false;
        }
    }


    private byte[] encodeImage(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] b = baos.toByteArray();

        return b;
    }

    private void sendImage(byte[] b) {
        ImageStore.getInstance().setCapturedPhotoData(b);
        mlocation.getBroadcastData();

        Intent i = new Intent(CameraCapture.this, SimiliarPhotos.class);
        startActivity(i);
        finish();
        //inicialize a map with pair key value
        //params = new HashMap<String, String>();
        // Add form fields to the map
        //GoogleLocation l = new GoogleLocation(this);
        //l.getPosition();
        //Log.d("myLat",String.valueOf(l.getLat()));
        //params.put("base64", encodedImage);
        //params.put("token",token);

        //Log.d("latitudeOP",String.valueOf(l.getLat()));

        //JSONObject sendObj = new JSONObject(params);

        //initVolleyCallback();

        //mVolleyService = new VolleyService(mResultCallback, this);

        //mVolleyService.postDataVolley(POSTREQUEST, URL, sendObj);
    }

    public void showToast(String message) {
        Toast toast = Toast.makeText(this, message, Toast.LENGTH_LONG);
        toast.show();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case 30: {

                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                } else {

                    Toast.makeText(CameraCapture.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
                }
                return;
            }
        }
    }

    void initVolleyCallback() {
        mResultCallback = new IResult() {
            @Override
            public void notifySuccess(String requestType, JSONObject response) {

            }

            @Override
            public void notifySuccess(String requestType, JSONArray response) {

            }


            @Override
            public void notifyError(String requestType, VolleyError error) {
                String body;

                if (error.networkResponse.data != null) {
                    String statusCode = String.valueOf(error.networkResponse.statusCode);
                    try {
                        body = new String(error.networkResponse.data, "UTF-8");
                        JSONObject jsonObj = new JSONObject(body);
                        Log.d("body", String.valueOf(jsonObj.get("message")));
                        showToast(String.valueOf(jsonObj.get("message")));
                    } catch (UnsupportedEncodingException e) {
                        showToast("You need to connect to the internet!");
                    } catch (JSONException e) {
                        Log.d("json:", "problems decoding jsonObj");
                    }
                }
            }
        };
    }

    ServiceConnection mConnection = new ServiceConnection() {

        public void onServiceDisconnected(ComponentName name) {
            mBounded = false;
            mlocation = null;
        }

        public void onServiceConnected(ComponentName name, IBinder service) {
            mBounded = true;
            GoogleLocation.LocalBinder mLocalBinder = (GoogleLocation.LocalBinder)service;
            mlocation = mLocalBinder.getServerInstance();
        }
    };

as you guys can see i register the receiver 2 times, oncreate and onResume, and then i destroy it onStop.


Solution

  • The problem is you are registering it twice. remove the code from onCreate and keep it only in onResume. Also if you are registering it in onResume then unRegister it in onPause to match the lifecycle events properly.