当前位置: 动力学知识库 > 问答 > 编程问答 >

android - Can't write to SD card

问题描述:

My app allows user to take a picture and I want that picture to be stored in the app's external files directory (getExternalFilesDir(null)). It all works except for the call to renameTo(), this call returns false and I don't know why.

The src file is:

/storage/extSdCard/DCIM/Camera/20140424_154458.jpg

Dest file is:

/storage/emulated/0/Android/data/com.myapp.myapp/files/20140424_154458.jpg

I also have specified the WRITE_EXTERNAL_STORAGE permission.

@Override

public boolean onOptionsItemSelected(MenuItem item)

{

if (item.getItemId() == R.id.action_take_picture)

{

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

startActivityForResult(intent, TAKE_PICTURE_REQUEST_CODE);

return true;

}

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data)

{

if (requestCode == TAKE_PICTURE_REQUEST_CODE && resultCode == RESULT_OK)

{

File dest = new File(

getExternalFilesDir(null),

new SimpleDateFormat("yyyyMMdd_hhmmss", Locale.getDefault()).format(new Date()) + ".jpg");

File src = new File(convertMediaUriToPath(data.getData()));

if (src.renameTo(dest)) // Always returns false

{

mAdapter.add(dest);

mAdapter.notifyDataSetChanged();

}

}

}

private String convertMediaUriToPath(Uri uri)

{

String[] proj = {MediaStore.Images.Media.DATA};

Cursor cursor = getContentResolver().query(uri, proj, null, null, null);

int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

cursor.moveToFirst();

String path = cursor.getString(column_index);

cursor.close();

return path;

}

网友答案:

I have ran into this problem previously - unfortunately, you are not allowed to use renameTo to move files and/or directories between different mount points (for example, internal and external storage). Consider using a different way of moving files, such as the one outlined here:

http://www.mkyong.com/java/how-to-copy-directory-in-java/

public static void copyFolder(File src, File dest) throws IOException{

    if(src.isDirectory()){

        //if directory not exists, create it
        if(!dest.exists()){
           dest.mkdir();
           System.out.println("Directory copied from " 
                          + src + "  to " + dest);
        }

        //list all the directory contents
        String files[] = src.list();

        for (String file : files) {
           //construct the src and dest file structure
           File srcFile = new File(src, file);
           File destFile = new File(dest, file);
           //recursive copy
           copyFolder(srcFile,destFile);
        }

    }else{
        //if file, then copy it
        //Use bytes stream to support all file types
        InputStream in = new FileInputStream(src);
            OutputStream out = new FileOutputStream(dest); 

            byte[] buffer = new byte[1024];

            int length;
            //copy the file content in bytes 
            while ((length = in.read(buffer)) > 0){
               out.write(buffer, 0, length);
            }

            in.close();
            out.close();
            System.out.println("File copied from " + src + " to " + dest);
    }
}
网友答案:

The problem is with the method renameTo, the renameTo doesn't create subdirectories,

Reason being The current File API isn't very well implemented in Java. There is a lot of functionality that would be desirable in a File API that isn't currently present such as move, copy and retrieving file metadata.

I don't think anyone will be able to give you an answer as to why the API is written as is. Probably a poor first draft that went live and couldn't be changed due to backwards compatibility issues.

These issue have been addressed in the Java 7. A entirely new API has been created to deal with files java.nio.file.Files.

To Solve this issue, try to get directory path of destination file e.g /storage/emulated/0/Android/data/com.myapp.myapp/files/20140424_154458.jpg

Destination Directory is /storage/emulated/0/Android/data/com.myapp.myapp/files/

Use mkdirs() , it will create all sub directories for you

网友答案:

If you want to add a file or folder or move application into your SD Card just do the following:

steps:

1) Open your Android application's source code file with a text or programming editor. 2) Browse to the location in the source code where you wish to call the function that writes a file to the device's external storage. 3) Insert this single line of code to check for the SD card:

File sdCard = Environment.getExternalStorageDirectory();

4) Insert these lines of code to set the directory and file name:

File dir = new File (sdcard.getAbsolutePath() + "/folder1/folder2");
dir.mkdirs();
File file = new File(dir, "example_file");

// The mkdirs function will create the directory folder for you, use it only you want to create a new one.

5) Replace "/folder1/folder2" in the above code with the actual path where you intend to save the file. This should be a location in which you normally save your application files. Also, change the "example_file" value to the actual file name you wish to use.

6) Insert the following line of code to output the file to the SD card:

FileOutputStream f = new FileOutputStream(file);
Finally step 7:

Save the file, then compile it and test the application using the Android emulator software or the device.

This will work!!! ;-)

分享给朋友:
您可能感兴趣的文章:
随机阅读: