简体   繁体   中英

FileNotFoundException when fetch image from Internal Storage

Files ==> 在此处输入图片说明 ==> 在此处输入图片说明

As I'm showing in this picture flow, my image(960-Minimalism.jpg) is inside internal phone storage and I'm trying to get it's path for further use through File class.

What I have tried yet

1st:

String filePath = MainActivity.this.getFilesDir().getAbsolutePath();
File file = new File(filePath, "960-Minimalism.jpg");

2nd:

File file = new File(Environment.getExternalStorageDirectory()+ "/Android/data/"+ getApplicationContext().getPackageName()
        + "/Files/"+"960-Minimalism.jpg");

The extreme hard code way:

File file = new File("/data/data/com.example.net/files/","960-Minimalism.jpg")

Exception here same as 1st..

I know I'm missing something or doing something wrong here but unable to find out till now.

Any Idea..

EDIT

Please don't think I have three problems . The above are my tried solutions which not worked. But problem is one that I want to fetch the image path which is in my internal storage memory. That's why I deleted my exceptions here.

Instead of giving the path can you do other way round. Open the phone gallery and select the file that you need then get the file uri and use it. I had had similar problem and I had solved it that way. And sometime the file's extension is jpeg but it shows jpg there and gives error. If you could check the file detail for correct file extension

String filepath = Environment.getExternalStorageDirectory().getAbsolutePath() +...(insert specific file path)
        Bitmap bitmap = BitmapFactory.decodeFile(filepath);

Now you have a bitmap that you can use. But be sure to call recycle()` method on bit once you are done to prevent memory leak.

And to get File Uri you can try following codes that I have directly pasted from one of my project

  Intent i = new Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

        startActivityForResult(i, RESULT_LOAD_IMAGE);

This will open the gallery for you to select image. And once you are done. Override onActivityResult method as below.

  @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && null != data) {
               Uri file = data.getData(); 
              }
else{
// no file selected
}
    }

You can use this file Uri for your image need. Hope it helps.

Getting access to external storage

In order to read or write files on the external storage, your app must acquire the READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE system permissions. For example:

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

If you need to both read and write files, then you need to request only the WRITE_EXTERNAL_STORAGE permission, because it implicitly requires read access as well.

For your 2nd problem add these two permissions to your Manifest file...

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

I just change a little as 1011 suggested and get the solution.

1st problem is the connected device(through data cable) which makes obstacle between memory storage and application. As i understand a physical connection prohibited the device to share its internal memory and also sdcard files.

For the solution I followed 1011's answer and did like:

Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);

and inside onActivityResult I fetched the uri and tried to get the path with a little modified way ..something like:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (resultCode == RESULT_OK && null != data) {
    Uri selectedImageURI = data.getData();
    File imageFile = new File(getRealPathFromURI(selectedImageURI));
    File file1 = new File(file.getPath());
    if(imageFile.exists()){
         Toast.makeText(MainActivity.this, "File Exists..:", Toast.LENGTH_SHORT).show();
    }
    else{
             Toast.makeText(MainActivity.this, "NOooooooooo..:", Toast.LENGTH_SHORT).show();
    }
  }else {
        // no file selected
  }
}

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

The method getRealPathFromURI(Uri contentUri) will help to get the real path with perfect File Extension .

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