0

I am writing an app to upload images to my server from gallery and from camera the problem I am having is when i take a picture from the camera and I click my upload button it crashes out of the app according to the debug logs it has something to do with the bitmap pointing to a null object refrence as well as bitmap failing to decode the stream

there are a few answers on SO pretaining to this but non have worked so far

Error log

   E/BitmapFactory: Unable to decode stream: java.lang.NullPointerException
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.smartpractice.myapplication, PID: 18010
    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
        at com.smartpractice.myapplication.MainActivity.upload(MainActivity.java:79)
        at com.smartpractice.myapplication.MainActivity.access$100(MainActivity.java:41)
        at com.smartpractice.myapplication.MainActivity$2.onClick(MainActivity.java:67)
        at android.view.View.performClick(View.java:6663)
        at android.view.View.performClickInternal(View.java:6635)
        at android.view.View.access$3100(View.java:794)
        at android.view.View$PerformClick.run(View.java:26199)
        at android.os.Handler.handleCallback(Handler.java:907)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:216)
        at android.app.ActivityThread.main(ActivityThread.java:7593)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

Activity java

public class MainActivity extends Activity {

Button btpic, btnup;
private Uri fileUri;
String picturePath;
Uri selectedImage;
Bitmap photo;
String ba1;
public static String URL = "Paste your URL here";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btpic = (Button) findViewById(R.id.cpic);
    btpic.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            clickpic();
        }
    });

    btnup = (Button) findViewById(R.id.up);
    btnup.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            upload();
        }
    });
}

private void upload() {
    // Image location URL
    Log.e("path", "----------------" + picturePath);

    // Image
    Bitmap bm = BitmapFactory.decodeFile(picturePath);
    ByteArrayOutputStream bao = new ByteArrayOutputStream();
    bm.compress(Bitmap.CompressFormat.JPEG, 0, bao);
    byte[] ba = bao.toByteArray();
    ba1 = Base64.encodeToString(ba, Base64.NO_WRAP);

    Log.e("base64", "-----" + ba1);

    // Upload image to server
    new uploadToServer().execute();

}

private void clickpic() {
    // Check Camera
    if (getApplicationContext().getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA)) {
        // Open default camera
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

        // start the image capture Intent
        startActivityForResult(intent, 100);

    } else {
        Toast.makeText(getApplication(), "Camera not supported", Toast.LENGTH_LONG).show();
    }
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 100 && resultCode == RESULT_OK) {

        selectedImage = data.getData();
        photo = (Bitmap) data.getExtras().get("data");




        Bitmap photo = (Bitmap) data.getExtras().get("data");
        ImageView imageView = (ImageView) findViewById(R.id.Imageprev);
        imageView.setImageBitmap(photo);
    }
}

public class uploadToServer extends AsyncTask<Void, Void, String> {

    private ProgressDialog pd = new ProgressDialog(MainActivity.this);
    protected void onPreExecute() {
        super.onPreExecute();
        pd.setMessage("Wait image uploading!");
        pd.show();
    }

    @Override
    protected String doInBackground(Void... params) {

        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("base64", ba1));
        nameValuePairs.add(new BasicNameValuePair("ImageName", System.currentTimeMillis() + ".jpg"));
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(URL);
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost);
            String st = EntityUtils.toString(response.getEntity());
            Log.v("log_tag", "In the try Loop" + st);

        } catch (Exception e) {
            Log.v("log_tag", "Error in http connection " + e.toString());
        }
        return "Success";

    }

    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        pd.hide();
        pd.dismiss();
    }
}
  • your picturePath is empty, so your Bitmap is null and then you're trying to compress a null bitmap hence the crash – Nikos Hidalgo Aug 07 '19 at 09:36
  • When doing things like that, you should put it in a try catch, so even if something goes wrong, your app doesn't crash at least. Also try doing `BitmapFactory.decodeFile(File(picturepath))` instead of `BitmapFactory.decodeFile(picturePath)`. – HartWoom Aug 07 '19 at 09:38
  • @NikosHidalgo I am really new to java and android, can you maybe give me alittle help to solve that? – Ruben Meiring Aug 07 '19 at 09:38
  • inside onActivityResult when you create the photo, get it's path (https://stackoverflow.com/questions/15432592/get-file-path-of-image-on-android) and save it on to picturePath. that should fix your crash. Although your app is still prone to crashes if the user can click the upload before taking any photo. that's why you either check for null values, or you add the picturePath as a parameter in your upload method and call it when you know you have a value for picturePath. – Nikos Hidalgo Aug 07 '19 at 09:47
  • @HartWoom changing BitmapFactory.decodeFile(picturePath) to BitmapFactory.decodeFile(File(picturepath)) gives me "METHOD CALL EXPECTED" error any solution to this? – Ruben Meiring Aug 07 '19 at 09:52
  • @RubenMeiring I forgot, since your on java you may want to do `new File(picturepath)` then. Not sure though, since I'm developing with Kotlin. – HartWoom Aug 07 '19 at 09:59

1 Answers1

0
@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

       if (requestCode==REQUEST_CAMERA)
        {
            Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
            File destination = new File(Environment.getExternalStorageDirectory(),"temp.jpg");
            FileOutputStream fo;
            try {
                fo = new FileOutputStream(destination);
                fo.write(bytes.toByteArray());
                fo.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

           new uploadFileToServerTask().execute(destination.getAbsolutePath());
        }
    }

Uploading File to server

 private class uploadFileToServerTask extends AsyncTask<String, String, Object> {
        @Override
        protected String doInBackground(String... args) {
            try {
                String lineEnd = "\r\n";
                String twoHyphens = "--";
                String boundary = "*****";
                int bytesRead, bytesAvailable, bufferSize;
                byte[] buffer;
                @SuppressWarnings("PointlessArithmeticExpression")
                int maxBufferSize = 1 * 1024 * 1024;


                java.net.URL url = new URL((ApplicationConstant.UPLOAD_IMAGE_URL) + IMAGE + customer_id);
                Log.d(ApplicationConstant.TAG, "url " + url);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                // Allow Inputs &amp; Outputs.
                connection.setDoInput(true);
                connection.setDoOutput(true);
                connection.setUseCaches(false);

                // Set HTTP method to POST.
                connection.setRequestMethod("POST");

                connection.setRequestProperty("Connection", "Keep-Alive");
                connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

                FileInputStream fileInputStream;
                DataOutputStream outputStream;
                {
                    outputStream = new DataOutputStream(connection.getOutputStream());

                    outputStream.writeBytes(twoHyphens + boundary + lineEnd);
                    String filename = args[0];
                    outputStream.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + filename + "\"" + lineEnd);
                    outputStream.writeBytes(lineEnd);
                    Log.d(ApplicationConstant.TAG, "filename " + filename);

                    fileInputStream = new FileInputStream(filename);

                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);

                    buffer = new byte[bufferSize];

                    // Read file
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                    while (bytesRead > 0) {
                        outputStream.write(buffer, 0, bufferSize);
                        bytesAvailable = fileInputStream.available();
                        bufferSize = Math.min(bytesAvailable, maxBufferSize);
                        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                    }
                    outputStream.writeBytes(lineEnd);
                    outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
                }

                int serverResponseCode = connection.getResponseCode();
                String serverResponseMessage = connection.getResponseMessage();
                Log.d("serverResponseCode", "" + serverResponseCode);
                Log.d("serverResponseMessage", "" + serverResponseMessage);

                fileInputStream.close();
                outputStream.flush();
                outputStream.close();

                if (serverResponseCode == 200) {
                    return "true";
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "false";
        }

        @Override
        protected void onPostExecute(Object result) {

        }
    }