Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:没有向SD卡写入数据的权限_Android - Fatal编程技术网

Android:没有向SD卡写入数据的权限

Android:没有向SD卡写入数据的权限,android,Android,在我的应用程序中,我需要将一些mp4文件下载到存储器中。有一个选项菜单可选择mp4文件的位置(电话存储或SD卡存储)。 我通过reflect android SDK获得手机存储路径和SD卡存储路径,如下图: public class StorageUtils { private static final String TAG = "===StorageUtil==="; public static String getPrimaryStoragePath(Context co

在我的应用程序中,我需要将一些mp4文件下载到存储器中。有一个选项菜单可选择mp4文件的位置(电话存储或SD卡存储)。 我通过reflect android SDK获得手机存储路径和SD卡存储路径,如下图:

public class StorageUtils {

    private static final String TAG = "===StorageUtil===";

    public static String getPrimaryStoragePath(Context context) {
        try {
            StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
            Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths", null);
            String[] paths = (String[]) getVolumePathsMethod.invoke(sm, null);
            // first element in paths[] is primary storage path
            return paths[0];
        } catch (Exception e) {
            Log.e(TAG, "getPrimaryStoragePath() failed", e);
        }
        return null;
    }

    public static String getSecondaryStoragePath(Context context) {
        try {
            StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
            Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths", null);
            String[] paths = (String[]) getVolumePathsMethod.invoke(sm, null);
            // second element in paths[] is secondary storage path
            return paths[1];
        } catch (Exception e) {
            Log.e(TAG, "getSecondaryStoragePath() failed", e);
        }
        return null;
    }

    public static String getStorageState(Context context, String path) {

        try {
            StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
            Method getVolumeStateMethod = StorageManager.class.getMethod("getVolumeState", new Class[]{String.class});
            String state = (String) getVolumeStateMethod.invoke(sm, path);
            return state;
        } catch (Exception e) {
            Log.e(TAG, "getStorageState() failed", e);
        }
        return null;
    }
}
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
和我的测试代码如下:

public class StorageTestActivity extends AppCompatActivity {

    private TextView primaryStoragePath;
    private TextView slaveStoragePath, tvStatus;
    private Button btn1, btn2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_storage_test);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        primaryStoragePath = (TextView) findViewById(R.id.primaryStoragePath);
        slaveStoragePath = (TextView) findViewById(R.id.slaveStoragePath);

        //state: mounted, shared, removed
        final String path1 = StorageUtils.getPrimaryStoragePath(this);
        String state1 = StorageUtils.getStorageState(this, path1);
        StringBuilder sb1 = new StringBuilder().append("path1:").append(path1).append("\n").append("state1=").append(state1);
        primaryStoragePath.setText(sb1.toString());

        final String path2 = StorageUtils.getSecondaryStoragePath(this);
        String state2 = StorageUtils.getStorageState(this, path2);
        StringBuilder sb2 = new StringBuilder().append("path2:").append(path2).append("\n").append("state2=").append(state2);
        slaveStoragePath.setText(sb2.toString());

        btn1 = (Button) findViewById(R.id.btnWriteToPrimaryStorage);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentType = 0;
                writeData(path1);
            }
        });

        btn2 = (Button) findViewById(R.id.btnWriteToSDCard);
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentType = 1;
                writeData(path2);
            }
        });

        tvStatus = (TextView) findViewById(R.id.tvStatus);



    }

    private int currentType = 0;
    private void writeData(final String path) {

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                String state = StorageUtils.getStorageState(StorageTestActivity.this, path);
                if(!"mounted".equals(state)) {
                    Snackbar.make(slaveStoragePath, "state is " + state, Snackbar.LENGTH_LONG).show();
                    return;
                }



                String tmpPath = path+File.separator+"Android/data/com.example.fjz.myapplication/";
                File directory = new File(tmpPath);

                if (!directory.exists()) {
                    Log.e("========", "create directories.");
                    directory.mkdirs();
                }

                File file = new File(tmpPath + "abcdefg.txt");
                if (file.exists()) {
                    file.delete();
                }

                try {
                    file.createNewFile();
                    handler.sendEmptyMessage(currentType);
                } catch (IOException e) {
                    e.printStackTrace();
                    handler.sendEmptyMessage(3);
                }

                Log.e("storage test activity:", file.getAbsolutePath());

            }
        };

        new Thread(runnable).start();
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

            if(msg.what == 0) {
                tvStatus.setText("Write primary success");
            } else if(msg.what == 1) {
                tvStatus.setText("Write SD card success");
            } else {
                tvStatus.setText("Write failed.");
            }
        }
    };
