The Storage Situation: External Storage

The Storage Situation: External Storage

https://commonsware.com/blog/2014/04/08/storage-situation-external-storage.html

There is a lot of confusion regarding Android’s storage model. That confusionhas only increased with Android 4.4’s changes to that storage model. Thereare countless StackOverflow questions and the like where they clearly do notquite grok the various pieces of Android’s storage model.

This is the second post in a five-part series covering this storage model, to helpclarify what is going on. Today, we will look at “external storage”… includingits various definitions.

What Your Users Think “External Storage” Means

Many Android device users will have no idea what “external storage” means.There is nothing in the device UI that will necessarily use that term.

Users who visit Settings > Storage may see only “Internal Storage”:

Storage in Android Settings, Nexus 4, Android 4.4.2

Or, they may see both “Internal Storage” and “SD Card”:

Storage in Android Settings, LG Pad 8.3, Android 4.4.2

Hence, at best, your users will think that an SD card is external storage.That’s not quite right. Except on Android 4.4+, in which case it is onlysorta right.

(yes, this is all rather confusing)

What Google Thinks “External Storage” Means

The Android SDK documentationhas this to say in terms of a definition of “external storage”:

Every Android-compatible device supports a shared “external storage” that you can use to save files. This can be a removable storage media (such as an SD card) or an internal (non-removable) storage. Files saved to the external storage are world-readable and can be modified by the user when they enable USB mass storage to transfer files on a computer.

The vast majority of what has been written so far, in the documentation and elsewhere,about external storage was for the pre-4.4 world. In those halcyon days of yesteryear,there was a single volume known as “external storage”, and it was effectively defined as“the stuff that shows up when the user plugs their device into a computer using aUSB cable”. Even that wasn’t completely accurate, as some manufacturers would alsoallow access to their devices’ removable media via the USB cable as well. AndAndroid 4.4 has added yet more wrinkles in terms of removable media… which is whyremovable media gets its own blog post tomorrow.

For the purposes of this blog post – and to line up with what most other writtenmaterial will refer to – “external storage” is defined as the directory tree returnedby Environment.getExternalStorageDirectory().

The Many Places Where External Storage Is Stored

External storage, like a tumbleweed, goes where the wind blows it.

In Android 1.x and most 2.x devices, external storage was generally some formof removable media, typically a micro SD card. More importantly, for all Android 1.xand 2.x devices, external storage was a separate partition with a separate filesystem.While a few Android 2.3 devices elected to use on-board flash for external storage,that was still a separate partition from the partition that held internal storage.As a result, we wound up with devices that might advertise having several GB worthof storage, but that storage tended to be mostly for external storage, as the partitionscould not be resized by ordinary users.

Android 3.0 changed this around, allowing internal and external storage to each beon the same partition, just in separate directory trees. This provided a lot moreflexibility for users, as now there was no artificial hard distinction between spacefor internal storage and space for external storage. Device manufacturers still couldelect to have external storage be a separate partition, or even be on removable media,but typically they did not.

The Many Paths Under Which External Storage is Stored

For us as developers, the actual path under which this magical “external storage” wasaccessed varied over the years, from /sdcard, to locations under /storage, toeventually the current /mnt/shell/emulated/0. And just as secondary users of anAndroid 4.2+ tablet get their own internal storage, they get their own external storage,with its own root directory.

Hence, as I mentioned yesterday:

NEVER HARDCODE PATHS

Use various methods to get the base directory to work from… though this toohas gotten more complicated over the years.

In the beginning, everyone used Environment.getExternalStorageDirectory(),which pointed to the root of external storage. This led to external storagebeing just a big basket of random content.

Later, Google offered more organization:

  • getExternalFilesDir() and getExternalCacheDir() on Context, pointingto an application-specific directory on external storage, one that would bedeleted when the app is uninstalled

  • Environment.getExternalStoragePublicDirectory(), for centralized placesto store well-known file types, like photos and movies

Note that the Context methods have plural forms on Android 4.4+(getExternalFilesDirs() and getExternalCacheDirs()), which ties into removablemedia, which we will get into more tomorrow.

External Storage and Permissions

Just as the location – physically and logically – of external storage keepschanging, so does our ability to work with it.

Originally, apps could do whatever they wanted.

Android 1.5 added the WRITE_EXTERNAL_STORAGE permission, which apps had to holdto be able to write files to external storage. That way, the user would be informedat install time that the app intended to modify external storage contents. Any appcould still read from external storage, though.

Android 4.4 is now enforcing a READ_EXTERNAL_STORAGE permission, so you cannoteven read from external storage if you do not hold some permission. Note thatWRITE_EXTERNAL_STORAGE implies READ_EXTERNAL_STORAGE, so you only need one of those,not both. And, for getExternalFilesDir() and getExternalCacheDir(), you do notneed either of those permissions – you can read and write in those directorieswith impunity. Android now has an android:maxSdkVersion attribute on<uses-permission>, specifically so that you can drop WRITE_EXTERNAL_STORAGE ifyou no longer need it, because you are only working with getExternalFilesDir()and getExternalCacheDir().

Poking Around External Storage

As a developer, assuming that you can find where external storage really residesfor your version of Android, you have unfettered access to it from DDMS, for bothemulators and production devices.

You can also use a USB cable, much like your users will use. However, bear in mindthat what is presented to the USB interface is not what is on external storage…but, instead, is what has been indexed on external storage in the MediaStore.Hence, unless you take stepsto ensure that new files that you create get indexed, they may not be immediately visible.

Under the covers, Android is using the Media Transfer Protocol for its USBcommunications. This enables a lot more flexibility than does Mass Storage Mode(a.k.a., what thumb drives use) that Android used originally. However:

  • some MTP clients may cache directory listings, so even after you get your fileindexed by MediaStore, an already-attached client may need to be refreshed

  • I eagerly await a decent MTP solution for Linux (while Ubuntu’s support is betterthan it used to be, I still get squirrelly results, particularly for advancedI/O operations like “delete”)

Frequently-Asked Questions

Here are some FAQs about what the SDK refers to as external storage:

How Do I Secure My Files on External Storage?

In general, you don’t. The user has complete access to external storage, and otherapps can get to external storage if they hold the right permissions.

One thing that you can do is use something like Facebook’s Conceal.This encrypts your files on external storage, but uses a generated encryptionkey kept on internal storage. From a security standpoint, the net effectis to make external storage closer to internal storage in terms of read access.Note, though, that Conceal cannot prevent other apps, or the user, from deletingyour files on external storage, or perhaps trying to write to them and corruptingthe files as a result.

What About Apps-On-SD?

I mentioned yesterday that internal storage used to be as little as 70MB.

(and that’s still not a typo)

There was a hue and a cry to allow applications to be installed to external storage,as a way of providing more space for those apps. Android 2.2 added such a capability,via the android:installLocation attribute on the root <manifest> elementin your manifest file.

However, once Android 3.0 shipped, this became less useful, because internaland external storage share a common partition.

My understanding is that you can only move an app to external storage nowadaysif you have a device for which external storage is still a separate partition.Personally, out of the 50+ devices in my Secret Mountain Lair, I have zero thatare on Android 3.0+ that have external storage as a separate partition, so I cannotconfirm this behavior.

Now, of course, the hue and cry have moved to putting apps on removable media, aspower users are running out of room on 32GB devices for all their apps. It isconceivable that Google will extend android:installLocation to supportremovable media, though I am not exactly holding my breath.

The Rest of the Posts

The entire blog post series covers:

— Apr 08, 2014 

Copyright © 2015 CommonsWare, LLC — All Rights Reserved

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值