当前位置: 首页 > 知识库问答 >
问题:

如何正确使用存储访问框架(SAF)和URI编辑共享存储中的文本文件?

梅修贤
2023-03-14

(编辑)由@blackapps回答:将“w”改为“wt”。而且奏效了!

//-----------------------------------//

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //--call this only once
//        createFile(MediaStore.Downloads.INTERNAL_CONTENT_URI);
    }

    private String todayFood = "pineapple";//change here to apple
    private static final int CREATE_FILE = 1;
    private static final int OPEN_FILE = 2;

    private void createFile(Uri pickerInitialUri) {
        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("text/plain");
        intent.putExtra(Intent.EXTRA_TITLE, "foodFile");
        intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri);

        startActivityForResult(intent, CREATE_FILE);
    }

    public void onOpenFileBtn(View v){//button click event
        openFile(MediaStore.Downloads.INTERNAL_CONTENT_URI);
    }

    private void openFile(Uri pickerInitialUri) {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("text/plain");
        intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri);

        startActivityForResult(intent, OPEN_FILE);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode,
                                 Intent resultData) {
        super.onActivityResult(requestCode, resultCode, resultData);
        if (requestCode == OPEN_FILE && resultCode == Activity.RESULT_OK) {
            Uri uri = null;
            if (resultData != null) {
                uri = resultData.getData();
                outputToFile(uri);
            }
        } else if (requestCode == CREATE_FILE && resultCode == Activity.RESULT_OK) {
            System.out.println("create successful");
        }
    }

    public void outputToFile(Uri fileUri) {
        try {
            ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(fileUri, "w");
            FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
            fileOutputStream.write(todayFood.getBytes());
            fileOutputStream.close();
            pfd.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

android:requestLegacyExternalStorage="true"

我已经尝试使用直接路径,它工作正确。我认为原因是它创建了一个新的文件来替换原来的文件。然而,我只是不想使用直接路径。

public void outputToFile(Uri fileUri) {
    File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    File f = new File(dir.getPath(), "foodFile.txt");

    try {
        FileOutputStream outputStream = new FileOutputStream(f);
        outputStream.write(todayFood.getBytes());
        outputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我已经尝试了PrintWriter清除内容,但它也需要直接路径创建文件,然后放入PrintWriter。

public void outputToFile(Uri fileUri) {
    File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    try {
        File f = new File(dir.getPath(), "foodFile.txt");
        PrintWriter writer = new PrintWriter(f);
        writer.print("");
        writer.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我已经尝试过使用OutputStream创建PrintWriter,但它不起作用。

public void outputToFile(Uri fileUri) {
    try {
        ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(fileUri, "w");
        OutputStream outputStream = new FileOutputStream(pfd.getFileDescriptor());
        PrintWriter writer = new PrintWriter(outputStream);
        writer.print("");
        writer.write("apple");
        writer.close();
        pfd.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

我也试着在其他文件夹中创建和编辑文本文件,比如文档文件夹,但它也不起作用。

我已经尝试请求运行时权限,但它有另一个问题我现在无法解决。

共有1个答案

屈博
2023-03-14

请尝试以下代码。

public void outputToFile(String text) {
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
try {
   File logFile = new File(dir.getPath(), "abc.txt");
   BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true)); 
   buf.append(text);
   buf.newLine();
   buf.close();
} catch (Exception e) {
    e.printStackTrace();
}
}
 类似资料:
  • 让我分享到目前为止我所学到的,并提出我的问题。如果希望获取文件夹的Uri并对其进行操作,则应使用和获取访问文件夹的Uri,并为该Uri设置W/R权限。 授予onActivityResult的持久权限: 如果选择设备的主文件夹: 如果使用DocumentFile类获取主文件夹的路径 返回:file:///storage/emulated/0 我的第一个问题是如何使用DocumentFile类获得包含

  • 我正在尝试打开一个现有文件,或者在外部使用SAF创建一个新文件,而用户不需要安装除我的apk之外的任何其他文件。 在我的Android10像素3上,ACTION_OPEN_DOCUMENT_TREE抛出一个异常,指示没有活动来处理这个(我想知道为什么会这样?)。 ACTION_OPEN_DOCUMENT和ACTION_CREATE_DOCUMENT似乎很合适。 但是,如果我: > 使用ACTION

  • 我是Android上存储访问框架的新手。 谢谢

  • 我正在使用android 4.4的存储访问框架并打开文件选择器。 除了从GoogleDrive中选择一个文件外,其他一切都可以正常工作,我只能知道如何将其作为输入流打开,但我希望得到一个java文件对象。 返回的内容uri如下所示:content://com.google.android.apps.docs.storage/document/acc=4;doc=2279 其他问题类似,但没有一个有

  • 我在一个应用程序上工作,我想访问“/存储/仿真/0/Android/媒体/com.whatsapp/WhatsApp/Media/.Statuses”来为我的应用程序获取状态文件夹中的数据。

  • 我有两个组件Display.jsx和DisplayList.jsx。组件协同工作以显示本地存储中的值。问题在于DisplayList.JSX handleEdit()方法切片。 Github项目 我的想法: 我在这个论坛上问如何删除本地存储值,得到了这个答案,没有解释:堆栈溢出问题 它可以工作,但现在我需要做类似的切片来编辑旧的存储值并用新的存储值替换。但是我不知道怎么做。 总结:在方法handl