0

I am trying to learn from the official tutorial at https://developer.android.com/training/camera/photobasics.html unfortunetly I cannot get that code to work, as I tinker with the code I get an error relating to the line "File image = File.createTempFile..." and sometimes from other lines depending on how I tinker. Given the code below I get the following errors:

 Caused by: java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Pictures/JPEG_20170213_015919_1702296485.jpg
                      at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:711)
                      at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:400)
                      at aaa.com.sss.MaxweightActivity.dispatchTakePictureIntent(MaxweightActivity.java:353)

Line 353 is the "FileProvider.getUriForFile" line. I have set my targetsdk to 22 to avoid the Marshmallow permissions issues for now. My manifest looks like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="aaa.com.sss">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        />

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


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MaxweightActivity"
            android:label="@string/title_activity_settings"
            android:theme="@style/AppTheme.NoActionBar" />
        <activity android:name=".SettingsActivity" />
        <activity android:name=".listMaxweightsActivity" />

        <activity android:name=".chartsActivity"></activity>



        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="aaa.com.sss.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths"></meta-data>
        </provider>
    </application>


</manifest>

and my filepaths.xml like this:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/aaa.com.sss/files/Pictures" />
</paths>

Java code:

String mCurrentPhotoPath;
private static final int REQUEST_TAKE_PHOTO = 101;

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

    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath =   image.getAbsolutePath();
    Log.d(TAG, " mCurrentPhotoPath " + mCurrentPhotoPath+  " exists "+image.exists());
    return image;
}


private void dispatchTakePictureIntent() {

    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.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
            Log.e(TAG, "dispatchTakePictureIntent   ", ex);
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            Log.d(TAG, " photoFile " + photoFile.getAbsolutePath() +  " exists "+photoFile.exists());
          ///// LINE 353 is next /////////
            Uri photoURI = FileProvider.getUriForFile(this,
                    "aaa.com.sss.fileprovider",
                    photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }
}




@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
       // Bitmap imageBitmap = (Bitmap) extras.get("data");
       // mImageView.setImageBitmap(imageBitmap);
    }
}

public void onCamera(View view) {
    dispatchTakePictureIntent();
  /*  String type = "image*//*";
    String filename = "/myPhoto.jpg";
    String mediaPath = Environment.getExternalStorageDirectory() + filename;
    createInstagramIntent(type, mediaPath);*/
}

I am content to save the photos to the public location. I am trying to make a button which will open the camera, allow me to snap a pic and then return to my app and then maybe associate the pic with a record in my apps DB and then share the image to social media maybe with some extra text data from my app. Since I can't quite get the camera part to work I am stuck. What am I doing wrong?

BTW, I know this same official tutorial has been asked about many times and I have tried to read a bunch of the answers but there seem to be many issues with this official code so I'm not sure what to believe. Another error I've had is that the data is null when returning from the camera, that one I can worry about later once this exception is figured out.

Thanks

PS: I know this is probably the same issue as the other question but then again it may not be exactly the same as I am targeting sdk 22 and the other may be targeting 23 and therefore might be encountering an issue related to the new permissions model. That other question remains unanswered and I tried the suggested solution there to no avail. A couple more log messages (added into my posted code above) reveals that the temp file at least got created:

SS_MaxweightActivity:  path true:
D/SS_MaxweightActivity:  mCurrentPhotoPath /storage/emulated/0/Pictures/JPEG_20170213_160915_649829663.jpg exists true
D/SS_MaxweightActivity:  photoFile /storage/emulated/0/Pictures/JPEG_20170213_160915_649829663.jpg exists true

UPDATE: New code (below, taken from 2 or 3 sources) seems to work for my uses but skips the FileProvider stuff, now to test it against a variety of Android versions - will this code work on Android 7.0 devices?

    static final int SHARETO = 2;
    static final int TAKE_PICTURE = 1;
    private Uri imageUri;



    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d(TAG, " onActivityResult 1 :"  );
        switch (requestCode) {
            case TAKE_PICTURE:
                if (resultCode == Activity.RESULT_OK) {
                    Uri selectedImage = imageUri;
                    String type = "image/*";
                    createInstagramIntent(type  );
                }
                Log.d(TAG, " onActivityResult 2 :"  );
                break;
            case SHARETO:
                Log.d(TAG, " onActivityResult 3 :"  );
                break;
        }


        Log.d(TAG, " onActivityResult end :"  );
    }

    public void onCamera(View view) {
        Log.d(TAG, " onCamera 1 :"  );
        imageUri = null;
        takePhoto(view) ;

        Log.d(TAG, " onCamera 2 :"  );
    }



    public void takePhoto(View view) {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + ".jpg";
        File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File photo = new File(path,  imageFileName);
        imageUri = Uri.fromFile(photo);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

        Log.d(TAG, "takePhoto imageUri path  :"+imageUri.getPath()  );
        startActivityForResult(intent, TAKE_PICTURE);
    }


    private void createInstagramIntent(String type){ //, String mediaPath
        // Create the new Intent using the 'Send' action.
        Intent share = new Intent(Intent.ACTION_SEND);
        // Set the MIME type
        share.setType(type);
        //  copy lift data to clipboard

        // Add the URI to the Intent.
        share.putExtra(Intent.EXTRA_STREAM, imageUri);
        // Broadcast the Intent.
        startActivityForResult(Intent.createChooser(share, getString(R.string.shareto)), SHARETO);
    }
lost baby
  • 3,178
  • 4
  • 32
  • 53
  • Isn't it the same http://stackoverflow.com/questions/40498380/java-lang-illegalargumentexception-failed-to-find-configured-root-that-contains – laser Feb 13 '17 at 07:44
  • Possible duplicate of [java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Pictures/](http://stackoverflow.com/questions/40498380/java-lang-illegalargumentexception-failed-to-find-configured-root-that-contains) – laser Feb 13 '17 at 07:44
  • I tried and File storageDir = getFilesDir( ); but that just give another exception : Caused by: java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/aaa.com.sss/files/JPEG_20170213_025321_1485507710.jpg – lost baby Feb 13 '17 at 07:55
  • when I try Environment.getExternalStoragePublicDirectory with the app crashes without any log messages. – lost baby Feb 13 '17 at 07:58
  • createImageFile simply uses external path. That is answer to your error message reason... now is the question how to handle it. Have you tried external-path? – laser Feb 13 '17 at 07:59
  • external-path is the original try, files-path is just what was suggested in the linked questions above. – lost baby Feb 13 '17 at 08:03

0 Answers0