Create file android sd card

Полный список

— работаем с файлами

Работа с файлами в 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 для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

How to create directory automatically on SD card

I’m trying to save my file to the following location
FileOutputStream fos = new FileOutputStream(«/sdcard/Wallpaper/»+fileName); but I’m getting the exception java.io.FileNotFoundException
However, when I put the path as «/sdcard/» it works.

Now I’m assuming that I’m not able to create directory automatically this way.

Can someone suggest how to create a directory and sub-directory using code?

14 Answers 14

If you create a File object that wraps the top-level directory you can call it’s mkdirs() method to build all the needed directories. Something like:

Note: It might be wise to use Environment.getExternalStorageDirectory() for getting the «SD Card» directory as this might change if a phone comes along which has something other than an SD Card (such as built-in flash, a’la the iPhone). Either way you should keep in mind that you need to check to make sure it’s actually there as the SD Card may be removed.

UPDATE: Since API Level 4 (1.6) you’ll also have to request the permission. Something like this (in the manifest) should work:

Had the same problem and just want to add that AndroidManifest.xml also needs this permission:

Here is what works for me.

in your manifest and the code below

Actually I used part of @fiXedd asnwer and it worked for me:

Make sure that you are using mkdirs() not mkdir() to create the complete path

With API 8 and greater, the location of the SD card has changed. @fiXedd’s answer is good, but for safer code, you should use Environment.getExternalStorageState() to check if the media is available. Then you can use getExternalFilesDir() to navigate to the directory you want (assuming you’re using API 8 or greater).

You can read more in the SDK documentation.

Don’t forget to make sure that you have no special characters in your file/folder names. Happened to me with «:» when I was setting folder names using variable(s)

Читайте также:  Все для андроид offline

not allowed characters in file/folder names

U may find this code helpful in such a case.

The below code removes all «:» and replaces them with «-«

I faced the same problem. There are two types of permissions in Android:

  • Dangerous (access to contacts, write to external storage. )
  • Normal (Normal permissions are automatically approved by Android while dangerous permissions need to be approved by Android users.)

Here is the strategy to get dangerous permissions in Android 6.0

  • Check if you have the permission granted
  • If your app is already granted the permission, go ahead and perform normally.
  • If your app doesn’t have the permission yet, ask for user to approve
  • Listen to user approval in onRequestPermissionsResult

Here is my case: I need to write to external storage.

Источник

Universal way to write to external SD card on Android

In my application, I need to store lots of images in the device storage. Such files tend to fulfill the device storage, and I want to allow users to be able to choose external SD card as the destination folder.

I read everywhere that Android doesn’t allow users to write to external SD card, by SD card I mean the external and mountable SD card and not the external storage, but file manager applications manage to write to External SD on all Android versions.

What is the better way to grant read/write access to external SD card on different API levels (Pre-KitKat, KitKat, Lollipop+)?

Update 1

I tried Method 1 from Doomknight’s answer, with no avail: As you can see I’m checking for permissions at runtime before attempting to write on SD:

But I get an access error, tried on two different devices: HTC10 and Shield K1.

7 Answers 7

Summary

Since KitKat, permissions are not necessary if you use app-specific directories, required otherwise.

Universal way:

The history says that there is no universal way to write to external SD card but continues.

API-based way:

Request permissions in manifest (Api = 23).

Recommended way:

The secure way of sharing it is to use a content provider or the new Storage Access Framework.

Privacy-aware way:

As of Android Q Beta 4, apps that target Android 9 (API level 28) or lower see no change, by default.

Apps targeting Android Q by default (or opting into it) are given a filtered view into external storage.

Universal way to write to external SD card on Android

Pre-KitKat: official Android platform has not supported SD cards at all except for exceptions.

KitKat: introduced APIs that let apps access files in app-specific directories on SD cards.

Lollipop: added APIs to allow apps to request access to folders owned by other providers.

Nougat: provided a simplified API to access common external storage directories.

What is the better way to grant read/write access to external SD card on different API levels

Update 1. I tried Method 1 from Doomknight’s answer, with no avail:

As you can see I’m checking for permissions at runtime before attempting to write on SD.

I would use application-specific directories to avoid the issue of your updated question and ContextCompat.getExternalFilesDirs() using getExternalFilesDir documentation as reference.

Improve the heuristics to determine what represents removable media based on the different api levels like android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT

. But I get an access error, tried on two different devices: HTC10 and Shield K1.

Remember that Android 6.0 supports portable storage devices and third-party apps must go through the Storage Access Framework. Your devices HTC10 and Shield K1 are probably API 23.

Your log shows a permission denied exception accessing /mnt/media_rw , like this fix for API 19+:

I never tried it so I can not share code but I would avoid the for trying to write on all the returned directories and look for the best available storage directory to write into based on remaining space.

Perhaps Gizm0’s alternative to your getStorageDirectories() method it’s a good starting point.

ContextCompat.getExternalFilesDirs solves the issue if you don’t need access to other folders.

Prior to KitKat try to use Doomsknight method 1 or read this response by Gnathonic.

