【问题标题】:java.io.FileNotFoundException:打开失败:Android 中的 ENOENT 错误
【发布时间】:2020-08-25 22:14:40
【问题描述】:

我正在尝试通过从照片中选择图像来获取文件并获取意图数据,将文件保存在内部存储器中并使用该文件加载图像视图。

但我收到如下错误:

java.io.FileNotFoundException:/storage/emulated/0/Android/data/com.dailyfaithapp.dailyfaith/Files/MI_10052020_1711.png:打开失败:ENOENT(没有这样的文件或目录)

我检查了较低版本的 api,即在 24 上它工作了一两次,但又失败了。

在 api 29 上它根本不起作用。为此,我遵循了这个网址: https://medium.com/@sriramaripirala/android-10-open-failed-eacces-permission-denied-da8b630a89df

我检查了java中的代码并尝试了同样的方法,但仍然给出了错误。

我也在检查运行时权限,并在清单文件中指定了权限。

以下是我的代码:

<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name = "android.permission.WAKE_LOCK" />
<uses-permission android:name = "android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name = "com.google.android.apps.photos.permission.GOOGLE_PHOTOS" />

检查运行时权限:

private boolean checkPermission() {

        return ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                ;
    }

    private void requestPermissionAndContinue() {
        if (ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(this, WRITE_EXTERNAL_STORAGE)
                    && ActivityCompat.shouldShowRequestPermissionRationale(this, READ_EXTERNAL_STORAGE)) {
                AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
                alertBuilder.setCancelable(true);
                alertBuilder.setTitle("Allow Daily Faith to access photos," +
                        "media, and files on your device?");
                alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions(ThemesActivity.this,
                                new String[]{WRITE_EXTERNAL_STORAGE
                                , READ_EXTERNAL_STORAGE}, 200);
                    }
                });
                AlertDialog alert = alertBuilder.create();
                alert.show();
                Log.e("", "permission denied, show dialog");
            } else {
                ActivityCompat.requestPermissions(ThemesActivity.this,
                        new String[]{WRITE_EXTERNAL_STORAGE,
                        READ_EXTERNAL_STORAGE}, 200);
            }
        } else {
            selectImageFromGallery();
        }
    }

检查是否已授予权限:

  if (!checkPermission()) {
                    selectImageFromGallery();
                } else {
                    if (checkPermission()) {
                        requestPermissionAndContinue();
                    } else {
                        selectImageFromGallery();
                    }
                }

打开意图:

  public void selectImageFromGallery()
    {
        Intent pickPhoto = new Intent(Intent.ACTION_PICK,
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(pickPhoto , 2);

    }

获取结果的意图数据:

 @RequiresApi(api = Build.VERSION_CODES.KITKAT) @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // Check which request we're responding to
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 2) {
            // Make sure the request was successful
            if (resultCode == RESULT_OK) {
                // The user picked a image.
                // The Intent's data Uri identifies which item was selected.
                if (data != null) {

                    customTheme = true;
                    // This is the key line item, URI specifies the name of the data
                    mImageUri = data.getData();

                    // Saves image URI as string to Default Shared Preferences
                    SharedPreferencesData sharedPreferencesData =
                            new SharedPreferencesData(this);

                    sharedPreferencesData.setStr("customThemeSet","true");


                    try {
                        Bitmap bitmap =
                                MediaStore.Images.Media.getBitmap(getContentResolver(), mImageUri);

               /*         Utils.storeImage(bitmap,
                                ThemesActivity.this);

                        File file = Utils.getOutputMediaFile(ThemesActivity.this);
*/

                        try {
                            final ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(
                                    mImageUri, "r");
                            final FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
                            bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
                            parcelFileDescriptor.close();

                            Utils.storeImage(bitmap,
                                    ThemesActivity.this);

                            File file = Utils.getOutputMediaFile(ThemesActivity.this);

                    int color = Utils.getDominantColor(bitmap);
                    Log.d("Bitmap", bitmap.toString());
                    Boolean isDark = Utils.isColorDark(color);

                    if(customTheme) {
                        for (Themes themes : themesArrayList) {

                            themes.setCustomTheme(file.getPath());
                            themes.setDark(isDark);
                        }

                        if(isDark)
                            sharedPreferencesData.setStr("ThemeColor","dark");
                        else
                            sharedPreferencesData.setStr("ThemeColor","light");

                        themesAdapter = new ThemesAdapter(themesArrayList, this,customTheme);
                        recyclerView.setAdapter(themesAdapter);
                    }

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

                    } catch (Exception e) {
                        Log.e("Failed", "Failed to Parse Image Uri", e);
                        try {
                            throw new Exception("failed to parse image uri");
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }

                }
            }
        }
    }

保存和获取文件

  public static File getOutputMediaFile(Context context){
        // To be safe, you should check that the SDCard is mounted
        // using Environment.getExternalStorageState() before doing this.
        File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
                + "/Android/data/"
                + context.getApplicationContext().getPackageName()
                + "/Files");

        // This location works best if you want the created images to be shared
        // between applications and persist after your app has been uninstalled.

        // Create the storage directory if it does not exist
        if (! mediaStorageDir.exists()){
            mediaStorageDir.mkdirs();
        }
        else {
            return null;
        }
        // Create a media file name
        String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
        File mediaFile;
        String mImageName="MI_"+ timeStamp +".png";
        mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
        return mediaFile;
    }
    public static void storeImage(Bitmap image,Context context) {
        File pictureFile = getOutputMediaFile(context);
        if (pictureFile == null) {
            Log.d(TAG,
                    "Error creating media file, check storage permissions: ");// e.getMessage());
            return;
        }
        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            image.compress(Bitmap.CompressFormat.PNG, 90, fos);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }

在我只使用以上两个函数保存文件时收到 EACCESS 错误之前。

后来我尝试了 Parcel 文件描述符但无法正常工作 为什么我会收到此错误?它是否也仅在 api 级别 29 或以下? 在所有设备上运行的解决方案是什么?

【问题讨论】:

    标签: java android android-permissions enoent parcelfiledescriptor


    【解决方案1】:

    我添加了这个权限,它可以工作。

    <uses-permission
            enter code hereandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
            tools:ignore="ProtectedPermissions" />
    

    【讨论】:

      【解决方案2】:

      这对我有用 使用所有新旧手机都可以公开访问的下载文件夹..

      试试{

       File csvfile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/brcOrdersaved.csv");
              final String filename = csvfile.toString();
      
              if (!csvfile.exists()) {
                  // displayMsg(context, "No Saved Order: ");
                  return (false);
              } 
              FileReader fr = new FileReader(filename);
              BufferedReader reader = new BufferedReader(fr);
      
              String csvLine = "";
              final char Separator = ',';
              final char Delimiter = '"';
              final char LF = '\n';
              final char CR = '\r';
              boolean quote_open = false;
              if (reader.equals(null)) {
                  displayMsg(context, "NULL");
                  return (false);//rww 11/13/2021
              }
              int i = 0;
              while (!myendofcsvfile) {
      
                  csvLine = reader.readLine();
                  if (csvLine == null) {
                      myendofcsvfile = true;
      
                  } 
                      // do stuff here
              }
      
              fr.close();
              fileexists = true;
      
          } catch (Exception e) {
      
              String msg = "Can not Load Saved Order ";
              fileexists = false;
              return (fileexists);
      
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多