Работа с файловой системой
Чтение и сохранение файлов
Работа с настройками уровня activity и приложения позволяет сохранить небольшие данные отдельных типов (string, int), но для работы с большими массивами данных, такими как графически файлы, файлы мультимедиа и т.д., нам придется обращаться к файловой системе.
ОС Android построена на основе Linux. Этот факт находит свое отражение в работе с файлами. Так, в путях к файлам в качестве разграничителя в Linux использует слеш «/», а не обратный слеш «\» (как в Windows). А все названия файлов и каталогов являются регистрозависимыми, то есть «data» это не то же самое, что и «Data».
Приложение Android сохраняет свои данные в каталоге /data/data/ / и, как правило, относительно этого каталога будет идти работа.
Для работы с файлами абстрактный класс android.content.Context определяет ряд методов:
boolean deleteFile (String name) : удаляет определенный файл
String[] fileList () : получает все файлы, которые содержатся в подкаталоге /files в каталоге приложения
File getCacheDir() : получает ссылку на подкаталог cache в каталоге приложения
File getDir(String dirName, int mode) : получает ссылку на подкаталог в каталоге приложения, если такого подкаталога нет, то он создается
File getExternalCacheDir() : получает ссылку на папку /cache внешней файловой системы устройства
File getExternalFilesDir(String type) : получает ссылку на каталог /files внешней файловой системы устройства
File getFileStreamPath(String filename) : возвращает абсолютный путь к файлу в файловой системе
FileInputStream openFileInput(String filename) : открывает файл для чтения
FileOutputStream openFileOutput (String name, int mode) : открывает файл для записи
Все файлы, которые создаются и редактируются в приложении, как правило, хранятся в подкаталоге /files в каталоге приложения.
Для непосредственного чтения и записи файлов применяются также стандартные классы Java из пакета java.io.
Итак, применим функционал чтения-записи файлов в приложении. Пусть у нас будет следующая примитивная разметка layout:
Поле EditText предназначено для ввода текста, а TextView — для вывода ранее сохраненного текста. Для сохранения и восстановления текста добавлены две кнопки.
Теперь в коде Activity пропишем обработчики кнопок с сохранением и чтением файла:
При нажатии на кнопку сохранения будет создаваться поток вывода FileOutputStream fos = openFileOutput(FILE_NAME, MODE_PRIVATE)
В данном случае введенный текст будет сохраняться в файл «content.txt». При этом будет использоваться режим MODE_PRIVATE
Система позволяет создавать файлы с двумя разными режимами:
MODE_PRIVATE : файлы могут быть доступны только владельцу приложения (режим по умолчанию)
MODE_APPEND : данные могут быть добавлены в конец файла
Поэтому в данном случае если файл «content.txt» уже существует, то он будет перезаписан. Если же нам надо было дописать файл, тогда надо было бы использовать режим MODE_APPEND:
Для чтения файла применяется поток ввода FileInputStream :
Подробнее про использование потоков ввода-вывода можно прочитать в руководстве по Java: https://metanit.com/java/tutorial/6.3.php
В итоге после нажатия кнопки сохранения весь текст будет сохранен в файле /data/data/название_пакета/files/content.txt
Где физически находится созданный файл? Чтобы увидеть его на подключенном устройстве перейдем в Android Stud в меню к пункту View -> Tool Windows -> Device File Explorer
После этого откроектся окно Device File Explorer для просмотра файловой системы устройства. И в папке data/data/[название_пакета_приложения]/files мы сможем найти сохраненный файл.
Источник
Полный список
— работаем с файлами
Работа с файлами в Android не сильно отличается от таковой в Java. В этом уроке рассмотрим, как записать/прочесть файл во внутреннюю память и на SD-карту.
Project name: P0751_Files
Build Target: Android 2.3.3
Application name: Files
Package name: ru.startandroid.develop.p0751files
Create Activity: MainActivity
Рисуем экран main.xml:
4 кнопки, смысл которых понятен по тексту на них.
В onclick обрабатываем нажатия 4-х кнопок и вызываем соответствующие методы.
writeFile – запись файла во внутреннюю память. Используется метод openFileOutput, который на вход берет имя файла и режим записи: MODE_PRIVATE – файл доступен только этому приложению, MODE_WORLD_READABLE – файл доступен для чтения всем, MODE_WORLD_WRITEABLE — файл доступен для записи всем, MODE_APPEND – файл будет дописан, а не начат заново.
readFile – чтение файла из внутренней памяти. Используем метод openFileInput, принимающий на вход имя файла. Здесь и в методе записи внутреннего файла вы можете задать только имя файла, а каталог для ваших файлов вам уже выделен.
writeFileSD – запись файла на SD. Используем метод getExternalStorageState для получения состояния SD-карты. Здесь можно посмотреть какие бывают состояния. Нам нужно MEDIA_MOUNTED – когда SD-карта вставлена и готова к работе. Далее мы получаем путь к SD-карте (метод getExternalStorageDirectory), добавляем свой каталог и имя файла, создаем каталог и пишем данные в файл.
readFileSD – чтение файла с SD. Все аналогично предыдущему методу, только файл не пишем, а читаем.
Осталось в манифест добавить разрешение на работу с файлами на SD — android.permission.WRITE_EXTERNAL_STORAGE.
Все сохраним и запустим. Видим экран с 4-мя кнопками:
Внутренняя память
Жмем кнопку Записать файл. Видим в логе:
Проверим. Идем в File Explorer (Window > Show View > Other > Android > File Explorer) и открываем там папку data/data/ru.startandroid.develop.p0751files/files и видим там наш файл file.
Возвращаемся в эмулятор. Жмем Прочесть файл и в логе видим:
Это тот текст, который мы записывали в файл.
SD карта
Теперь жмем Записать файл на SD.
Файл записан на SD: /mnt/sdcard/MyFiles/fileSD
Проверяем. Идем в FileExplorer и открываем там папку mnt/sdcard/MyFiles/ а в ней файл fileSD.
Возвращаемся в эмулятор и жмем кнопку Прочесть файл с SD. В логе видим:
Содержимое файла на SD
Этот текст мы и записывали.
mnt/sdcard — обычно этот путь ведет к содержимому SD-карты. Возможно у вас он будет другой.
В общем, при работе с файлами на SD вы используете стандартные java механизмы. А при работе с внутренним хранилищем для удобства можно использовать методы-оболочки от Activity:
openFileOutput – открыть файл на запись
openFileInput – открыть файл на чтение
И есть метод getFilesDir – возвращает объект File, соответствующий каталогу для файлов вашей программы. Используйте его, чтобы работать напрямую, без методов-оболочек.
Подробности работы в java с файловой системой я здесь описывать не буду. На нашем форуме пользователь SKR сделал отличную памятку по работе с файлами. Скорее всего, вы найдете там все что нужно.
Если у вас проверка SD-карты показывает, что карта недоступна (см. лог), то убедитесь в свойствах AVD, что у вас для SDCard указан Size или File. Если указаны, то попробуйте перезапустить AVD.
На следующем уроке:
— создаем экран с вкладками
— используем иконку в названии вкладки
— используем обработчик перехода между вкладками
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
Правильная работа с файлами в Android
Сегодня я бы хотел рассказать вам о правильной работе с файлами в ОС Android. Итак, чаще всего у новичков возникают ситуации, когда обычные Java функции не могут корректно создать тот или иной файл в системе Android.
Во-первых, вам нужно обратить внимание на интересную особенность ОС:
когда вы устанавливаете apk приложение в эмулятор или телефон, система Linux (на которой базируется ядро Android) выделяет ему специальный User-ID, который является неким ключом доступа к (sandbox). То есть другие приложения в телефоне не смогут получить доступ к чтению файлов вашего приложения просто так. Кончено, всё это сделано в целях безопасности.
В общем, если вы запустите следующий код:
FileWriter f = new FileWriter(«impossible.txt»);
То этот код вызовет исключение: ‘java.io.FileNotFoundException: /impossible.txt ‘
Тогда как должен в случае отсутствия файла создать его.
Далее стоит отметить, что данное ограничение не распространяется на файлы, записываемые на SDCard. Туда можно писать любые файлы без всяких проблем, правда предварительно нужно добавить в AndroidManifest разрешение на запись:
Код файла на карту:
File fileName = null;
String sdState = android.os.Environment.getExternalStorageState();
if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) <
File sdDir = android.os.Environment.getExternalStorageDirectory();
fileName = new File(sdDir, «cache/primer.txt»);
> else <
fileName = context.getCacheDir();
>
if (!fileName.exists())
fileName.mkdirs();
try <
FileWriter f = new FileWriter(fileName);
f.write(«hello world»);
f.flush();
f.close();
> catch (Exception e) <
>
Как уже ранее было сказано мною, android приложение находится в некой песочнице, изолированной от воздействия со стороны других приложений по умолчанию. Для того, чтобы создать файл внутри этой песочницы, следует использовать функцию openFileOutput(). Хочу отметить 2 аргумента:
1. имя файла
2. режим доступа к нему со стороны чужих приложений
С первым аргументом все ясно, что касается второго, то режимов существует два: MODE_WORLD_READABLE и/или MODE_WORLD_WRITEABLE.
И ещё, чтобы записать файл можно использовать следующий код:
final String TESTSTRING = new String(«Hello Android»);
FileOutputStream fOut = openFileOutput(«samplefile.txt», MODE_WORLD_READABLE);
OutputStreamWriter osw = new OutputStreamWriter(fOut);
// записываем строку в файл
osw.write(TESTSTRING);
/* проверяем, что все действительно записалось и закрываем файл */
osw.flush();
osw.close();
Для чтения файлов используется метод openFileInput():
FileInputStream fIn = openFileInput(«samplefile.txt»);
InputStreamReader isr = new InputStreamReader(fIn);
char[] inputBuffer = new char[TESTSTRING.length()];
isr.read(inputBuffer);
String readString = new String(inputBuffer);
Для удаления используется метод deleteFile() в контексте приложения/активити. На этом я бы хотел закончить полезный пост, спасибо за внимание!
Источник
Методы лечения различных ошибок в Android Studio при разработке проекта
Сегодня хотел бы поделиться своим анализом и способами лечением разных ошибок при разработке своего продукта в Android Studio. Лично я, не раз сталкивался с различными проблемами и ошибками при компиляции и/или тестировании мобильного приложения. Данный процесс, всегда однообразный и в 99% случаев и всегда нужно тратить n-колличество времени на его устранение. Даже, когда ты уже сталкивался с данной проблемой, ты все равно идешь в поисковик и вспоминаешь, как же решить ту или иную ситуацию.
Я для себя завел файлик, в котором отметил самые частые ошибки — потратив на это несколько часов и перечислил самые популярные ошибки (в дальнейшем планирую просто их запомнить), чтоб сократить свое время в дальнейшем.
Итак, начну по порядку с самой распространенной проблемы и дальше буду перечислять их по мере появления:
1) Если подчеркивает красным код, где используются ресурсы: R. — попробовать (но вероятно не поможет): Build -> Clean Project.
В принципе на Build -> Clean Project можно не терять времени, а лучше всего — слева переключиться на Project, открыть каталог .idea, затем каталог libraries и из него удалить все содержимое. Затем нажать кнопку Sync Project. А затем (если все еще красное, но скорее всего уже будет все ок ) Build -> Clean Project.
2) После внезапного выключения компьютера, после перезапуска может быть во всех проектах весь код красным. Перед этим может быть ошибка: Unable to create Debug Bridge: Unable to start adb server: Unable to obtain result of ‘adb version’. Есть три решения — первое помогло, второе нет (но может быть для другого случая), а третье — не пробовал:
а) File — Invalidate Caches/Restart — Invalidate and Restart
б) Закрыть студию. В корне папки проекта удалить файл(ы) .iml и папку .idea. Вновь запустить студию и импортировать проект.
в) Нажать Ctrl-Alt-O и запустить оптимизацию импорта.
Кстати, adb сервер можно проверить на версию (и работоспособность) и затем перезапустить:
3) Если Android Studio выдает приблизительно такую ошибку: Error:Execution failed for task ‘:app:dexDebug’.
Надо слева переключиться на опцию Project, найти и удалить папку build которая лежит в папке app, т.е. по пути app/build. Затем перестроить весь проект заново: Build -> Rebuild Project.
Такое же решение если ошибка типа: «не могу удалить (создать) папку или файл» и указан путь, который в ведет в app/build. Тоже удаляем папку build и ребилдим проект.
4) В сообщении об ошибке упоминается heap — виртуальная память. А ошибка обычно вызвана ее нехваткой, т.е. невозможностью получить запрашиваемый объем. Поэтому этот запрашиваемый объем надо уменьшить, т.е. переписать дефолтное значение (обычно 2048 MB которое можно изменить в настройках), на меньшее 1024 MB.
В файле проекта gradle.properties пишем:
5) Android Studio пришет примерно такую ошибку: Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment variable to «83648b99316049d63656d7276cb19cc7e95d70a5»
Возможные причины (кроме необходимости регулярного обновления SDK):
а) Загруженный проект был скомпилирован с помощью уже несовместимого старого gradle плагина. В этом случае надо найти и подключить в своем build.gradle проекта этот более старый плагин. т.е. попробовать более старые версии, например: 1.1.3 (часто именно 1.1.x и подходит).
Найти все версии можно здесь.
б) Если в build.gradle проекта используется beta-версия плагина — это означает, что срок ее истек. Посмотреть последние релизы (продакшн и бета) можно также здесь:
6) Иногда при подключении сторонних библиотек могут дублироваться некоторые файлы (обычно связанные с лицензированием). В сообщении будет что-то содержащее слова: duplicate files. Решение — надо посмотреть в сообщении об ошибке или в документации подключенной сторонней библиотеки — какие именно файлы стали избыточными, и перечислить их в build.gradle модуля для исключения (exclude) из билда.
Это делается в директиве packagingOptions (которая, в свою очередь, находится в директиве android).
Источник