简体   繁体   中英

FileNotFoundException while picking images from gallery

I am picking images form Gallery but the following code snippet create the FileNotFoundException. Code is fine but I don't know why it raises the exception. Thanks in advance

Here is the Logcat Message:

Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/Pictures/Screenshots/Screenshot_2015-09-15-17-27-49.png: open failed: EACCES (Permission denied)

Below is my code

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==0010 && resultCode== RESULT_OK && data!=null)
        {
            Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };

            Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String imgDecodableString = cursor.getString(columnIndex);
            cursor.close();

            Testing = (ImageView) findViewById(R.id.testing);
            // Set the Image in ImageView after decoding the String
            Testing.setImageBitmap(BitmapFactory.decodeFile(imgDecodableString));

        } else {
            Utility.message(EditProfileActivity.this, "You've not picked image");
        }
    }

Better use the following class which will return the file path.doesn't matter from where ever you chosen.your code will fail some times for example if your choosing from google drive you might not get the path with the above code.check out..

import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;


public class FetchPath {
    /**
     * Get a file path from a Uri. This will get the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     * @author paulburke
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static String getPath(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

}

Usage

 Uri photoUri = data.getData();
 if (photoUri != null) {
 String filePath = FetchPath.getPath(this, photoUri);
  }

Gallery Intent

 Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
 photoPickerIntent.setType("image/*");
 startActivityForResult(photoPickerIntent, requestCode);

在清单中放一行

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

您可能未将所需的权限添加到清单中,而是添加了读取外部存储的用户权限

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

I had the same issue as this one. My code was working all night then upon waking up in the morning nothing seems to be working anymore. I had everything setup even:

  1. Intent

     Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); photoPickerIntent.setType("image/*"); // Ensure that there's a gallery to handle the intent if (photoPickerIntent.resolveActivity(getPackageManager()) != null) { // Launch the gallery startActivityForResult(photoPickerIntent, REQUEST_IMAGE_GALLERY); } 
  2. onActivityResult:

     Uri imageUri = data.getData(); InputStream imageStream = getContentResolver().openInputStream(imageUri); mResultsBitmap = BitmapFactory.decodeStream(imageStream); 
  3. Manifest file:

     uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" 

So I thought I had it all figured out last night then this morning nothing was working.. My solution: I went to my Samsung Settings->Device Maintenance -> Memory and then ->Storage. I started cleaning up memory and the system works again.

It seems that it had to do with low memory since I only had 16GB of total memory and just a few GB left remaining

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM