首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >java.io.FileNotFoundException:打开失败:安卓出现ENOENT错误

java.io.FileNotFoundException:打开失败:安卓出现ENOENT错误
EN

Stack Overflow用户
提问于 2020-05-10 20:00:47
回答 1查看 1.5K关注 0票数 1

我正在尝试从照片中提取图像并获取意图数据的文件,将文件保存在内存中,并使用该文件加载到图像视图中。

但我得到的错误如下:

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

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

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

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

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

以下是我的代码:

代码语言:javascript
运行
复制
<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" />

正在检查运行时权限:

代码语言:javascript
运行
复制
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();
        }
    }

检查是否有权限:

代码语言:javascript
运行
复制
  if (!checkPermission()) {
                    selectImageFromGallery();
                } else {
                    if (checkPermission()) {
                        requestPermissionAndContinue();
                    } else {
                        selectImageFromGallery();
                    }
                }

开场意图:

代码语言:javascript
运行
复制
  public void selectImageFromGallery()
    {
        Intent pickPhoto = new Intent(Intent.ACTION_PICK,
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(pickPhoto , 2);

    }

获取结果的意图数据:

代码语言:javascript
运行
复制
 @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();
                        }
                    }

                }
            }
        }
    }

保存和获取文件

代码语言:javascript
运行
复制
  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文件描述符,但没有工作为什么我得到这个错误?是否只有29级或以下的空气污染指数?有什么解决方案可以让它在所有设备上运行?

EN

回答 1

Stack Overflow用户

发布于 2021-04-20 15:13:44

我添加了这个权限,它就起作用了。

代码语言:javascript
运行
复制
<uses-permission
        enter code hereandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
        tools:ignore="ProtectedPermissions" />
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61711622

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档