当我尝试在 Android 5.1 中将数据写入 SD 卡时,出现打开失败:EACCES(权限被拒绝)错误,为什么?

问题描述 投票:0回答:5

我需要保存一些数据到SD卡,我已经添加了权限 到AndroidManifest.xml文件中,在Android 4.12手机上测试时可以得到正确的结果。

但是我在 Android 5.1 手机上测试时出现 open failed: EACCES (Permission Denied) 错误,为什么?

顺便说一句,我已经阅读了文章 Android 6.0 打开失败:EACCES(权限被拒绝)Android 上的异常“打开失败:EACCES(权限被拒绝)”,但现在我的手机是三星 Android 5.1

代码

 private void ActionUploadFiles(Map<String, String> files,IHTTPSession session,String uploadFolder){

        try{
            Set<String> keys = files.keySet();

            for (String key:keys) {
                String location = files.get(key);
                File source = new File(location);

                String filename= session.getParms().get(key);
                filename=FilenameUtils.getName(filename);

                File target = new File(uploadFolder,filename);

                FileUtils.copyFile(source,target);
            }
        }
        catch (Exception e) {
            Utility.LogError("Upload Error: "+ e.getMessage());
        }
    }

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.dodata.wifi">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>

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

    <uses-permission android:name="com.android.vending.BILLING" />

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {      
        multiDexEnabled true

        applicationId "info.dodata.wifi"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 4
        versionName "1.04"
        archivesBaseName = "WiFiFileTransfer-V" + versionName
    }

    productFlavors {
        free {
            applicationId "info.dodata.wifi"
        }

        pro {
            applicationId "info.dodata.wifi.pro"
        }
    }


    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField "boolean", "IsDebugMode", "false"
        }

        debug {
            buildConfigField "boolean", "IsDebugMode", "true"
        }
    }

}
android
5个回答
3
投票

您缺少从 Android Lollipop 引入的运行时权限。您可以做的就是启用权限。要执行此操作,请转到

Settings -> Apps -> YOUR_APP -> Permissions

并启用权限然后测试。

要添加运行时权限,可以在里面询问

onCreate()

String[] permission ={Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};

if(ContextCompat.checkSelfPermission(EditDisplayPicture.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
 && ContextCompat.checkSelfPermission(EditDisplayPicture.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        ActivityCompat.requestPermissions(YourActivity.this, permission, 1);
    }
} else proceedFurther();

然后像这样监听许可接受或拒绝,

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        proceedFurther();
    } else {
        Toast.makeText(YourActivity.this, "You need to give permission in order to proceed further.", Toast.LENGTH_SHORT).show();
    }
}

0
投票

因为您有

targetSdkVersion 23
这就是为什么您会收到安全异常,您必须降级到
targetSdkVersion 22
或添加运行时权限。请检查此链接https://developer.android.com/training/permissions/requesting.html

更新:打开失败:EACCES(权限被拒绝)


0
投票

从 Kitkat 开始,Android 限制第三方应用程序对 SDCARD 的写入访问。他们引入了“存储访问框架”来执行操作。要写入 SDCard 上的文件,您需要使用这些 API。 对于某些运行 Lollipop 的设备,您可以使用这些 api 获得对文件的写入权限。由于我自己没有使用过该 api,因此无法向您提供代码片段。但这个链接一定能帮助你解决问题。

您可以查看

Es Explorer

以了解他们如何处理此场景的流程。


0
投票

通常此错误是由于权限被拒绝而导致的,因此如果您使用物理设备作为模拟器来运行应用程序,只需转到设备中的设置,然后转到应用程序管理器。找到您的应用程序并转到权限,然后允许您的应用程序的权限存储并重试。


0
投票

下面是我使用的代码:

View view = inflater.inflate(R.layout.feedback_dialog, container, false); File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "contact_us.txt"); if (file.exists()) { StringBuilder text = new StringBuilder(); try { BufferedReader br = new BufferedReader(new FileReader(file)); String line; while ((line = br.readLine()) != null) { text.append(line); text.append('\n'); } br.close(); TextView tv = view.findViewById(R.id.contact_us_text); tv.setText(text.toString()); } catch (IOException e) { // Handle Exception } } else { // Handle if file doesn't exist }

注意:按照以下步骤操作后无需更改代码

按照以下步骤后,我的应用程序开始从 SDCard 文件夹读取文件。

打开设置
  • 转到隐私权
  • 选择权限管理器
  • 选择文件
  • 选择您的应用程序(位于“不允许”部分下)
  • 点击“允许”以使应用程序访问文件。
  • 运行应用程序,
© www.soinside.com 2019 - 2024. All rights reserved.