1

So.. I'm trying to choose a picture using both camera and gallery, then pass it to an external library to crop image.

The problem lies with saving image after taking it with the camera. I've managed to get the camera running and take an image with it, then it display the image and the default Android Ok and back button. The Ok button responds to touch (as touch effect can be seen) but it doesn't do anything.

Here's the code for getting the file ready to save

date = calendar.getTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyyyyHHmmss");
        dateString = simpleDateFormat.format(date);
        dateBuilder = new StringBuilder().append(dateString).append(".jpg");
        SAMPLE_CROPPED_IMAGE_NAME = dateBuilder.toString();

        final String cameraDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/SamplePics/";
        newDir = new File(cameraDir);
        newDir.mkdirs();

This is the code for camera function

RelativeLayout.OnClickListener photoCameraWrapperHandler = new RelativeLayout.OnClickListener(){

        @Override
        public void onClick(View v) {
            //Intent intent = new Intent(SignupStepThreeActivity.this, SignupStepFourActivity.class);
            //startActivity(intent);
            String cameraFile = SAMPLE_CROPPED_IMAGE_NAME;
            newFile = new File(cameraFile);
            try {
                newFile.createNewFile();
            }
            catch (IOException e)
            {
            }

            Uri outputFileUri = Uri.fromFile(newFile);
            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
            startActivityForResult(cameraIntent, CAMERA_REQUEST);
        }
    };

And here's the onActivityResult :

private static final int CAMERA_REQUEST = 1888;
private static final int REQUEST_SELECT_PICTURE = 0x01;

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == REQUEST_SELECT_PICTURE || requestCode == CAMERA_REQUEST) {
                final Uri selectedUri = data.getData();
                if (selectedUri != null) {
                    startCropActivity(data.getData());
                } else {
                    Toast.makeText(SignupStepThreeActivity.this, R.string.toast_cannot_retrieve_selected_image, Toast.LENGTH_SHORT).show();
                }
            } else if (requestCode == UCrop.REQUEST_CROP) {
                handleCropResult(data);
            }
        }
        if (resultCode == UCrop.RESULT_ERROR) {
            handleCropError(data);
        }
    }

Several updates before, it crashes when I click on camera button, I suspected it was because of I kind of take the uri of the image from storage but I haven't created the folder. Now I finally managed to get the camera running but not saving. The create folder part works tho..

Kevin Murvie
  • 2,592
  • 1
  • 25
  • 43
  • do you set WRITE permission in your AndroidManifest.xml? – Gueorgui Obregon Feb 09 '16 at 03:54
  • Yes both read for gallery and write for camera ` ` Wait I think I just realized something, does `WRITE_EXTERNAL_STORAGE` only lets access to `EXTERNAL`? – Kevin Murvie Feb 09 '16 at 04:11
  • "doesn't do anything": is your onActivityResult() called? What is **resultCode**? Please check [this answer](http://stackoverflow.com/a/10779050/192373) if your problem is that **resultCode** is OK, but **data** is null. – Alex Cohn Feb 09 '16 at 09:41
  • Yes I've found it while going thru Stack's answers, and in fact that's what I needed, `data.getData()` is null, it returns `Bitmap` instead which I have to convert to `Uri`. Check my answer for the solution :D – Kevin Murvie Feb 09 '16 at 10:02

3 Answers3

0
public String getCamerPath(Context context) {
        SharedPreferences prefs = context.getSharedPreferences("setCamerPath", 0);
        String value = prefs.getString("getCamerPath", "");

        return value;

    }

    public void setCamerPath(Context context, String value)

    {
        SharedPreferences prefs = context.getSharedPreferences("setCamerPath", 0);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString("getCamerPath", value);
        editor.commit();
    }

Uri outputFileUri = Uri.fromFile(newFile);

setCamerPath(this, outputFileUri.getPath());
            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
            startActivityForResult(cameraIntent, CAMERA_REQUEST);


@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == REQUEST_SELECT_PICTURE || requestCode == CAMERA_REQUEST) {

                    startCropActivity(getCamerPath(this));

            } else if (requestCode == UCrop.REQUEST_CROP) {
                handleCropResult(data);
            }
        }
        if (resultCode == UCrop.RESULT_ERROR) {
            handleCropError(data);
        }
    }
Rohit Heera
  • 2,709
  • 2
  • 21
  • 31
  • `startCropActivity` needs `Uri`.. But `getCamerPath` returns `String`.. Does shared Prefs store the Uri?? – Kevin Murvie Feb 09 '16 at 04:29
  • I did this `final Uri selectedUri = Uri.parse(getCamerPath(SignupStepThreeActivity.this));` but it still doesn't do anything when I click on the Ok button.. – Kevin Murvie Feb 09 '16 at 07:40
  • you need to debug your code if you get the path in onActivityResult or not – Rohit Heera Feb 09 '16 at 09:05
  • Nevermind, I'm going to post the result in a bit, it's because of I had `cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);` before starting the camera, I now know that the Data doesn't even have Uri return, but bitmap.. I had to convert Bitmap to Uri and voilaa – Kevin Murvie Feb 09 '16 at 09:52
0

In the camera OnClickListener, I commented some stuffs like this :

Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            //Uri outputFileUri = Uri.fromFile(newFile);
            //cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
            //setCamerPath(SignupStepThreeActivity.this, outputFileUri.getPath());
            startActivityForResult(cameraIntent, CAMERA_REQUEST);

In my onActivityResult, I've modified a part of CAMERA_REQUEST :

else if (requestCode == CAMERA_REQUEST) {
                Uri capturedImageUri = data.getData();
                Bitmap bitmap;
                if (capturedImageUri != null) {
                    startCropActivity(capturedImageUri);
                } else {
                    Toast.makeText(SignupStepThreeActivity.this, R.string.toast_cannot_retrieve_selected_image, Toast.LENGTH_SHORT).show();
                    Bundle extras = data.getExtras();
                    bitmap = (Bitmap) extras.get("data");
                    Uri imageUri = getImageUri(SignupStepThreeActivity.this, bitmap);
                    startCropActivity(imageUri);
                }
            }

So basically as I've been reading around for the past 4 hours, data is Intent. It will always be not null BUT will not always contain Uri itself for the image. Because I need the Uri for a library I'm using, I use a method called getImageUri from another Stackoverflow answer.

public static Uri getImageUri(Context inContext, Bitmap inImage)
    {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
        return Uri.parse(path);
    }

Now the problem lies with bitmap image quality after taking the image, I'm going to tinker around with it and be back with an update.

Kevin Murvie
  • 2,592
  • 1
  • 25
  • 43
0
This can also resolve the problem
@Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d("camera", "onSaveInstance");

        // save file url in bundle as it will be null on screen orientation
        // changes
        outState.putParcelable("file_uri", fileUri);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.d("camera", "onRestoreInstance");
        // get the file url
        fileUri = savedInstanceState.getParcelable("file_uri");
    }
Rohit Heera
  • 2,709
  • 2
  • 21
  • 31
  • Ahh that is for the part where user might press home or anything which sets the app not currently running, right? I used it in another class, thanks though :D – Kevin Murvie Feb 11 '16 at 04:53