无法在Android 6.0

时间:2017-03-20 02:31:05

标签: android permissions android-external-storage

我的设备是Android 6.0.1操作系统,但无法将文件写入外部SD卡,从日志中看,没有权限,但我有权申请成功,并且知道AndroidManifest.xml中的权限文件;

我使用" adb shell dumpsys包packagename"命令,读写权限都返回true; 然后我看了一下Settings->应用 - >我的应用 - >已授予权限,读写权限;

我必须使用外置SD卡

有没有人遇到过这个问题,我觉得这很奇怪

private void requestPermiss() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission_group.STORAGE) != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
            Toast.makeText(this, "We need to read file from sdcard", Toast.LENGTH_SHORT).show();
            ActivityCompat.requestPermissions(this, new String[]{
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
            }, 0);
        }

    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(requestCode == 0){
        if(grantResults[0] == PackageManager.PERMISSION_GRANTED
                && grantResults[1] == PackageManager.PERMISSION_GRANTED){
            writeFile();
        }
    }
}

private void writeFile(){
    new Thread(new Runnable() {
        @Override
        public void run() {
            String sdDir = getPath_For23(MainActivity.this, 0);
            File file = new File(sdDir + "/test.txt");
            if(!file.exists()){
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
}

private static String getPath_For23(Context context, int flag) {
    try {
        StorageManager sManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
        Class class_StorageManager = StorageManager.class;
        Method method_getVolumes = class_StorageManager.getMethod("getVolumes");

        Class<?> class_VolumeInfo = Class.forName("android.os.storage.VolumeInfo");
        Method method_getPath = class_VolumeInfo.getMethod("getPath");
        Method method_getDisk = class_VolumeInfo.getMethod("getDisk");

        Class<?> class_DiskInfo = Class.forName("android.os.storage.DiskInfo");
        Method method_isSd = class_DiskInfo.getMethod("isSd");
        Method method_isUsb = class_DiskInfo.getMethod("isUsb");

        List<Object> volumes = (List<Object>) method_getVolumes.invoke(sManager);
        for (Object volumeInfo : volumes) {
            File file = (File) method_getPath.invoke(volumeInfo);
            if (file != null) {
                Object diskInfo = method_getDisk.invoke(volumeInfo);
                if (diskInfo != null) {
                    boolean isSd = (boolean) method_isSd.invoke(diskInfo);
                    boolean isUsb = (boolean) method_isUsb.invoke(diskInfo);
                    switch (flag){
                        case 0:
                            if (isSd) {
                                return  file.getAbsolutePath();
                            }
                            break;
                        case 1:
                            if (isUsb) {
                                return file.getAbsolutePath();
                            }
                            break;
                    }
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
 }

错误日志:

  

W / System.err:java.io.IOException:open failed:EACCES(Permission   拒绝)

     

W / System.err:at java.io.File.createNewFile(File.java:939)

     

W / System.err:at   com.example.user.test60.MainActivity $ 1.run(MainActivity.java:70)

     

W / System.err:at java.lang.Thread.run(Thread.java:818)

     

W / System.err:引起:android.system.ErrnoException:open failed:   EACCES(许可被拒绝)

     

W / System.err:at libcore.io.Posix.open(Native Method)

     

W / System.err:at   libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)

     

W / System.err:在java.io.File.createNewFile(File.java:932)

     

W / System.err:... 2更多

4 个答案:

答案 0 :(得分:0)

试试这个

String imgLocation = Environment.getExternalStorageDirectory().toString() + "/FolderName/", fileName;
                FileOutputStream fOut = null;
                Date date = new Date();
                File dir = new File(imgLocation);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                fileName = "img" + date.getTime() + ".jpg";
                file = new File(dir, fileName);
                try {
                    Bitmap imageBitmap = bm;
                    FileOutputStream out = new FileOutputStream(file);
                    imageBitmap.compress(Bitmap.CompressFormat.JPEG, 85, out);
                    out.flush();
                    out.close();
                   } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

答案 1 :(得分:0)

抬头,getExternalFilesDirectory()!= getExternalFilesDirs()

我很确定getExternalFilesDirs(String)可以完成这项工作。检查https://developer.android.com/reference/android/os/Environment.html

他们说:

  

在具有多个共享/外部存储目录的设备中,这个   directory表示用户将与之交互的主存储   用。可以访问二级存储   throughgetExternalFilesDirs(字符串),getExternalCacheDirs(),   和getExternalMediaDirs()

答案 2 :(得分:0)

现代Android版本(如6.0)上的SD卡是只读的。

您的应用只能在其上编写特定目录。

查看getExternalFilesDirs()为该路径返回的第二项。

答案 3 :(得分:0)

尝试将此添加到您的清单文件中:

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

这将获得所需的权限。