Add the next code to your AndroidManifest.xml and read Getting access to external storage

Access to external storage is protected by various Android permissions.

Starting in Android 1.0, write access is protected with the WRITE_EXTERNAL_STORAGE permission.

Starting in Android 4.1, read access is protected with the READ_EXTERNAL_STORAGE permission.

In order to . write files on the external storage, your app must acquire . system permissions:

If you need to both. you need to request only the WRITE_EXTERNAL_STORAGE permission.

  • Until Android 4.4, there was no official support for removable media in Android, Starting in KitKat, the concept of “primary” and “secondary” external storage emerges in the FMW API.
  • Prior apps are just relying on MediaStore indexing, ship with the hardware or examine mount points and apply some heuristics to determine what represents removable media.

Ignore the next note due to bugs, but try to use ContextCompat.getExternalFilesDirs() :

  • Since Android 4.2, there has been a request from Google for device manufacturers to lock down removable media for security (multi-user support) and new tests were added in 4.4.
  • Since KitKat getExternalFilesDirs() and other methods were added to return a usable path on all available storage volumes (The first item returned is the primary volume).
  • The table below indicates what a developer might try to do and how KitKat will respond:

Note: Beginning with Android 4.4, these permissions are not required if you’re reading or writing only files that are private to your app. For more info. see saving files that are app-private.

In KitKat there’s now a public API for interacting with these secondary shared storage devices.

The new Context.getExternalFilesDirs() and Context.getExternalCacheDirs() methods can return multiple paths, including both primary and secondary devices.

Читайте также:  Oneplus dialer android 11

You can then iterate over them and check Environment.getStorageState() and File.getFreeSpace() to determine the best place to store your files.

These methods are also available on ContextCompat in the support-v4 library.

Starting in Android 4.4, the owner, group and modes of files on external storage devices are now synthesized based on directory structure. This enables apps to manage their package-specific directories on external storage without requiring they hold the broad WRITE_EXTERNAL_STORAGE permission. For example, the app with package name com.example.foo can now freely access Android/data/com.example.foo/ on external storage devices with no permissions. These synthesized permissions are accomplished by wrapping raw storage devices in a FUSE daemon.

With KitKat your chances for a «complete solution» without rooting are pretty much zero:

The Android project has definitely screwed up here. No apps get full access to external SD cards:

  • file managers: you cannot use them to manage your external SD card. In most areas, they can only read but not write.
  • media apps: you cannot retag/re-organize your media collection any longer, as those apps cannot write to it.
  • office apps: pretty much the same

