簡體   English   中英

寫入SD卡

[英]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;
}

參見https://stackoverflow.com/a/23534713/980521

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM