Как я могу позволить пользователю загружать файлы во внутреннюю память?

Я пишу небольшое приложение, которое читает файлы, которые необходимо регулярно записывать в хранилище на устройстве из источника, внешнего для устройства, будь то USB, Bluetooth, Airdroid и т.д. Из того, что я читал, ничего подобного может записываться во внутреннее хранилище. Я хотел бы управлять файлами во внутреннем хранилище для обеспечения конфиденциальности.

Мое первое решение - это действие, которое позволяет пользователю записывать файлы на внешнее хранилище, а затем нажать кнопку, чтобы перенести их на внутреннее хранилище. Если это не произойдет через n минут, файлы на внешнем хранилище будут уничтожены. Но с тех пор я узнал, что getExternalStorageDirectory довольно бесполезен, потому что устройства эмулируют внешнее хранилище на внутреннем хранилище, а Android не может знать, как и как это делается.

Тем не менее мне было интересно, не было ли какой-либо встроенной активности, которая позволяет пользователям загружать или загружать файлы непосредственно из внутреннего хранилища, но без свободного доступа ко всей файловой структуре внутреннего хранилища, например, они имеют внутреннее хранилище.

В крайнем случае, возможно, мое приложение может получать файлы через TCP-соединение и записывать их во внутреннее хранилище. Это беспорядочно, но так пытается найти SD-карту. См. Вопрос Найти местоположение внешней SD-карты.

NEW: Цель этого упражнения - найти все CSV файлы в каталоге на SD-карте, позволить пользователю выбрать один, обработать его и записать выходной файл на SD-карту, Пользователь вводит значение "Вес", которое будет использоваться в вычислениях для обработки файла.

Но, так как Android настолько ненадежен в предоставлении местоположения действительно внешнего хранилища, то есть на SD-карте, я хочу попробовать хранить файлы во внутреннем хранилище, где Android выглядит более честным и надежным в отношении местоположения этого хранения.

Ответ 1

TL;DR: getExternalStorageDirectory() и getExternalFilesDirs()[0] (API 19+) должны возвращать " первичное" место хранения, т.е. внутреннее хранилище.

EDIT: если вы просто хотите написать eMMC и не заботитесь о том, чтобы он был закрытым, просто используйте getFilesDir() и его гарантированное письмо написано eMMC. > .


Объяснение

Чтобы избежать неясности и для удобства, я буду использовать следующие термины

  • PrivateStorage: личное хранилище приложений во внутренней памяти - /data/data/package name
  • eMMC: внутренняя память телефона
  • SD: расширяемое по телефону хранилище (съемное)

Если я правильно понял ваш вопрос, вы не хотите писать в PrivateStorage, который НЕ разрешил бы другим приложениям получать доступ к этим данным. Таким образом, задача состоит в том, чтобы написать eMMC и быть более конкретным, общедоступным eMMC, а не в частном пространстве приложения eMMCs.

Согласно Android Docs (API 1),

Environment.getExternalStorageDirectory() возвращает основной каталог внешней памяти. Этот каталог в настоящее время недоступен, если он был установлен пользователем на своем компьютере, был удален с устройства или возникла какая-то другая проблема. Вы можете определить его текущее состояние с помощью getExternalStorageState().

И согласно API 19 docs,

Теперь вы можете читать и записывать файлы, зависящие от приложения, на вторичных внешних носителях, например, когда устройство предоставляет как эмулированное хранилище, так и SD-карту. Новый метод getExternalFilesDirs() работает так же, как и существующий метод getExternalFilesDir(), за исключением того, что возвращает массив объектов File.The первая запись в возвращаемом массиве файлов считается устройством "primary" внешнее хранилище, которое совпадает с файлом, возвращаемым существующими методами, такими как getExternalFilesDir().

Подводя итоги, как getExternalStorageDirectory(), так и getExternalFilesDirs()[0] должны возвращать " первичное" место хранения eMMC. однако на практике вы можете заметить, что то, что оно вернуло , может не обязательно быть eMMC, для нескольких телефонов (KarbonnTitiniumS2, XoloX3000 и многих других телефонов)

Вот несколько снимков для второго предложения: этот телефон TitaniumS2 работал 4.2, поэтому я не мог использовать getExternalFilesDirs()

введите описание изображения здесь введите описание изображения здесь

