Search code examples
androidandroid-volleyandroid-image

NullPointer Exception at android.content.ContentResolver.openInputStream When Send Image To PHP Server


I modify from tutorial Android Upload Image to Server using Volley Tutorial

in this tutorial, when user select an image, the script directly upload to server. so I modify that when the user select an image, the image display first on imageview, and then, when user click "sendtoserver" button, that image will send to server with the other EditText.

first, I have finish with choose image button, and the image that I choose is showing on imageview.

second, when I click the "sendtoserver" button, I got error about getContentResolver(), here my MainActivity Code

package com.example.celmira.uploadgambar;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.Volley;
import com.squareup.picasso.Picasso;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


public class MainActivity extends AppCompatActivity {

//ImageView to display image selected
ImageView imageView;
//edittext for getting the tags input
EditText editTextTags;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    //initializing views
    imageView = (ImageView) findViewById(R.id.imageView);
    editTextTags = (EditText) findViewById(R.id.editTextTags);

    //mengecek permission, jika blm diijinkan, maka buka setting atau keluar apps
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ContextCompat.checkSelfPermission(this,
            Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
        finish();
        startActivity(intent);
        return;
    }


    //get image from gallery when clicked
    findViewById(R.id.buttonUploadImage).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            //if the tags edittext is empty
            //we will throw input error
            if (editTextTags.getText().toString().trim().isEmpty()) {
                editTextTags.setError("Enter tags first");
                editTextTags.requestFocus();
                return;
            }

            //if everything is ok we will open image chooser
            Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(i, 100);
        }
    });


    // SENDING IMAGE AND TAG TO SERVER WHEN BUTTON sendtoserver clicked
    findViewById(R.id.sendtoserver).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Uri imageUri = getIntent().getData();

            try {
                //getting bitmap object from uri
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
                Log.d("eek",bitmap.toString());

                //function to send to server
                uploadBitmap(bitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 100 && resultCode == RESULT_OK && data != null) {

        //getting the image Uri
        Uri imageUri = data.getData();
        try {
            //getting bitmap object from uri
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
            //displaying selected image to imageview
            Picasso.get().load(imageUri).into(imageView);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/*
* The method is taking Bitmap as an argument
* then it will return the byte[] array for the given bitmap
* and we will send this array to the server
* here we are using PNG Compression with 80% quality
* you can give quality between 0 to 100
* 0 means worse quality
* 100 means best quality
* */
public byte[] getFileDataFromDrawable(Bitmap bitmap) {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 80, byteArrayOutputStream);
    return byteArrayOutputStream.toByteArray();
}

private void uploadBitmap(final Bitmap bitmap) {

    //getting the tag from the edittext
    final String tags = editTextTags.getText().toString().trim();

    //our custom volley request
    VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(Request.Method.POST, "http://192.168.166.2/MyApi/Api.php?apicall=uploadpic",
            new Response.Listener<NetworkResponse>() {
                @Override
                public void onResponse(NetworkResponse response) {
                    try {
                        JSONObject obj = new JSONObject(new String(response.data));
                        Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
                }
            }) {

        /*
        * If you want to add more parameters with the image
        * you can do it here
        * here we have only one parameter with the image
        * which is tags
        * */
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<>();
            params.put("tags", tags);
            return params;
        }

        /*
        * Here we are passing image by renaming it with a unique name
        * */
        @Override
        protected Map<String, DataPart> getByteData() {
            Map<String, DataPart> params = new HashMap<>();
            long imagename = System.currentTimeMillis();
            params.put("pic", new DataPart(imagename + ".png", getFileDataFromDrawable(bitmap)));
            return params;
        }
    };

    //adding the request to volley
    Volley.newRequestQueue(this).add(volleyMultipartRequest);
}
}

and here the script that causing error

 Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);

and this is what error message

FATAL EXCEPTION: main
              java.lang.NullPointerException
                  at android.content.ContentResolver.openInputStream(ContentResolver.java:481)
                  at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:792)
                  at com.example.celmira.uploadgambar.MainActivity$2.onClick(MainActivity.java:94)

how to getContentResolver() that I can pass to MediaStore.Images.Media.getBitmap()


Solution

  • For upload after select iamge:

    Move uploadBitmap(bitmap); to onActivityResult()

    For upload after click button:

    First create global image url

    private Uri imageUri;

    In above of your code Fill it in onActivityResult like you do

    imageUri = data.getData();
    

    And send it when call button

    findViewById(R.id.sendtoserver).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //THIS LINE REMOVED
            //Uri imageUri = getIntent().getData();
    
            try {
                //getting bitmap object from uri
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
                Log.d("eek",bitmap.toString());
    
                //function to send to server
                uploadBitmap(bitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });