[英]Writing to the SDCard
我已經嘗試了很長時間,以弄清楚如何在三星Galaxy上寫入SD卡。 我嘗試了許多方法,但它似乎仍然無法正常工作。 我已經遍歷了此代碼,並且似乎可以執行(無論是否在手機中插入了SDCard)。 問題是我永遠找不到它應該寫的文件。 有人可以幫忙嗎?
if (isExternalStorageWritable()) {
try {
File myFile = new File("/sdcard/WorkoutData.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
for (WorkoutData iterator: workouts) {
myOutWriter.append(iterator.toString());
Log.d(TAG, iterator.toString());
}
myOutWriter.close();
fOut.close();
Toast.makeText(getBaseContext(),
"Done writing SD 'WorkoutData.txt'",
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
我的三星Galaxy S4遇到相同的問題。 我已經檢查過,外部存儲可用且可寫。 但是無法創建文件夾或文件。
然后,我嘗試使用下面的代碼創建/刪除文件夾。 沒關系。 但是無法創建文件,EACCES(權限被拒絕)發生了。 希望這段代碼可以為您提供幫助。
package com.example.truongphuquoc;
public class MediaFile {
private final File file;
private final ContentResolver contentResolver;
private final Uri filesUri;
private final Uri imagesUri;
public MediaFile(ContentResolver contentResolver, File file) {
this.file = file;
this.contentResolver = contentResolver;
filesUri = MediaStore.Files.getContentUri("external");
imagesUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
/**
* Deletes the file. Returns true if the file has been successfully deleted or otherwise does not exist. This operation is not
* recursive.
*/
public boolean delete()
throws IOException {
if (!file.exists()) {
return true;
}
boolean directory = file.isDirectory();
if (directory) {
// Verify directory does not contain any files/directories within it.
String[] files = file.list();
if (files != null && files.length > 0) {
return false;
}
}
String where = MediaStore.MediaColumns.DATA + "=?";
String[] selectionArgs = new String[] { file.getAbsolutePath() };
// Delete the entry from the media database. This will actually delete media files (images, audio, and video).
contentResolver.delete(filesUri, where, selectionArgs);
if (file.exists()) {
// If the file is not a media file, create a new entry suggesting that this location is an image, even
// though it is not.
ContentValues values = new ContentValues();
values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
contentResolver.insert(imagesUri, values);
// Delete the created entry, such that content provider will delete the file.
contentResolver.delete(filesUri, where, selectionArgs);
}
return !file.exists();
}
public File getFile() {
return file;
}
/**
* Creates a new directory. Returns true if the directory was successfully created or exists.
*/
public boolean mkdir()
throws IOException {
if (file.exists()) {
return file.isDirectory();
}
ContentValues values;
Uri uri;
// Create a media database entry for the directory. This step will not actually cause the directory to be created.
values = new ContentValues();
values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
contentResolver.insert(filesUri, values);
// Create an entry for a temporary image file within the created directory.
// This step actually causes the creation of the directory.
values = new ContentValues();
values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath() + "/temp.jpg");
uri = contentResolver.insert(imagesUri, values);
// Delete the temporary entry.
contentResolver.delete(uri, null, null);
return file.exists();
}
public boolean mkFile(){
if (file.exists() || file.isDirectory()) {
return false;
}
ContentValues values;
// Create a media database entry for the directory. This step will not actually cause the directory to be created.
values = new ContentValues();
values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
contentResolver.insert(filesUri, values);
return file.exists();
}
/**
* Returns an OutputStream to write to the file. The file will be truncated immediately.
*/
public OutputStream write()
throws IOException {
if (file.exists() && file.isDirectory()) {
throw new IOException("File exists and is a directory.");
}
// Delete any existing entry from the media database.
// This may also delete the file (for media types), but that is irrelevant as it will be truncated momentarily in any case.
String where = MediaStore.MediaColumns.DATA + "=?";
String[] selectionArgs = new String[] { file.getAbsolutePath() };
contentResolver.delete(filesUri, where, selectionArgs);
ContentValues values = new ContentValues();
values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
Uri uri = contentResolver.insert(filesUri, values);
if (uri == null) {
// Should not occur.
throw new IOException("Internal error.");
}
return contentResolver.openOutputStream(uri);
}
}
也許是由於“外部”存儲隔離所致...
在AndroidManifest.xml
,包括:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
例如,在MyApp.java
某個MyApp.java
,您要提取其日志並將其保存到默認外部sd卡上的“ file.log”中:
String PACKAGE_NAME = MyApp.class.getPackage().getName();
String KEY_DIRECTORY_SELECTED = PACKAGE_NAME + ".DIRECTORY_SELECTED";
SharedPreference preferences = getSharedPreferences(PACKAGE_NAME, Context.MODE_PRIVATE);
private String extractLogToFile()
{
final String defaultFolder = preferences.getString(KEY_DIRECTORY_SELECTED,
Environment.getExternalStorageDirectory().toString()) +
System.getProperty("file.separator");
final String FILENAME = defaultFolder + "file.log";
PackageManager manager = this.getPackageManager();
PackageInfo info = null;
try {
info = manager.getPackageInfo (this.getPackageName(), 0);
} catch (NameNotFoundException e2) {
}
String model = Build.MODEL;
if (!model.startsWith(Build.MANUFACTURER))
model = Build.MANUFACTURER + " " + model;
// Make file name - file must be saved to external storage or it wont be readable by
// the email app.
//String path = defaultFolder;
String fullName = FILENAME;
// Extract to file.
File file = new File (fullName);
InputStreamReader reader = null;
FileWriter writer = null;
try
{
// For Android 4.0 and earlier, you will get all app's log output, so filter it to
// mostly limit it to your app's output. In later versions, the filtering isn't needed.
String cmd = (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) ?
"logcat -d -v time MyApp:v dalvikvm:v System.err:v *:s" :
"logcat -d -v time";
// get input stream
Process process = Runtime.getRuntime().exec(cmd);
reader = new InputStreamReader (process.getInputStream());
// write output stream
writer = new FileWriter (file);
writer.write ("Android version: " + Build.VERSION.SDK_INT + "\n");
writer.write ("Device: " + model + " (S/N: "+ Tools.getDeviceSerialNumber()+")" + "\n");
writer.write ("App version: " + (info == null ? "(null)" : info.versionName) + "\n");
char[] buffer = new char[10000];
do
{
int n = reader.read (buffer, 0, buffer.length);
if (n == -1)
break;
writer.write (buffer, 0, n);
} while (true);
reader.close();
writer.close();
}
catch (IOException e)
{
if (writer != null)
try {
writer.close();
} catch (IOException e1) {
}
if (reader != null)
try {
reader.close();
} catch (IOException e1) {
}
// You might want to write a failure message to the log here.
return null;
}
return fullName;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.