Вы также можете заметить, что по той же причине ES Explorer имеет неверно идентифицировал /sdcard0 как внутреннее хранилище (eMMC) и /sdcard1 в качестве внешнего хранилища ( SD) в старых и новых версиях и действительно продолжают сообщать пользователям, что sdcard0 как внутреннее хранилище.

Кроме того, был добавлен issue для поиска хранилища non-primary (SD).

Кажется, нет никакой функции API для поиска внешних устройств хранения non-primary, и Google не намерен исправлять ситуацию, оставляя приложения использовать хакерские обходные пути, такие как синтаксический анализ всех смонтированных в данный момент файловых систем. Это довольно ужасно для операционной системы текущего поколения, чтобы не поддерживать что-то как основное, как доступ к файлам на вставленной USB-карте.

Ответ 2

Надеюсь, что эта помощь...

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

Исправьте меня, если я ошибаюсь...

вот как вы можете попытаться записать файл на ваш путь к приложению... my one is /data/data/com.test.internalstorage/files

try {
    File filesDir = getApplicationContext().getFilesDir();
    Log.d(TAG, "  Files -> 1 context.getFilesDir()-=> " + filesDir);
    Log.d(TAG, "  Files -> 1 context.getFilesDir().getName-=> " + filesDir.get-name());
    Log.d(TAG, "  Files -> 1 context.getFilesDir().getAbsolutePath-=> " + filesDir.getAbsolutePath());
    Log.d(TAG, "  Files -> 1 context.getFilesDir().getCanonicalPath-=> " + filesDir.getCanonicalPath());
    Log.d(TAG, "  Files -> 1 context.getFilesDir().getPath-=> " + filesDir.getPath());
    String[] lst = getApplicationContext().getFilesDir().list();
    for (int i=0; i< lst.length; i++){
        Log.d(TAG, "  Files -> 1 context.getFilesDir()list("+i+")-=> " + lst[i]);
    }
    String FILENAME = "hello_file5";
    String string = "hello world!";

    FileOutputStream fos = null;

    fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
    fos.write(string.getBytes());
    fos.close();


    Log.d(TAG, "  Files ");"
    File nw_filesDir = getApplicationContext().getFilesDir();
    Log.d(TAG, "  Files -> 2 context.getFilesDir()-=> " + nw_filesDir);
    String[] nw_lst = getApplicationContext().getFilesDir().list();
    for (int i=0; i< nw_lst.length; i++){
        Log.d(TAG, "  Files -> 2 context.getFilesDir()list("+i+")-=>  " + nw_lst[i] +
                " -> " + new File(nw_filesDir,nw_lst[i]).getParentFile());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

вывод

D/_TAG_:   Files -> 1 context.getFilesDir()-=> /data/data/com.test.internalstorage/files
D/_TAG_:   Files -> 1 context.getFilesDir().getName-=> files
D/_TAG_:   Files -> 1 context.getFilesDir().getAbsolutePath-=> /data/data/com.test.internalstorage/files
D/_TAG_:   Files -> 1 context.getFilesDir().getCanonicalPath-=> /data/data/com.test.internalstorage/files
D/_TAG_:   Files -> 1 context.getFilesDir().getPath-=> /data/data/com.test.internalstorage/files
D/_TAG_:   Files -> 1 context.getFilesDir()list(0)-=> hello_file
D/_TAG_:   Files -> 1 context.getFilesDir()list(1)-=> hello_file2
D/_TAG_:   Files -> 1 context.getFilesDir()list(2)-=> hello_file3
D/_TAG_:   Files -> 1 context.getFilesDir()list(3)-=> hello_file4
D/_TAG_:   Files 
D/_TAG_:   Files -> 2 context.getFilesDir()-=> /data/data/com.test.internalstorage/files
D/_TAG_:   Files -> 2 context.getFilesDir()list(0)-=>  hello_file -> /data/data/com.test.internalstorage/files
D/_TAG_:   Files -> 2 context.getFilesDir()list(1)-=>  hello_file2 -> /data/data/com.test.internalstorage/files
D/_TAG_:   Files -> 2 context.getFilesDir()list(2)-=>  hello_file3 -> /data/data/com.test.internalstorage/files
D/_TAG_:   Files -> 2 context.getFilesDir()list(3)-=>  hello_file4 -> /data/data/com.test.internalstorage/files
D/_TAG_:   Files -> 2 context.getFilesDir()list(4)-=>  hello_file5 -> /data/data/com.test.internalstorage/files

Исправления и предложения приветствуются!!!