1

I have an error whenever I try to take a picture by using camera intent.

This is the error

FileNotFoundException: No files supported by provider at content://com.example.fahad.inventory/my_images/dcim/Inventory/JPEG20170922_170324_1975076666.jpg

 at com.example.fahad.inventory.AddProductActivity.getBitmap(AddProductActivity.java:270) 09-22 17:03:30.117 12950-12950/? W/System.err:     at com.example.fahad.inventory.AddProductActivity.onActivityResult(AddProductActivity.java:197)

This is my code

public class AddProductActivity extends AppCompatActivity {

private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final int REQUEST_SELECT_IMAGE = 2;

private static final String IMAGE_PATH = "imagePath";
private static final String IMAGE_URI = "imageUri";
private static final String BITMAP = "bitmap";

private static final String CAMERA_DIR = "/dcim/";

private String imagePath = "";
private String imageUri = "";

private ImageView imageView;
private Bitmap bitmap;

private Uri mUri;

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

    Button addProduct = (Button) findViewById(R.id.id_btn_add_product);
    Button addImage = (Button) findViewById(R.id.id_btn_add_image);
    Button addGalleryImage = (Button) findViewById(R.id.id_btn_add_gallery_image);

    imageView = (ImageView) findViewById(R.id.id_image_view);

    if (savedInstanceState != null) {
        imagePath = savedInstanceState.getString(IMAGE_PATH);
        imageUri = savedInstanceState.getString(IMAGE_URI);
        bitmap = (Bitmap) savedInstanceState.get(BITMAP);
        imageView.setImageBitmap(bitmap);
    }

    addProduct.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            insert();
        }
    });

    addImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            try {
                File f = createImageFile();

                mUri = FileProvider.getUriForFile(
                        AddProductActivity.this, ProductContract.CONTENT_AUTHORITY, f);

                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);

                // Solution taken from http://stackoverflow.com/a/18332000/3346625
                if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
                    List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(takePictureIntent, PackageManager.MATCH_DEFAULT_ONLY);
                    for (ResolveInfo resolveInfo : resInfoList) {
                        String packageName = resolveInfo.activityInfo.packageName;
                        grantUriPermission(packageName, mUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    }
                }

                if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

    addGalleryImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
            } else {
                intent = new Intent(Intent.ACTION_GET_CONTENT);
            }
            intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setType("image/*");
            startActivityForResult(Intent.createChooser(intent, "Select image"), REQUEST_SELECT_IMAGE);
        }
    });

}

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG" + timeStamp + "_";
    File albumF = getAlbumDir();
    File imageF = File.createTempFile(imageFileName, ".jpg", albumF);
    return imageF;
}

private File getAlbumDir() {
    File storageDir = null;

    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {

        storageDir = new File(Environment.getExternalStorageDirectory()
                + CAMERA_DIR
                + getString(R.string.app_name));

        if (storageDir != null) {
            if (!storageDir.mkdirs()) {
                if (!storageDir.exists()) {
                    return null;
                }
            }
        }
    } else {
        Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
    }

    return storageDir;
}

public void insert() {
    EditText editProductName = (EditText) findViewById(R.id.id_edit_product_name);
    EditText editProductPrice = (EditText) findViewById(R.id.id_edit_product_price);
    EditText editProductQuantity = (EditText) findViewById(R.id.id_edit_product_quantity);


    String name = editProductName.getText().toString();
    String quantity = editProductQuantity.getText().toString();
    String price = editProductPrice.getText().toString();

    ContentValues values = new ContentValues();

    values.put(ProductContract.ProductColumns.PRODUCT_NAME, name);
    values.put(ProductContract.ProductColumns.PRODUCT_QUANTITY, quantity);
    values.put(ProductContract.ProductColumns.PRODUCT_PRICE, price);
    values.put(ProductContract.ProductColumns.PRODUCT_IMAGE_PATH, imagePath);
    values.put(ProductContract.ProductColumns.PRODUCT_IMAGE_URI, imagePath);

    Uri uri = getContentResolver().insert(ProductContract.ProductColumns.CONTENT_URI, values);
    if (uri != null) {
        finish();
    }
}

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

        imageUri = mUri.getPath();
        bitmap = getBitmap(mUri);
        imageView.setImageBitmap(bitmap);

    } else if (requestCode == REQUEST_SELECT_IMAGE && resultCode == RESULT_OK) {
        if (data != null) {
            Uri uri = data.getData();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                final int flags = data.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION;
                ContentResolver contentResolver = getContentResolver();
                contentResolver.takePersistableUriPermission(uri, flags);
            }
            imageView.setImageBitmap(getBitmapFromUri(uri));
            imageUri = uri.toString();
            imagePath = uri.toString();
        }
    }

}

