Android No such file or directory exception

I'm trying to follow this tutorial https://developer.android.com/training/camera/photobasics.html#TaskPath for taking an image and saving the file. It opens the camera, I take a picture, click the check mark, then it crashes. I have found several articles on StackOverflow and have tried all of their solutions that I could understand (which were file.mkdirs() , file.getParentFile().mkdirs() ).

It seems that, even though it's a RuntimeException, the root problem is the IOException (which I catch and print the message). I'm using Genymotion, not sure if that's relevant or not. What have I missed that is keeping me from being able to create the file?

I have added permissions to my manifest:

<uses-feature android:name="android.hardware.camera"
    android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

My button click:

public void onClick(View v) {
    Log.d("DebugMySocks", "Change photo button clicked");
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    try {
        // CHANGED THIS
        mImageUri = FileProvider.getUriForFile(getApplicationContext(), getApplicationContext().getPackageName() + "socks", createImageFile());
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
    } catch (Exception e) {
        Log.d("DebugMySocks", "Error creating file " + e.getMessage());
    }
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    }
}

and the problem code (I think):

  private File createImageFile() throws IOException {
    //ADDED THIS
      int permissionCheck = ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE);
      if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    5);
      }
      // Create an image file name
      String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
      String imageFileName = "JPEG_" + timeStamp + "_";
      File storageDir = Environment.getExternalStorageDirectory();
      Log.d("DebugMySocks", "Storage directory is: " + storageDir);
      File image = new File(Environment.getExternalStorageDirectory() + File.separator + "socks"+ File.separator + imageFileName);
      Log.d("DebugMySocks", "getAbsoluteFile: " + image.getAbsoluteFile());
      image.getParentFile().mkdirs();
      image.mkdirs();
      image.createNewFile();
      //File image = File.createTempFile(
      //        imageFileName,  /* prefix */
      //        ".jpg",         /* suffix */
      //        storageDir      /* directory */
      //);

      // Save a file: path for use with ACTION_VIEW intents
      mCurrentPhotoPath = image.getAbsolutePath();
      return image;
  }

Output from LogCat:

12-14 08:05:01.411 4967-4967/com.example.kevin.moresocksplease D/DebugMySocks: Change photo button clicked
12-14 08:05:01.412 4967-4967/com.example.kevin.moresocksplease D/DebugMySocks: Storage directory is: /storage/emulated/0
12-14 08:05:01.413 4967-4967/com.example.kevin.moresocksplease D/DebugMySocks: getAbsoluteFile: /storage/emulated/0/socks/JPEG_20171214_080501_
12-14 08:05:01.416 4967-4967/com.example.kevin.moresocksplease D/DebugMySocks: Error creating file No such file or directory

And the exception:

FATAL EXCEPTION: main
Process: com.example.kevin.moresocksplease, PID: 4967
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=111, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.example.kevin.moresocksplease/com.example.kevin.moresocksplease.EditProfileActivity}: java.lang.NullPointerException: uri
 at android.app.ActivityThread.deliverResults(ActivityThread.java:4089)
 at android.app.ActivityThread.handleSendResult(ActivityThread.java:4132)
 at android.app.ActivityThread.-wrap20(ActivityThread.java)
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1533)
 at android.os.Handler.dispatchMessage(Handler.java:102)
 at android.os.Looper.loop(Looper.java:154)
 at android.app.ActivityThread.main(ActivityThread.java:6119)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.NullPointerException: uri
 at com.android.internal.util.Preconditions.checkNotNull(Preconditions.java:111)
 at android.content.ContentResolver.notifyChange(ContentResolver.java:1714)
 at android.content.ContentResolver.notifyChange(ContentResolver.java:1693)
 at com.example.kevin.moresocksplease.EditProfileActivity.onActivityResult(EditProfileActivity.java:254)
 at android.app.Activity.dispatchActivityResult(Activity.java:6932)
 at android.app.ActivityThread.deliverResults(ActivityThread.java:4085)
 at android.app.ActivityThread.handleSendResult(ActivityThread.java:4132) 
 at android.app.ActivityThread.-wrap20(ActivityThread.java) 
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1533) 
 at android.os.Handler.dispatchMessage(Handler.java:102) 
 at android.os.Looper.loop(Looper.java:154) 
 at android.app.ActivityThread.main(ActivityThread.java:6119) 
 at java.lang.reflect.Method.invoke(Native Method) 
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