然后出错:

public class StorageTestActivity extends AppCompatActivity {

    private TextView primaryStoragePath;
    private TextView slaveStoragePath, tvStatus;
    private Button btn1, btn2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_storage_test);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        primaryStoragePath = (TextView) findViewById(R.id.primaryStoragePath);
        slaveStoragePath = (TextView) findViewById(R.id.slaveStoragePath);

        //state: mounted, shared, removed
        final String path1 = StorageUtils.getPrimaryStoragePath(this);
        String state1 = StorageUtils.getStorageState(this, path1);
        StringBuilder sb1 = new StringBuilder().append("path1:").append(path1).append("\n").append("state1=").append(state1);
        primaryStoragePath.setText(sb1.toString());

        final String path2 = StorageUtils.getSecondaryStoragePath(this);
        String state2 = StorageUtils.getStorageState(this, path2);
        StringBuilder sb2 = new StringBuilder().append("path2:").append(path2).append("\n").append("state2=").append(state2);
        slaveStoragePath.setText(sb2.toString());

        btn1 = (Button) findViewById(R.id.btnWriteToPrimaryStorage);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentType = 0;
                writeData(path1);
            }
        });

        btn2 = (Button) findViewById(R.id.btnWriteToSDCard);
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                currentType = 1;
                writeData(path2);
            }
        });

        tvStatus = (TextView) findViewById(R.id.tvStatus);



    }

    private int currentType = 0;
    private void writeData(final String path) {

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                String state = StorageUtils.getStorageState(StorageTestActivity.this, path);
                if(!"mounted".equals(state)) {
                    Snackbar.make(slaveStoragePath, "state is " + state, Snackbar.LENGTH_LONG).show();
                    return;
                }



                String tmpPath = path+File.separator+"Android/data/com.example.fjz.myapplication/";
                File directory = new File(tmpPath);

                if (!directory.exists()) {
                    Log.e("========", "create directories.");
                    directory.mkdirs();
                }

                File file = new File(tmpPath + "abcdefg.txt");
                if (file.exists()) {
                    file.delete();
                }

                try {
                    file.createNewFile();
                    handler.sendEmptyMessage(currentType);
                } catch (IOException e) {
                    e.printStackTrace();
                    handler.sendEmptyMessage(3);
                }

                Log.e("storage test activity:", file.getAbsolutePath());

            }
        };

        new Thread(runnable).start();
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

            if(msg.what == 0) {
                tvStatus.setText("Write primary success");
            } else if(msg.what == 1) {
                tvStatus.setText("Write SD card success");
            } else {
                tvStatus.setText("Write failed.");
            }
        }
    };
01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err: java.io.IOException:打开失败:EACCES(权限被拒绝)01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err:
在java.io.File.createNewFile(File.java:978)01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err:at com.example.fjz.demo.StorageTestActivity$4.run(StorageTestActivity.java:108) 01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err: 在java.lang.Thread.run(Thread.java:841)01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err:由以下原因引起: libcore.io.ErrnoException:打开失败:EACCES(权限被拒绝) 01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err: 在libcore.io.Posix.open(本机方法)01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err:at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err:at java.io.File.createNewFile(File.java:971)01-18 16:05:12.819 30125-30601/com.example.myapplication W/System.err:。。。还有两个

在清单文件中,我已声明权限:



非常感谢您的帮助

您需要在AndroidManifest.xml中添加写入权限

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

我声明权限如下:

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

幸运的是,我明白了

1) 我将
sdcard
路径设置为
/storaget/sdcard1
2) 然后我创建路径
/storaget/sdcard1/Android/data/com.example.sdcard.demo

3) 尝试
mkdirs(path)
,然后返回false,因此我没有权限创建
'Android/data/com.example.sdcard.demo'
目录


4)我可以调用
api:getExternalCacheDir
,它可以成功创建此目录。

此问题经常发生,因为权限声明在错误的位置……它需要位于应用程序标记之外……因此,您可以使用此文件sd=Environment.getExternalStorageDirectory()进行检查;Log.e(“CHECK WRITE”,sd.canWrite()+”);" "