casillas
casillas

Reputation: 16793

Taken image is not found, FileNotFoundException

I am working on application where user could take a pic and put it into recyclerview networkImageview as follows. I am taking picture but this picture is not assigned to the networkImage.

The following line throws an exception

 InputStream is = context.getContentResolver().openInputStream(uri);

java.io.FileNotFoundException: No content provider: /storage/emulated/0/Pictures/JPEG_20160219_113457_-713510024.jpg

MainActivity Class

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

    if (requestCode == 100 && resultCode == Activity.RESULT_OK) {
        String path = ImageUtil.camPicturePath;
        mCurrentItem.setPath(path);
        mAdapter.notifyDataSetChanged();
        mCurrentItem = null;
        mCurrentPosition = -1;
    }
}

RecylerViewAdapter

@Override
    public void onBindViewHolder(final ListViewHolder holder, int position) {
        PostProductImageLIst item = mItems.get(position);
        ImageUtil.getInstance().setSelectedPic(holder.imgViewIcon, item.getPath());
    }

ImageUtilClass

public static String camPicturePath;

public static void captureImage(Activity activity) {
        File photoFile = null;
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(activity.getPackageManager()) != null) {
            // Create the File where the photo should go
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                // Error occurred while creating the File
                ex.printStackTrace();
            }
            // Continue only if the File was successfully created
            if (photoFile != null) {
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                        Uri.fromFile(photoFile));
                activity.startActivityForResult(takePictureIntent, 100);
            }
        }
        camPicturePath = (photoFile != null) ? photoFile.getAbsolutePath() : null;
    }


private LruCache<String, Bitmap> mMemoryCache;

public void setSelectedPic(CustomNetworkImageView view, String url) {
    Context context = view.getContext();
    if (!TextUtils.isEmpty(url)) {
        if (url.startsWith("http")) {
            view.setImageUrl(url, CustomVolleyRequest.getInstance(context).getImageLoader());
        } else {
            try {
                Uri uri = Uri.parse(url);
                Bitmap bitmap = mMemoryCache.get(url);
                if (bitmap == null) {
                    InputStream is = context.getContentResolver().openInputStream(uri);
                    bitmap = BitmapFactory.decodeStream(is);
                    Bitmap scaled = ImageUtil.getInstance().scaleBitmap(bitmap);
                    mMemoryCache.put(url, scaled);
                    if (is!=null) {
                        is.close();
                    }
                }
                view.setLocalImageBitmap(bitmap);
            } catch (Exception ex) {
                Log.e("Image", ex.getMessage(), ex);
            }
        }
    } else {
        view.setImageUrl("", CustomVolleyRequest.getInstance(view.getContext()).getImageLoader());
    }
}
public Bitmap scaleBitmap(Bitmap bitmap) {
    int width = WIDTH;
    int height = (WIDTH * bitmap.getHeight()) / bitmap.getWidth();
    return Bitmap.createScaledBitmap(bitmap, width, height, false);
}

Upvotes: 1

Views: 2017

Answers (2)

andrea.petreri
andrea.petreri

Reputation: 4147

You need to be careful when taking picture both from camera and gallery. First of all you need to properly handle Intent for picking photo. Below I reported a possible implementation for building it.

If you need to both get photo from camera and gallery.

public Intent buildPicturePickerIntent(PackageManager packageManager) {
    // Camera
    final List<Intent> cameraIntents = new ArrayList<>();
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
    for (ResolveInfo res : listCam) {
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(packageName);
        cameraIntents.add(intent);
    }
    // Filesystem
    final Intent galleryIntent = new Intent();
    galleryIntent.setType("image/*");
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
    // Chooser of filesystem options
    final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
    // Add the camera options
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
            cameraIntents.toArray(new Parcelable[cameraIntents.size()]));
    // returning intent
    return chooserIntent;
}

What is important is that implementation for onActivityResult must handle photo taken from camera and photo taken from gallery in a different way. Below you can see sample code:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_IMAGE_CODE && resultCode == RESULT_OK) {
        Uri uri = data.getData();
        // photo from gallery?
        if (uri != null) {
            // yes, photo from gallery
            String path = uri.toString();
            // use path here
            // ... 
        } else {
            // no, photo from camera
            Bitmap photo = (Bitmap) data.getExtras().get("data");
            // store bitmap (eventually scaling it before) 
            // in filesystem here and get absolute path
            // ...                
        }
        // do your common work here (e.g. notify UI)
    }
} 

Be careful about two things in storing Bitmap on file system:

  • When storing a new Bitmap, you will have its absolute path. Of course you can use it, but if you want to manage in same way photos from camera and photos from gallery, you need to make a conversion from absolute path to Content URI. You can find many answer to this problem here on SO.
  • If you are targeting API 23 you need to explicitly handle Storage permission. Otherwise, when you will try to save on storage the bitmap taken from camera on Android 6 devices, you will get a Permission Denied error.

Here you can find sample code for picking image from gallery / camera and update recycler view item accordingly.

Upvotes: 2

Sree Reddy Menon
Sree Reddy Menon

Reputation: 1311

it seems that you are passing uri instead of URL.

InputStream is = (InputStream) new URL(encodedurl).getContent();
             Bitmap d = BitmapFactory.decodeStream(is);

Android BitmapFactory.decodeStream(...) doesn't load HTTPS URL on emulator

 File file = new File(url);
        BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            FileInputStream fis = new FileInputStream(f);
            Bitmap b= BitmapFactory.decodeStream(fis, null, o);
            fis.close();


public void showCamera() {
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    File photo = new File(Environment.getExternalStorageDirectory(),
            Calendar.getInstance().getTimeInMillis() + ".jpg");
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
    imageUri = Uri.fromFile(photo);
    startActivityForResult(intent, CAMERA_INTENT_CALLED);
}

if (requestCode == CAMERA_INTENT_CALLED) {

                Uri selectedImage = imageUri;
                try {
                    if (selectedImage != null) {
                        getContentResolver().notifyChange(selectedImage, null);
                        String path = getRealPathFromURI(selectedImage);
                        Log.e("Imagepath Camera", path);
                        imageUri = null;
                    }
            } catch (Exception e) {

                Log.e("Camera", e.toString());

            }

        }

private String getRealPathFromURI(Uri contentURI) {
    Cursor cursor = getContentResolver().query(contentURI, null, null,
            null, null);
    if (cursor == null) { // Source is Dropbox or other similar local file
                            // path
        return contentURI.getPath();
    } else {
        cursor.moveToFirst();
        int idx = cursor
                .getColumnIndex(MediaStore.Images.ImageColumns.DATA);
        return cursor.getString(idx);
    }
}

Upvotes: 2

Related Questions