写入SD卡

时间:2014-10-09 03:08:54

标签: java android file android-sdcard filewriter

我已经花了很长时间才弄清楚如何在我的三星Galaxy上写入SDCard。我尝试过很多方法但它似乎仍然没有用。我已经跟踪了这段代码并且似乎执行了(无论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();
   }
}

2 个答案:

答案 0 :(得分:0)

我的三星Galaxy S4遇到了同样的问题。我已经检查过,外部存储是可用的和可写的。但无法创建文件夹或文件。

然后我尝试使用下面的代码来创建/删除文件夹。没关系。但无法创建文件,EACCES(Permission denied)发生了。希望这段代码可以帮到你。

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);
    }
}

答案 1 :(得分:0)

可能,这是由于“外部”存储隔离......

AndroidManifest.xml中,包括:

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

例如,在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;
}

请参阅https://stackoverflow.com/a/23534713/980521