The only place 3 rd party apps are allowed to write on your external card are «their own directories» (i.e. /sdcard/Android/data/

The only ways to really fix that require either the manufacturer (some of them fixed it, e.g. Huawei with their Kitkat update for the P6) – or root. (Izzy’s explanation continues here)

  1. Android 5.0 introduced changes and the DocumentFile helper class.

getStorageState Added in API 19, deprecated in API 21, use getExternalStorageState(File)

Here’s a great tutorial for interacting with the Storage Access Framework in KitKat.

  1. Android 6.0 Marshmallow introduces a new runtime permissions model.

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app . or update the app . user can revoke the permissions.

Android 6.0 introduces a new runtime permissions model where apps request capabilities when needed at runtime. Because the new model includes the READ/WRITE_EXTERNAL_STORAGE permissions, the platform needs to dynamically grant storage access without killing or restarting already-running apps. It does this by maintaining three distinct views of all mounted storage devices:

  • /mnt/runtime/default is shown to apps with no special storage permissions.
  • /mnt/runtime/read is shown to apps with READ_EXTERNAL_STORAGE
  • /mnt/runtime/write is shown to apps with WRITE_EXTERNAL_STORAGE
  1. Android 7.0 provides a simplified API to access external storage dirs.

Scoped Directory Access In Android 7.0, apps can use new APIs to request access to specific external storage directories, including directories on removable media such as SD cards.

Note that the scoped directory access added in 7.0 is deprecated in Android Q.

Specifically, the createAccessIntent() method on StorageVolume is deprecated.

They added a createOpenDocumentTreeIntent() that can be used as an alternative.

  1. Android 8.0 Oreo .. Android Q Beta changes.

Starting in Android O, the Storage Access Framework allows custom documents providers to create seekable file descriptors for files residing in a remote data source.

Permissions, prior to Android O, if an app requested a permission at runtime and the permission was granted, the system also incorrectly granted the app the rest of the permissions that belonged to the same permission group, and that were registered in the manifest.

For apps targeting Android O, this behavior has been corrected. The app is granted only the permissions it has explicitly requested. However, once the user grants a permission to the app, all subsequent requests for permissions in that permission group are automatically granted.

For example, READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE .

Update: An Android Q earlier beta release temporarily replaced the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions with more fine-grained, media-specific permissions.

Note: Google introduced roles on Beta 1 and removed them from the documentation before Beta 2.

Note: The permissions specific to media collections that were introduced in earlier beta releases— READ_MEDIA_IMAGES , READ_MEDIA_AUDIO , and READ_MEDIA_VIDEO —are now obsolete. More info:

«Death is more universal than life. Everyone dies, but not everyone lives.» ― Andrew Sachs

  1. Related questions and recommended answers.
  1. Related bugs and issues.

I believe there are two methods to achieve this:

METHOD 1: (does NOT work on 6.0 and above, due to permission changes)

I have been using this method for years on many device version with no issue. Credit is due to the original source, as it was not me who wrote it.

It will return all mounted media (including Real SD Cards) in a list of strings directory locations. With the list you can then ask the user where to save, etc.

You can call it with the following:

METHOD 2:

Use the v4 support library

Just call the following to get a list of File locations of storage.

The locations differ in usage however though.

Returns absolute paths to application-specific directories on all external storage devices where the application can place persistent files it owns. These files are internal to the application, and not typically visible to the user as media.

External storage devices returned here are considered a permanent part of the device, including both emulated external storage and physical media slots, such as SD cards in a battery compartment. The returned paths do not include transient devices, such as USB flash drives.

Читайте также:  Настройка часов вотч 6 андроид

An application may store data on any or all of the returned devices. For example, an app may choose to store large files on the device with the most available space

They are like app specific files. Hidden from other apps.

Just another answer. This answer only shows 5.0+ because I believe Doomknight’s answer posted here is the best way to do for Android 4.4 and below.

This is originally posted here (Is there a way to get SD Card size in Android?) by me to get the external SD Card’s size on Android 5.0+

To get the External SD card as a File :

Note: I only get the «first» external sd card however you can modify it and return ArrayList instead of File and let the loop continue instead of calling break after the first one is found.

In addition to all other nice answers, I could add a bit more to this question so it can give wider coverage for readers. In my answer here, I would use 2 countable resources to present External Storage.

The first resource is from Android Programming, The Big Nerd Ranch Guide 2nd edition, chapter 16, page 294.

The book describes the basic and external file and directory methods. I will try to make a resume of what could be relevant to your question.

The following part from the book:

External Storage

Your photo needs more than a place on the screen. Full-size pictures are too large to stick inside a SQLite database, much less an Intent . They will need a place to live on your device’s filesystem. Normally, you would put them in your private storage. Recall that you used your private storage to save your SQLite database. With methods like Context.getFileStreamPath(String) and Context.getFilesDir() , you can do the same thing with regular files, too (which will live in a subfolder adjacent to the databases subfolder your SQLite database lives in)

Basic file and directory methods in Context

If you are storing files that only your current application needs to use, these methods are exactly what you need.

On the other hand, if you need another application to write to those files, you are out of luck: while there is a Context.MODE_WORLD_READABLE flag you can pass in to openFileOutput(String, int) , it is deprecated, and not completely reliable in its effects on newer devices. If you are storing files to share with other apps or receiving files from other apps (files like stored pictures), you need to store them on external storage instead.

There are two kinds of external storage: primary, and everything else. All Android devices have at least one location for external storage: the primary location, which is located in the folder returned by Environment.getExternalStorageDirectory() . This may be an SD card, but nowadays it is more commonly integrated into the device itself. Some devices may have additional external storage. That would fall under “everything else.”

Context provides quite a few methods for getting at external storage, too. These methods provide easy ways to get at your primary external storage, and kinda-sorta-easy ways to get at everything else. All of these methods store files in publicly available places, too, so be careful with them.

External file and directory methods in Context

Technically, the external folders provided above may not be available, since some devices use a removable SD card for external storage. In practice this is rarely an issue, because almost all modern devices have nonremovable internal storage for their “external” storage. So it is not worth going to extreme lengths to account for it. But we do recommended including simple code to guard against the possibility, which you will do in a moment.

External storage permission

In general, you need a permission to write or read from external storage. Permissions are well-known string values you put in your manifest using the tag. They tell Android that you want to do something that Android wants you to ask permission for.

Here, Android expects you to ask permission because it wants to enforce some accountability. You tell Android that you need to access external storage, and Android will then tell the user that this is one of the things your application does when they try to install it. That way, nobody is surprised when you start saving things to their SD card.

In Android 4.4, KitKat, they loosened this restriction. Since Context.getExternalFilesDir(String) returns a folder that is specific to your app, it makes sense that you would want to be able to read and write files that live there. So on Android 4.4 (API 19) and up, you do not need this permission for this folder. (But you still need it for other kinds of external storage.)

Add a line to your manifest that requests the permission to read external storage, but only up to API Listing 16.5 Requesting external storage permission ( AndroidManifest.xml )

The maxSdkVersion attribute makes it so that your app only asks for this permission on versions of Android that are older than API 19, Android KitKat. Note that you are only asking to read external storage. There is also a WRITE_EXTERNAL_STORAGE permission, but you do not need it. You will not be writing anything to external storage: The camera app will do that for you

The second resource is this link read all of it, but you can also jump to Using the External Storage section.

Источник

Оцените статью