Как читать / писать в файл, к которому может получить доступ пользователь, не являющийся root? - PullRequest
1 голос
/ 13 марта 2020

Я хотел бы записать в файл, к которому я могу получить доступ из файловой системы, не будучи root.

Это моя попытка:

FileOutputStream fos = null;
final String FILE_NAME = "test.txt";

fos = openFileOutput(FILE_NAME, MODE_PRIVATE);
fos.write("test".getBytes());

// Display path of file written to
Toast.makeText(this, "Saved to" + getFilesDir() + "/" + FILE_NAME, Toast.LENGTH_LONG).show();

Который пишет в

/data/user/0/com.example.PROJECT_NAME/files/test.txt

, который недоступен без root.

Было бы хорошо, если бы была возможность указать другой, абсолютный путь, к которому я знаю, что я могу получить доступ, например, /data/data/....

Мое устройство - Google Pixel C, к сожалению, не имеющее слота для внешней SD-карты для записи.

1 Ответ

1 голос
/ 17 марта 2020

После того как я выяснил, что возможности доступа к внешнему хранилищу сильно различаются в разных android версиях, я выбрал go с Storage Access Framework (SAF). SAF - это API (начиная с уровня API 19), который предлагает пользователю пользовательский интерфейс для просмотра файлов.

Используя Intent, появляется пользовательский интерфейс, который позволяет пользователю создать файл или выбрать существующий:

private static final int CREATE_REQUEST_CODE = 40;
private Uri mFileLocation = null;

Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);

intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("text/plain"); // specify file type
intent.putExtra(Intent.EXTRA_TITLE, "newfile.txt"); // default name for file

startActivityForResult(intent, CREATE_REQUEST_CODE);

После выбора пользователем файла вызывается onActivityResult(...). Теперь можно получить URI файла, вызвав resultData.getData ();

public void onActivityResult(int requestCode, int resultCode, Intent resultData) {

    if (resultCode == Activity.RESULT_OK)
    {
        if (requestCode == CREATE_REQUEST_CODE)
        {
            if (resultData != null) {
                mFileLocation = resultData.getData();
            }
        } 
    }
}

Теперь используйте этот URI для записи в файл:

private void writeFileContent(Uri uri, String contentToWrite)
{
    try
    {
        ParcelFileDescriptor pfd = this.getContentResolver().openFileDescriptor(uri, "w"); // or 'wa' to append

        FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
        fileOutputStream.write(contentToWrite.getBytes());

        fileOutputStream.close();
        pfd.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
...