public Bitmap getBitmapFromUri(Uri uri) {

    if (uri == null || uri.toString().isEmpty())
        return null;

    // Get the dimensions of the View
    int targetW = imageView.getWidth();
    int targetH = imageView.getHeight();

    InputStream input = null;
    try {
        input = this.getContentResolver().openInputStream(uri);

        // Get the dimensions of the bitmap
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(input, null, bmOptions);
        input.close();

        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;

        input = this.getContentResolver().openInputStream(uri);
        Bitmap bitmap = BitmapFactory.decodeStream(input, null, bmOptions);
        input.close();
        return bitmap;

    } catch (FileNotFoundException fne) {
        fne.printStackTrace();
        return null;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        try {
            input.close();
        } catch (IOException ioe) {

        }
    }
}

private Bitmap getBitmap(Uri uri) {
    ParcelFileDescriptor parcelFileDescriptor = null;
    try {
        parcelFileDescriptor =
                getContentResolver().openFileDescriptor(uri, "r");
        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
        Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
        parcelFileDescriptor.close();
        return image;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        try {
            if (parcelFileDescriptor != null) {
                parcelFileDescriptor.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString(IMAGE_PATH, imagePath);
    outState.putString(IMAGE_URI, imageUri);
    outState.putParcelable(BITMAP, bitmap);
}

The contentAuthority is my package name.

com.example.fahad.inventory

And this is my paths :

<?xml version="1.0" encoding="utf-8"?>
 <paths>
<external-path name="my_images" />
 </paths>

And this is my provider in manifest :

<provider
        android:name=".data.ProductProvider"
        android:authorities="com.example.fahad.inventory"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_paths" />
    </provider>

I have seen some posts like this by I don't understands it. or it didn't help me with my problem.

The error in the logs are pointing to :

getContentResolver().openFileDescriptor(uri, "r");

Also the data returned in onActivityResult from the camera is always null.

I think the problem is I have to implement OpenFile method in my custom contentProvider but the problem I don't know what to write in that method.

Or the getUriForFile return wrong uri.

Please help me I'm in this problem for two weeks now and it seems I'm not going anywhere. And I'm new to contentProvider.

Thanks in Advance And happy coding !

Punit
  • 324
  • 1
  • 4
  • 17
Fahd Al-Qahtani
  • 188
  • 1
  • 9
  • ProductProvider is extended from? And why dont you just use FileProvider? – greenapps Sep 22 '17 at 15:00
  • ProdcutProvider is extending ContentProvider @greenapps – Fahd Al-Qahtani Sep 22 '17 at 15:12
  • `No files supported by provider at`. Well so this message comes from your provider. Can you find it in the source? – greenapps Sep 22 '17 at 15:15
  • It points to getContentResolver().openFileDescriptor(uri, "r"); @greenapps – Fahd Al-Qahtani Sep 22 '17 at 15:17
  • ??? That is the statement that causes the error message. But I asked for code in your contentprovider that gives this error message. – greenapps Sep 22 '17 at 15:20
  • Are you telling that getBitmapFromUri() works ok and getBitmap() not? Why do you need two? – greenapps Sep 22 '17 at 15:21
  • `` You only need that if you extend from FileProvider i think. In which way are you using it? – greenapps Sep 22 '17 at 15:24
  • I am sorry for the bad naming .. getBitmap() is called when i try to get the picture that was taking by the camera and it is not working .. getBitmapFromUri() for getting bitmaps from gallery and yes it is working .. in my provider it points to openFile method which I left it empty and just has this line of code : return super.openFile(uri, mode); @greenapps – Fahd Al-Qahtani Sep 22 '17 at 15:27
  • @greenapps I used custom content provider to save a data with a picture with every data, that way i used content provider – Fahd Al-Qahtani Sep 22 '17 at 15:29
  • If your provider does not work then the camera app cannot save the picture too as then openFile() has to be used too. Did you ever check if the camera app saved the picture? – greenapps Sep 22 '17 at 15:29
  • You let the camera app use your provider with a content scheme. But your app yourself can load the saved picture just from file of course. Your app does not have to use it's own content provider. But then it should work also. Start with just checking if the camera app created the picture file. – greenapps Sep 22 '17 at 15:31
  • No it doesnt save the picture @greenapps – Fahd Al-Qahtani Sep 22 '17 at 15:33
  • Then your post is nonsense. You should have told that right away. What sense does it have to call getBitmap() if there is no file? – greenapps Sep 22 '17 at 15:34
  • Im sorry i dont understand you .. so what is the solution ? can we move to a chat ? @greenapps – Fahd Al-Qahtani Sep 22 '17 at 15:35
  • @greenapps my reputation is very low we cant move to chat sorry :( – Fahd Al-Qahtani Sep 22 '17 at 15:37
  • `Log.d(TAG, "open-File() mode: " + mode ); // "w" or "r" Log.d(TAG, "open-File() uri.getPath(): " + uri.getPath() ); // "/" Log.d(TAG, "open-File() uri.toString(): " + uri.toString() ); `. Place those log statements in your openFile() code. – greenapps Sep 22 '17 at 15:42
  • Then develop your contentprovider not using the camera app. Just let the uri point to an existing jpg file and then call getBitMap(uri). Look what is logged by openFIle(). – greenapps Sep 22 '17 at 15:45
  • I think that in xml external-path element you need to include the "path" attribute. – Tom Rutchik Jun 24 '23 at 22:03

0 Answers0