Android 删除失败:EACCES(权限被拒绝)-从外部SD卡删除文件

Android 删除失败:EACCES(权限被拒绝)-从外部SD卡删除文件,android,storage,android-permissions,android-sdcard,permission-denied,Android,Storage,Android Permissions,Android Sdcard,Permission Denied,我正在尝试从外部/可移动SD卡中删除文件。但我犯了以下错误: remove failed: EACCES (Permission denied) : /storage/987F-099F/SDNumber/Voc_112_1.png 我基本上需要将文件从我的可移动SD卡移动到我的设备存储器。 但我也无法做到这一点 我可以从我的可移动SD卡获取所有文件。 下面是我如何从可移动SD卡获取文件的代码: final String[] columns = {MediaStore.Images.Media

我正在尝试从外部/可移动SD卡中删除文件。但我犯了以下错误:

remove failed: EACCES (Permission denied) : /storage/987F-099F/SDNumber/Voc_112_1.png
我基本上需要将文件从我的可移动SD卡移动到我的设备存储器。 但我也无法做到这一点

我可以从我的可移动SD卡获取所有文件。 下面是我如何从可移动SD卡获取文件的代码:

final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID, MediaStore.Images.Media.DISPLAY_NAME};
        final String orderBy = MediaStore.Images.Media.DISPLAY_NAME;

        Cursor cursor = context.getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null,
                null, orderBy);
因此,当我尝试将文件从SD卡移动到设备外部存储器时,会出现如下错误:

rename failed: EXDEV (Cross-device link) : /storage/987F-099F/SDNumber/Voc_112_1.png
remove failed: EACCES (Permission denied) : /storage/987F-099F/SDNumber/Voc_112_1.png
public static void moveFile(Context context, File srcFile, File destFile) {
        boolean rename = srcFile.renameTo(destFile);
        if (!rename) {
            copyFile(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
            boolean deleted = deleteFile(srcFile.getAbsolutePath());
            if (!deleted) {
                deleted = delete(context, srcFile);
                Log.e("moveFile", "deleted : " + deleted);
            }
        }
    }


public static boolean copyFile(String sourceFilePath, String destFilePath) {
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(sourceFilePath);
        } catch (FileNotFoundException e) {
            throw new RuntimeException("FileNotFoundException occurred. ", e);
        }
        return writeFile(destFilePath, inputStream);
    }


public static boolean deleteFile(String path) {
        if (path == null || path.trim().length() == 0) {
            return true;
        }

        File file = new File(path);
        if (!file.exists()) {
            return true;
        }
        if (file.isFile()) {
            return file.delete();
        }
        if (!file.isDirectory()) {
            return false;
        }
        for (File f : file.listFiles()) {
            if (f.isFile()) {
                f.delete();
            } else if (f.isDirectory()) {
                deleteFile(f.getAbsolutePath());
            }
        }
        return file.delete();
    }
然后,我继续前进,试图复制那个文件。复制文件效果很好。但是,之后我需要删除该文件,但它也不工作,并给出如下错误:

rename failed: EXDEV (Cross-device link) : /storage/987F-099F/SDNumber/Voc_112_1.png
remove failed: EACCES (Permission denied) : /storage/987F-099F/SDNumber/Voc_112_1.png
public static void moveFile(Context context, File srcFile, File destFile) {
        boolean rename = srcFile.renameTo(destFile);
        if (!rename) {
            copyFile(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
            boolean deleted = deleteFile(srcFile.getAbsolutePath());
            if (!deleted) {
                deleted = delete(context, srcFile);
                Log.e("moveFile", "deleted : " + deleted);
            }
        }
    }


public static boolean copyFile(String sourceFilePath, String destFilePath) {
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(sourceFilePath);
        } catch (FileNotFoundException e) {
            throw new RuntimeException("FileNotFoundException occurred. ", e);
        }
        return writeFile(destFilePath, inputStream);
    }


public static boolean deleteFile(String path) {
        if (path == null || path.trim().length() == 0) {
            return true;
        }

        File file = new File(path);
        if (!file.exists()) {
            return true;
        }
        if (file.isFile()) {
            return file.delete();
        }
        if (!file.isDirectory()) {
            return false;
        }
        for (File f : file.listFiles()) {
            if (f.isFile()) {
                f.delete();
            } else if (f.isDirectory()) {
                deleteFile(f.getAbsolutePath());
            }
        }
        return file.delete();
    }
