[英]Can't write to SD card
我的應用程序允許用戶拍照,而我希望該照片存儲在應用程序的外部文件目錄( getExternalFilesDir(null)
)中。 除了對renameTo()
的調用外,所有其他方法均有效,該調用返回false,我不知道為什么。
src文件是:
/storage/extSdCard/DCIM/Camera/20140424_154458.jpg
目標文件是:
/storage/emulated/0/Android/data/com.myapp.myapp/files/20140424_154458.jpg
我還指定了WRITE_EXTERNAL_STORAGE
權限。
@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;
}
之前,我曾遇到過此問題-不幸的是,您不允許使用renameTo
在不同的安裝點(例如內部和外部存儲)之間移動文件和/或目錄。 考慮使用另一種移動文件的方式,例如此處概述的一種方式:
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);
}
}
問題在於方法renameTo
, renameTo
不會創建子目錄,
原因是當前的File API在Java中的實現不是很好。 當前不存在的File API中有許多功能是理想的,例如移動,復制和檢索文件元數據。
我不認為有人會向您提供API為何按原樣編寫的答案。 可能是一份較差的初稿,由於上下游的兼容性問題而無法使用,因此無法更改。
這些問題已在Java 7中解決。創建了一個全新的API以處理文件java.nio.file.Files 。
要解決此問題,請嘗試獲取目標文件的目錄路徑, eg /storage/emulated/0/Android/data/com.myapp.myapp/files/20140424_154458.jpg
目標目錄為/storage/emulated/0/Android/data/com.myapp.myapp/files/
使用mkdirs() ,它將為您創建所有子目錄
如果要添加文件或文件夾或將應用程序移動到SD卡中,請執行以下操作:
腳步:
1)使用文本或程序編輯器打開Android應用程序的源代碼文件。 2)瀏覽到源代碼中您要調用將文件寫入設備外部存儲的函數的位置。 3)插入以下單行代碼以檢查SD卡:
File sdCard = Environment.getExternalStorageDirectory();
4)插入以下代碼行以設置目錄和文件名:
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)將上面代碼中的“ / folder1 / folder2”替換為您要保存文件的實際路徑。 這應該是您通常保存應用程序文件的位置。 同樣,將“ example_file”值更改為您希望使用的實際文件名。
6)插入以下代碼行,以將文件輸出到SD卡:
FileOutputStream f = new FileOutputStream(file);
Finally step 7:
保存文件,然后編譯並使用Android模擬器軟件或設備測試應用程序。
這將工作!!! ;-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.