Как я могу позволить пользователю загружать файлы во внутреннюю память?
Я пишу небольшое приложение, которое читает файлы, которые необходимо регулярно записывать в хранилище на устройстве из источника, внешнего для устройства, будь то 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
Исправления и предложения приветствуются!!!