基本上我的整个代码是这样的:

rename failed: EXDEV (Cross-device link) : /storage/987F-099F/SDNumber/Voc_112_1.png
remove failed: EACCES (Permission denied) : /storage/987F-099F/SDNumber/Voc_112_1.png
public static void moveFile(Context context, File srcFile, File destFile) {
        boolean rename = srcFile.renameTo(destFile);
        if (!rename) {
            copyFile(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
            boolean deleted = deleteFile(srcFile.getAbsolutePath());
            if (!deleted) {
                deleted = delete(context, srcFile);
                Log.e("moveFile", "deleted : " + deleted);
            }
        }
    }


public static boolean copyFile(String sourceFilePath, String destFilePath) {
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(sourceFilePath);
        } catch (FileNotFoundException e) {
            throw new RuntimeException("FileNotFoundException occurred. ", e);
        }
        return writeFile(destFilePath, inputStream);
    }


public static boolean deleteFile(String path) {
        if (path == null || path.trim().length() == 0) {
            return true;
        }

        File file = new File(path);
        if (!file.exists()) {
            return true;
        }
        if (file.isFile()) {
            return file.delete();
        }
        if (!file.isDirectory()) {
            return false;
        }
        for (File f : file.listFiles()) {
            if (f.isFile()) {
                f.delete();
            } else if (f.isDirectory()) {
                deleteFile(f.getAbsolutePath());
            }
        }
        return file.delete();
    }
我还尝试使用内容解析程序删除:

public static boolean delete(final Context context, final File file) {
        final String where = MediaStore.MediaColumns.DATA + "=?";
        final String[] selectionArgs = new String[] {
                file.getAbsolutePath()
        };
        final ContentResolver contentResolver = context.getContentResolver();
        final Uri filesUri = MediaStore.Files.getContentUri("external");

        contentResolver.delete(filesUri, where, selectionArgs);

        if (file.exists()) {

            contentResolver.delete(filesUri, where, selectionArgs);
        }
        return !file.exists();
    }
但这些功能都不起作用。那个文件仍然出现在我的图库中

请让我知道我哪里做错了,这里缺少了什么。 我还在检查外部存储器的读写运行时权限

这是我的Manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="pix.tours.pixtours">

    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="com.android.vending.BILLING" />

    <application
        android:name=".GlobalApplication"
        android:allowBackup="true"
        android:hardwareAccelerated="false"
        android:icon="@drawable/logo"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:roundIcon="@drawable/logo"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">


        <activity
            android:name=".activities.MainActivity"
            android:screenOrientation="portrait"
            android:theme="@style/AppTheme.NoActionBar" />

        <activity
            android:name=".activities.SplashActivity"
            android:screenOrientation="portrait"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 </application>

</manifest>


谢谢

您是否在运行时请求存储权限?即使在清单中添加uses权限,仍然需要请求用户在运行时授予权限。以下是代码:

/ Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};

/**
 * Checks if the app has permission to write to device storage
 *
 * If the app does not has permission then the user will be prompted to grant permissions
 *
 * @param activity
 */
public static void verifyStoragePermissions(Activity activity) {
    // Check if we have write permission
    int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        // We don't have permission so prompt the user
        ActivityCompat.requestPermissions(
                activity,
                PERMISSIONS_STORAGE,
                REQUEST_EXTERNAL_STORAGE
        );
    }
}
在此处阅读有关运行时权限请求的更多信息:

重命名失败:EXDEV(跨设备链接):/storage/987F-099F/SDNumber/Voc_112_1.png

自Android 4.4+以来,可移动SD卡是只读的(使用文件方案)


要能够写入,请使用存储访问框架。

显示清单file@krishankTripathi请检查更新的问题。Android是Linux。反过来,这就是Unix。确保你(你的应用程序)对该特定文件具有写入(w)权限。我如何才能将写入权限添加到我的可移动SD卡?
以下是我如何从可移动SD卡获取文件的代码:
该代码永远不会为你提供你提到的路径。是的,。。我正在做同样的事情,谢谢你的回答。你能告诉我更多关于“存储访问框架”的信息吗?我不知道它的用途。