Lastly, including because it's in the exception stack:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("DebugMySocks", "onActivityResult in EditProfileActivity");
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == this.RESULT_OK) {
        this.getContentResolver().notifyChange(mImageUri, null); // <-- THIS IS LINE 254!
        ContentResolver cr = this.getContentResolver();
        Bitmap bitmap;
        try
        {
            bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageUri);
            mProfileImage.setImageBitmap(bitmap);
            saveToFirebase(bitmap);
        }
        catch (Exception e)
        {
            Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
            Log.d("DebugMySocks", "Failed to load", e);
        }
    }
}

Additional links that I've been drawing information from:

File.createNewFile() thowing IOException No such file or directory

Android Camera Intent: how to get full sized photo?

Edit 1:

After viewing this, I added logs to the mkdir requests and they both return false. According to this gentleman, that means the directories already exist, so it's just the creation of the file that is failing? Creating a directory in /sdcard fails

Log.d("DebugMySocks", "parentfile mkdirs: " + image.getParentFile().mkdirs());
Log.d("DebugMySocks", "image.mkdirs: " + image.mkdirs());
Log.d("DebugMySocks", "create file: " + image.createNewFile());

DebugMySocks: parentfile mkdirs: false
DebugMySocks: image.mkdirs: false
DebugMySocks: Error creating file No such file or directory

Edit 2: I now have:

public void onClick(View v) {
                        Log.d("DebugMySocks", "Change photo button clicked");
                        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        try {
                            if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED) {
                                mImageUri = FileProvider.getUriForFile(getApplicationContext(), getApplicationContext().getPackageName() + "socks", createImageFile());
                            } else {
                                Log.v("DebugMySocks","Permission is revoked");
                                ActivityCompat.requestPermissions(getParent(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                            }
                            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
                        } catch (Exception e) {
                            Log.d("DebugMySocks", "Error creating file " + e.getMessage());
                        }
                        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
                        }
                    }

    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 0:
                boolean permissionsGranted = true;
                if (grantResults.length > 0 && permissions.length==grantResults.length) {
                    for (int i = 0; i < permissions.length; i++){
                        if (grantResults[i] != PackageManager.PERMISSION_GRANTED){
                            permissionsGranted=false;
                        }
                    }

                } else {
                    permissionsGranted=false;
                }
                if(permissionsGranted){
                    try {
                        mImageUri = FileProvider.getUriForFile(getApplicationContext(), getApplicationContext().getPackageName() + "socks", createImageFile());
                    } catch (Exception e) {
                        Log.d("DebugMySocks", "Permissions granted but exception happened " + e.getMessage());
                    }
                }
                break;
        }
    }

But I get Error creating file Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference


如果被用户授予,您需要检查权限。

private void checkPermission(){
    if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED) {        
        createFile();
    } else {    
        Log.v(TAG,"Permission is revoked");
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);  
    }
}


@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 0:
            boolean permissionsGranted = true;
            if (grantResults.length > 0 && permissions.length==grantResults.length) {
                for (int i = 0; i < permissions.length; i++){
                    if (grantResults[i] != PackageManager.PERMISSION_GRANTED){
                        permissionsGranted=false;
                    }
                }

            } else {
                permissionsGranted=false;
            }
            if(permissionsGranted){
                createFile();
            }
            break;
    }
}

private void createFile(){
   ContentResolver cr = this.getContentResolver();
   Bitmap bitmap;
   try{
       bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageUri);
       mProfileImage.setImageBitmap(bitmap);
       saveToFirebase(bitmap);
   }catch (Exception e){
     Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
     Log.d("DebugMySocks", "Failed to load", e);
   }
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("DebugMySocks", "onActivityResult in EditProfileActivity");
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == this.RESULT_OK) {
        this.getContentResolver().notifyChange(mImageUri, null); // <-- THIS IS LINE 254!
        checkPermission();
    }
}
链接地址: http://www.djcxy.com/p/68824.html

上一篇: C#SqlDataAdaptor更新不更新数据库

下一篇: Android没有这样的文件或目录例外