Add new API to find out whether external storage is removable.

This is implemented based on whether we are using the "nosdcard"
product.  Needed to tweak aapt to allow use of the product attribute
with other resource definition tags besides strings.

Change-Id: I49922d23b52a34183a8e2f4d2515adaf1fc9149a
This commit is contained in:
Dianne Hackborn
2010-10-04 11:31:17 -07:00
parent eb6e22f29d
commit 407f625a9b
4 changed files with 62 additions and 12 deletions

View File

@@ -123739,6 +123739,17 @@
visibility="public"
>
</method>
<method name="isExternalStorageRemovable"
return="boolean"
abstract="false"
native="false"
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
<field name="DIRECTORY_ALARMS"
type="java.lang.String"
transient="false"

View File

@@ -18,6 +18,7 @@ package android.os;
import java.io.File;
import android.content.res.Resources;
import android.os.storage.IMountService;
/**
@@ -116,6 +117,19 @@ public class Environment {
* happened. You can determine its current state with
* {@link #getExternalStorageState()}.
*
* <p><em>Note: don't be confused by the word "external" here. This
* directory can better be thought as media/shared storage. It is a
* filesystem that can hold a relatively large amount of data and that
* is shared across all applications (does not enforce permissions).
* Traditionally this is an SD card, but it may also be implemented as
* built-in storage in a device that is distinct from the protected
* internal storage and can be mounted as a filesystem on a computer.</em></p>
*
* <p>In devices with multiple "external" storage directories (such as
* both secure app storage and mountable shared storage), this directory
* represents the "primary" external storage that the user will interact
* with.</p>
*
* <p>Applications should not directly use this top-level directory, in
* order to avoid polluting the user's root namespace. Any files that are
* private to the application should be placed in a directory returned
@@ -130,6 +144,9 @@ public class Environment {
*
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* monitor_storage}
*
* @see #getExternalStorageState()
* @see #isExternalStorageRemovable()
*/
public static File getExternalStorageDirectory() {
return EXTERNAL_STORAGE_DIRECTORY;
@@ -359,11 +376,9 @@ public class Environment {
public static final String MEDIA_UNMOUNTABLE = "unmountable";
/**
* Gets the current state of the external storage device.
* Note: This call should be deprecated as it doesn't support
* multiple volumes.
* Gets the current state of the primary "external" storage device.
*
* <p>See {@link #getExternalStorageDirectory()} for an example of its use.
* <p>See {@link #getExternalStorageDirectory()} for more information.
*/
public static String getExternalStorageState() {
try {
@@ -377,6 +392,19 @@ public class Environment {
}
}
/**
* Returns whether the primary "external" storage device is removable.
* If true is returned, this device is for example an SD card that the
* user can remove. If false is returned, the storage is built into
* the device and can not be physically removed.
*
* <p>See {@link #getExternalStorageDirectory()} for more information.
*/
public static boolean isExternalStorageRemovable() {
return Resources.getSystem().getBoolean(
com.android.internal.R.bool.config_externalStorageRemovable);
}
static File getDirectory(String variableName, String defaultPath) {
String path = System.getenv(variableName);
return path == null ? new File(defaultPath) : new File(path);

View File

@@ -71,6 +71,15 @@
when there's no network connection. If the scan doesn't timeout, use zero -->
<integer name="config_radioScanningTimeout">0</integer>
<!-- A product with no SD card == not removable. -->
<bool name="config_externalStorageRemovable" product="nosdcard">false</bool>
<!-- Configures whether the primary external storage device is
removable. For example, if external storage is on an SD card,
it is removable; if it is built in to the device, it is not removable.
The default product has external storage on an SD card, which is
removable. -->
<bool name="config_externalStorageRemovable" product="default">true</bool>
<!-- XXXXX NOTE THE FOLLOWING RESOURCES USE THE WRONG NAMING CONVENTION.
Please don't copy them, copy anything else. -->

View File

@@ -782,7 +782,6 @@ status_t compileResourceFile(Bundle* bundle,
const String16 translatable16("translatable");
const String16 formatted16("formatted");
const String16 false16("false");
const String16 product16("product");
const String16 myPackage(assets->getPackage());
@@ -830,7 +829,6 @@ status_t compileResourceFile(Bundle* bundle,
bool curIsStyled = false;
bool curIsPseudolocalizable = false;
bool curIsFormatted = fileIsTranslatable;
String16 curProduct;
bool localHasErrors = false;
if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
@@ -1228,8 +1226,6 @@ status_t compileResourceFile(Bundle* bundle,
translatable.setTo(block.getAttributeStringValue(i, &length));
} else if (strcmp16(attr, formatted16.string()) == 0) {
formatted.setTo(block.getAttributeStringValue(i, &length));
} else if (strcmp16(attr, product16.string()) == 0) {
curProduct.setTo(block.getAttributeStringValue(i, &length));
}
}
@@ -1356,6 +1352,12 @@ status_t compileResourceFile(Bundle* bundle,
hasErrors = localHasErrors = true;
}
String16 product;
identIdx = block.indexOfAttribute(NULL, "product");
if (identIdx >= 0) {
product = String16(block.getAttributeStringValue(identIdx, &len));
}
String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr);
if (curIsBag) {
@@ -1447,7 +1449,7 @@ status_t compileResourceFile(Bundle* bundle,
err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,
ident, parentIdent, itemIdent, curFormat, curIsFormatted,
curProduct, false, overwrite, outTable);
product, false, overwrite, outTable);
if (err == NO_ERROR) {
if (curIsPseudolocalizable && localeIsDefined(curParams)
&& bundle->getPseudolocalize()) {
@@ -1456,7 +1458,7 @@ status_t compileResourceFile(Bundle* bundle,
block.setPosition(parserPosition);
err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,
curType, ident, parentIdent, itemIdent, curFormat,
curIsFormatted, curProduct, true, overwrite, outTable);
curIsFormatted, product, true, overwrite, outTable);
#endif
}
}
@@ -1480,7 +1482,7 @@ status_t compileResourceFile(Bundle* bundle,
err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
*curTag, curIsStyled, curFormat, curIsFormatted,
curProduct, false, overwrite, outTable);
product, false, overwrite, outTable);
if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
hasErrors = localHasErrors = true;
@@ -1492,7 +1494,7 @@ status_t compileResourceFile(Bundle* bundle,
block.setPosition(parserPosition);
err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
ident, *curTag, curIsStyled, curFormat,
curIsFormatted, curProduct,
curIsFormatted, product,
true, overwrite, outTable);
if (err != NO_ERROR) {
hasErrors = localHasErrors = true;