⬆️ ⬇️

Android Storage: Internal, External, Removable. Part 1/3

Anyone who, despite everything, has managed to make the right choice.

This is a translation of a series of articles by Mark Murphy from CommonsWare, widely known on stackoverflow, as well as the author of the books “The Busy Coder’s Guide to Android Development”, “Android’s Architecture Components”. Some terms are left untranslated.



Internal Storage



There is a lot of confusion regarding the Android storage model. The confusion has become much more with the changes of Android 4.4 in the Storage Model, and since then the situation has not improved. There are countless questions on Stack Overflow and other similar resources, where people clearly do not quite understand the various models of Android storage.



What Users Consider Internal Storage



Depending on the model of your device, users will eventually come to Settings -> Storage on their device (Settings -> Storage on their device) or an equivalent place, and can see a screen that describes “Internal storage” .



The user thinks that the entire built-in flash drive is “Internal Storage” (Internal Storage). Fortunately, Google began to change this term from Android 8.0, going to “general storage” instead of “internal storage”.



However, users can still see “internal storage” in places such as the Windows Explorer window when their device is connected via USB.



What Google Considers Internal Storage



Alas, what users see is not the same as the Android SDK considers “internal storage”, which leads to some confusion. If you read the Android documentation on the internal storage , then this description ... at least vague (note the text has changed since the writing of the article):



You can save files directly to the device’s internal memory. By default, files stored in the internal storage are private to your application, and other applications cannot access them (as well as the user). When the user deletes the application, these files are deleted.

Truth be told, the Android SDK defines “internal storage” as a special directory unique to your application, where your application can host files. As suggested in the documentation, these default files are designed to be read and written for your application and are prohibited for any other application (exception: users working with file managers with root privileges on rooted devices can access everything).



In Context, there are several basic methods that give you access to internal storage, including:





Other methods will rely on them, such as openOrCreateDatabase() . Other classes will also rely on them, such as SQLiteOpenHelper and SharedPreferences .



Where Internal Storage is Stored ... Sometimes



If you are viewing various blog posts, responses to StackOverflow, and books released in 2012 or earlier, you are informed that the “internal storage” of your application is located at: /data/data/your.application.package.name .



Inside there will be some directories automatically created by Android, since you are using some of the Context methods. For example, getFilesDir() returns a File object pointing to the files/ directory in your application’s internal storage.



Where is the internal storage stored ... the rest of the time



However, the internal storage of your application is not always located in the specified location. For developers, there is one rule that you should learn from this series of blog posts:



NEVER HARDCODE PATHS .



From time to time, I see developers doing something like this:



File f=new File("/data/data/their.app.package.name/files/foo.txt");



This is not a crime, it is worse, it is a mistake.



The right move, and write less:



File f=new File(getFilesDir(), "foo.txt");



More importantly, the internal storage is not always in one place . It is noteworthy that we have the concept of separate user profiles (separate user profiles), starting with Android 4.2 for tablets and Android 5.0 for phones. Each user gets their own "internal storage". Although the above directory is still used for the primary user, it is not guaranteed that it will also be used for secondary accounts.



We investigate Internal Storage



The Device File Explorer tool in Android Studio 3.0+ can view all internal storage on the emulator, as well as internal storage of debugged applications on production devices.



On the command line, you can use adb with the run-as option.



For example, to load a database from the main user's internal storage to your development machine, you can use:



adb shell 'run-as your.application.package.name cp /data/data/your.application.package.name/databases/dbname.db /sdcard'



Note that:





Internal Storage Restrictions



On older Android 1.x and 2.x devices, internal storage was usually located in a dedicated partition of the file system, and this partition was usually quite tiny. HTC Dream (aka, T-Mobile G1), the original Android device, had a huge 70 MB of internal memory for use by all applications (this is not a typo, at that time we measured the memory in megabytes).



By the time 2.3 devices came out, the internal storage could be 1 GB in size.



Android 3.0 has changed the storage model, as the internal storage has become more volume. Devices that advertise as having 4 GB, 8 GB, 16 GB, etc. storage space, there was usually all this (minus existing content) available for internal storage. We will look at what has changed in Android 3.0 and its effect on the storage model in the following posts about external storage.



For Android 1.x and 2.x, internal storage was really only for small files, and you needed to use external storage for everything else. Android 3.0+ means that for most devices and most users, internal storage is great for files that are not intended for normal use by other applications or are accessible to the user regardless of your application. However, some experienced users find that even on-board flash is not enough for what they want to store, so they switch to removable storage ... which is a can of worms (note ἕλμινς) - the source of many unpredictable and complex problems.



Internal Storage FAQ



Should I make files in the World-Readable or World-Writeable internal storage?



Oh, $ gods, no. Use FileProvider and serve this content using the ContentProvider implementation. After that, you at least have the ability to use the Android permission system to control access to these files, unlike your version, when any application on the system can corrupt these files.



Well, what about android:sharedUserId ?



I do not advise.



android: sharedUserId is an attribute that you can put in a manifest that specifies the logical user ID that will be used for your application. Any other application that is installed, which is signed by the same signature key and requests the same android:sharedUserId will use the same Linux user from a security point of view. The effect is that these two applications will be able to work with each other's files with impunity, since these files belong to the same Linux user.



This attribute is really intended for pre-installed applications such as the software suite pre-loaded by the device manufacturer, mobile operator or developer of a modified ROM firmware. In particular, as soon as you install your application once, you cannot then change your value painlessly android:sharedUserId without blocking the user’s access to any existing files ... since Android does not change the owner’s rights to existing files when changing the Linux user account under which starts the application.



There are various risks with simultaneous access of several processes to files. Some subsystems, such as SQLite, have built-in logic to solve this problem. But if you yourself organize your own access to the file (for example, through File and Java I / O), you need to do something with simultaneous access, and this is difficult.



You also need to handle the situation when one application is uninstalled, deleting files that another application used. In a hub-and-spoke model, for example, with an application and a set of plug-ins, this may not be so risky. In other models where applications are more equal, you cannot afford to lose the data of your application just because the user decided to delete some particular application.



Finally, you do not know what the future can bring. Right now you can view your suite of applications as a set with a close connection. Someone who acquires these applications or acquires your company may want to go the other way. Using data sharing features that are more loosely coupled, like ContentProvider , gives you more flexibility. In an ideal world, your application should treat other applications as a fairly reliable, but not always accessible resource, just like your own web service.



How to prevent users of rooted devices from accessing my files in the internal storage?



Just do not place files in the internal storage. Users of rooted devices can gain access to what they need on the device, so the only way to prevent them from accessing your data is to not have them on the device.



Some developers will try to encrypt their files with a hard-coded password so that users of rooted devices cannot use these files. This will create a “speed bump” effect for a short time. All that is required is one person who is interested in reverse engineering your application, who determined how to decrypt these files and then wrote a blog or forum message on how to do this.



In general, there are relatively few people with rooted devices - I rate them at less than 1%. IMHO, you will succeed more by focusing your engineering work on writing the best application, instead of wasting time on protection from rooted devices.



')

Source: https://habr.com/ru/post/429338/



All Articles