android-4.4-kitkatandroid-camera-intentforceclose

Android Camera force close after capturing on KitKat


Currently I am creating apps that allowed user to take photo and show it to an ImageView. It works like charm on Android 5.1.1 Sony M2 Dual. But on Kitkat 4.4.2 Samsung Galaxy Tab 3 and KitKat 4.4.4 Xiaomi Redmi 2, the camera force close after capturing image.

I don't know if this will be useful or not, but I realized that the camera probably force close because after capturing, on those two KitKat device, user will be prompted to accept the captured picture or not, then if accepted, it will be back to my current Activity.

Beacuse on my Sony with 5.1.1, user will not be prompted for the captured picture, it will be straight back to my current Activity.

Here I included the corresponding code.

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

    bAddPhoto = (TextView) findViewById(R.id.bAddPhoto);
    bSaveJOLine = (TextView) findViewById(R.id.bSaveJOLine);

    editDescription = (EditText) findViewById(R.id.editDescription);
    editQty = (EditText) findViewById(R.id.editQty);
    editPrice = (EditText) findViewById(R.id.editPrice);
    ivImage = (ImageView) findViewById(R.id.imageTaken);

    Intent intent = getIntent();
    jobId = intent.getIntExtra("jobId", 0);
    docNo = intent.getStringExtra("docNo");

    bAddPhoto.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if (intentCamera.resolveActivity(getPackageManager()) != null) {
                // Create the File where the photo should go
                File photoFile = null;
                try {
                    photoFile = createImageFile();
                } catch (IOException ex) {
                    // Error occurred while creating the File
                    Toast.makeText(OJobOrderLineFormActivity.this, "Create file failed!",
                            Toast.LENGTH_SHORT).show();
                }
                // Continue only if the File was successfully created
                if (photoFile != null) {
                    Uri photoURI = FileProvider.getUriForFile(OJobOrderLineFormActivity.this,
                            "com.opentoko.opentokolaundry.fileprovider",
                            photoFile);
                    System.out.println(photoURI);
                    intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                    startActivityForResult(intentCamera, 360);
                }
            }
        }
    });

    bSaveJOLine.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Snackbar.make(v, "Item has been saved!", Snackbar.LENGTH_LONG)
                    .setAction("OK", null).show();
        }
    });

}

Create temporary file function :

    private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmm").format(new Date());
    String imageFileName = docNo + "_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
    System.out.println(storageDir);
    System.out.println(image);

    // Save a file: path for use with ACTION_VIEW intents
    currentPhotoPath = image.getAbsolutePath();
    System.out.println(currentPhotoPath);

    return image;
}

onActivityResult :

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case 360:
            if(resultCode == RESULT_OK) {
                int targetW = ivImage.getWidth();
                int targetH = ivImage.getHeight();

                // Get the dimensions of the bitmap
                BitmapFactory.Options bmOptions = new BitmapFactory.Options();
                bmOptions.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(currentPhotoPath, bmOptions);
                int photoW = bmOptions.outWidth;
                int photoH = bmOptions.outHeight;

                // Determine how much to scale down the image
                int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

                // Decode the image file into a Bitmap sized to fill the View
                bmOptions.inJustDecodeBounds = false;
                bmOptions.inSampleSize = scaleFactor;
                bmOptions.inPurgeable = true;

                Bitmap bitmap = BitmapFactory.decodeFile(currentPhotoPath, bmOptions);
                ivImage.setImageBitmap(bitmap);
            }
    }
}

I can't really figured out what causing this because in logcat there is seems no error at all, my build still running like usual. Here is my logcat after entering current activity for take the picture:

D/TextLayoutCache: Enable myanmar Zawgyi converter
D/TextLayoutCache: Enable myanmar Zawgyi converter
D/TextLayoutCache: Enable myanmar Zawgyi converter
D/TextLayoutCache: Enable myanmar Zawgyi converter
I/System.out: /storage/emulated/0/Android/data/com.opentoko.opentokolaundry/files/Pictures
I/System.out: /storage/emulated/0/Android/data/com.opentoko.opentokolaundry/files/Pictures/A-00003_20170127_1758_-1345208956.jpg
I/System.out: /storage/emulated/0/Android/data/com.opentoko.opentokolaundry/files/Pictures/A-00003_20170127_1758_-1345208956.jpg
I/System.out: content://com.opentoko.opentokolaundry.fileprovider/my_images/A-00003_20170127_1758_-1345208956.jpg
W/IInputConnectionWrapper: showStatusIcon on inactive InputConnection

This logcat already in this exact point when it start begin open the camera. After capturing, nothing added to the logcat.

This is part of my Android-Manifest.xml :

    <uses-feature android:name="android.hardware.camera" android:required="true" />

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.opentoko.opentokolaundry.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths">
        </meta-data>
    </provider>

Does anyone here had or has same problem with me? Any solution? Any help will be appreciated.


Solution

  • I've found solution for intent camera force close on KitKat by trial and error. Seems I don't need FileProvider at all.

    I change storageDir in my createImageFile() to this :

    File storageDir = getExternalFilesDir("Pictures");
    

    And photoURI to this :

    Uri photoURI = Uri.fromFile(photoFile);
    

    Now I have the right fullscreen image to display on KitKat too.

    And I remove provider from my manifest. Now I have my captured image file at Android/data/my.package.name/files/Pictures/ folder.