More storage UI updates.
Storage volumes now have headers with larger fonts and progress bars to show used versus free space. Updated Memory to use new formatting template, and Data Usage to use consistent display logic. Allocate a unique color for each private volume, and yell when a volume is running low on space. Update private volume details to launch into MediaStore-backed storage backends in a management mode, and only show detailed items when hosting emulated storage. Show details dialog about "Other" and user storage items. Shortcut into single private volume when it's the only device. Add real eject icon. Bug: 21756698, 20275574, 21326612 Change-Id: If3ecd1d912d3e709c09d3e4da24f368e04dd3f9d
This commit is contained in:
24
res/drawable/ic_eject_24dp.xml
Normal file
24
res/drawable/ic_eject_24dp.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M5 17h14v2H5zm7,-12L5.33 15h13.34z"/>
|
||||
</vector>
|
24
res/drawable/ic_eject_48dp.xml
Normal file
24
res/drawable/ic_eject_48dp.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M5 17h14v2H5zm7,-12L5.33 15h13.34z"/>
|
||||
</vector>
|
24
res/drawable/ic_warning_24dp.xml
Normal file
24
res/drawable/ic_warning_24dp.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M2 42h44L24 4 2 42zm24,-6h-4v-4h4v4zm0,-8h-4v-8h4v8z"/>
|
||||
</vector>
|
24
res/drawable/ic_warning_48dp.xml
Normal file
24
res/drawable/ic_warning_48dp.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48.0"
|
||||
android:viewportHeight="48.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M2 42h44L24 4 2 42zm24,-6h-4v-4h4v4zm0,-8h-4v-8h4v8z"/>
|
||||
</vector>
|
@@ -20,7 +20,7 @@
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
<ImageView
|
||||
android:id="@+id/unmount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
@@ -29,19 +29,7 @@
|
||||
android:contentDescription="@string/storage_menu_unmount"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:textSize="30sp"
|
||||
android:src="@drawable/ic_eject_24dp"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
|
||||
<!--
|
||||
<ImageView
|
||||
android:id="@+id/eject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingStart="16dip"
|
||||
android:paddingEnd="16dip"
|
||||
android:src="@drawable/ic_sync_green_holo"
|
||||
android:contentDescription="@string/storage_menu_eject"
|
||||
android:layout_gravity="center"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
-->
|
||||
</LinearLayout>
|
||||
|
60
res/layout/storage_summary.xml
Normal file
60
res/layout/storage_summary.xml
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:paddingTop="16dip"
|
||||
android:paddingBottom="16dip"
|
||||
android:background="?android:attr/selectableItemBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Subhead"
|
||||
android:textColor="#ff607d8b"
|
||||
android:textSize="36sp"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Body1"
|
||||
android:textColor="#8a000000"
|
||||
android:maxLines="10" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@android:id/progress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:visibility="gone"
|
||||
android:max="100"
|
||||
style="?android:attr/progressBarStyleHorizontal" />
|
||||
|
||||
</LinearLayout>
|
89
res/layout/storage_volume.xml
Normal file
89
res/layout/storage_volume.xml
Normal file
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:background="?android:attr/activatedBackgroundIndicator"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/icon_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="-4dp"
|
||||
android:minWidth="60dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp">
|
||||
<com.android.internal.widget.PreferenceImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxWidth="48dp"
|
||||
android:maxHeight="48dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<TextView android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:ellipsize="marquee" />
|
||||
|
||||
<TextView android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@android:id/title"
|
||||
android:layout_alignStart="@android:id/title"
|
||||
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:maxLines="10" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@android:id/progress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_below="@android:id/summary"
|
||||
android:layout_alignStart="@android:id/summary"
|
||||
android:max="100"
|
||||
style="?android:attr/progressBarStyleHorizontal" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- Preference should place its actual preference widget here. -->
|
||||
<LinearLayout android:id="@android:id/widget_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="end|center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:orientation="vertical" />
|
||||
|
||||
</LinearLayout>
|
@@ -2363,7 +2363,7 @@
|
||||
<!-- Summary of a single storage volume, constrasting available and total storage space. [CHAR LIMIT=48]-->
|
||||
<string name="storage_volume_summary"><xliff:g id="used" example="1.2GB">%1$s</xliff:g> used of <xliff:g id="total" example="32GB">%2$s</xliff:g></string>
|
||||
<!-- Summary of a single storage volume used space. [CHAR LIMIT=24] -->
|
||||
<string name="storage_size_large"><xliff:g id="number" example="128">^1</xliff:g> <small><small><xliff:g id="unit" example="KB">^2</xliff:g></small></small></string>
|
||||
<string name="storage_size_large"><xliff:g id="number" example="128">^1</xliff:g><small><small> <xliff:g id="unit" example="KB">^2</xliff:g></small></small></string>
|
||||
<!-- Summary of a single storage volume total space. [CHAR LIMIT=48]-->
|
||||
<string name="storage_volume_used">Used of <xliff:g id="total" example="32GB">%1$s</xliff:g></string>
|
||||
<!-- Summary of a single storage volume total space. [CHAR LIMIT=48]-->
|
||||
|
@@ -19,11 +19,12 @@ import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceClickListener;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.text.format.Formatter.BytesResult;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.settings.InstrumentedFragment;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.applications.ProcStatsData.MemInfo;
|
||||
@@ -76,7 +77,8 @@ public class ProcessStatsSummary extends ProcessStatsBase implements OnPreferenc
|
||||
double usedRam = memInfo.realUsedRam;
|
||||
double totalRam = memInfo.realTotalRam;
|
||||
double freeRam = memInfo.realFreeRam;
|
||||
String usedString = Formatter.formatShortFileSize(context, (long) usedRam);
|
||||
BytesResult usedResult = Formatter.formatBytes(context.getResources(), (long) usedRam,
|
||||
Formatter.FLAG_SHORTER);
|
||||
String totalString = Formatter.formatShortFileSize(context, (long) totalRam);
|
||||
String freeString = Formatter.formatShortFileSize(context, (long) freeRam);
|
||||
CharSequence memString;
|
||||
@@ -87,7 +89,8 @@ public class ProcessStatsSummary extends ProcessStatsBase implements OnPreferenc
|
||||
} else {
|
||||
memString = memStatesStr[memStatesStr.length - 1];
|
||||
}
|
||||
mMemStatus.setText(usedString);
|
||||
mMemStatus.setText(TextUtils.expandTemplate(getText(R.string.storage_size_large),
|
||||
usedResult.value, usedResult.units));
|
||||
float usedRatio = (float)(usedRam / (freeRam + usedRam));
|
||||
mColors.setRatios(usedRatio, 0, 1 - usedRatio);
|
||||
|
||||
|
@@ -21,7 +21,7 @@ import static com.android.settings.deviceinfo.StorageSettings.TAG;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.DownloadManager;
|
||||
import android.app.Fragment;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@@ -34,15 +34,16 @@ import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.storage.DiskInfo;
|
||||
import android.os.storage.StorageEventListener;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.os.storage.VolumeInfo;
|
||||
import android.os.storage.VolumeRecord;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.text.format.Formatter.BytesResult;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
@@ -79,8 +80,12 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
|
||||
// TODO: warn when mounted read-only
|
||||
|
||||
private static final String TAG_RENAME = "rename";
|
||||
private static final String TAG_OTHER_INFO = "otherInfo";
|
||||
private static final String TAG_USER_INFO = "userInfo";
|
||||
private static final String TAG_CONFIRM_CLEAR_CACHE = "confirmClearCache";
|
||||
|
||||
private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents";
|
||||
|
||||
private StorageManager mStorageManager;
|
||||
private UserManager mUserManager;
|
||||
|
||||
@@ -94,19 +99,16 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
|
||||
|
||||
private int mNextOrder = 0;
|
||||
|
||||
private UsageBarPreference mGraph;
|
||||
private StorageItemPreference mTotal;
|
||||
private StorageItemPreference mAvailable;
|
||||
private StorageSummaryPreference mSummary;
|
||||
private StorageItemPreference mApps;
|
||||
private StorageItemPreference mDcim;
|
||||
private StorageItemPreference mMusic;
|
||||
private StorageItemPreference mDownloads;
|
||||
private StorageItemPreference mImages;
|
||||
private StorageItemPreference mVideos;
|
||||
private StorageItemPreference mAudio;
|
||||
private StorageItemPreference mOther;
|
||||
private StorageItemPreference mCache;
|
||||
private StorageItemPreference mMisc;
|
||||
private List<StorageItemPreference> mUsers = Lists.newArrayList();
|
||||
|
||||
private long mTotalSize;
|
||||
private long mAvailSize;
|
||||
private Preference mExplore;
|
||||
|
||||
@Override
|
||||
protected int getMetricsCategory() {
|
||||
@@ -136,28 +138,26 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
|
||||
mMeasure = new StorageMeasurement(context, mVolume, mSharedVolume);
|
||||
mMeasure.setReceiver(mReceiver);
|
||||
|
||||
mGraph = buildGraph();
|
||||
mTotal = buildItem(R.string.memory_size, 0);
|
||||
mAvailable = buildItem(R.string.memory_available, R.color.memory_avail);
|
||||
mSummary = new StorageSummaryPreference(context);
|
||||
|
||||
mApps = buildItem(R.string.memory_apps_usage, R.color.memory_apps_usage);
|
||||
mDcim = buildItem(R.string.memory_dcim_usage, R.color.memory_dcim);
|
||||
mMusic = buildItem(R.string.memory_music_usage, R.color.memory_music);
|
||||
mDownloads = buildItem(R.string.memory_downloads_usage, R.color.memory_downloads);
|
||||
mCache = buildItem(R.string.memory_media_cache_usage, R.color.memory_cache);
|
||||
mMisc = buildItem(R.string.memory_media_misc_usage, R.color.memory_misc);
|
||||
mApps = buildItem(R.string.storage_detail_apps);
|
||||
mImages = buildItem(R.string.storage_detail_images);
|
||||
mVideos = buildItem(R.string.storage_detail_videos);
|
||||
mAudio = buildItem(R.string.storage_detail_audio);
|
||||
mOther = buildItem(R.string.storage_detail_other);
|
||||
mCache = buildItem(R.string.storage_detail_cached);
|
||||
|
||||
mCurrentUser = mUserManager.getUserInfo(UserHandle.myUserId());
|
||||
final List<UserInfo> otherUsers = getUsersExcluding(mCurrentUser);
|
||||
for (int i = 0; i < otherUsers.size(); i++) {
|
||||
final UserInfo user = otherUsers.get(i);
|
||||
final int colorRes = i % 2 == 0 ? R.color.memory_user_light
|
||||
: R.color.memory_user_dark;
|
||||
final StorageItemPreference userPref = new StorageItemPreference(
|
||||
context, user.name, colorRes, user.id);
|
||||
context, user.name, user.id);
|
||||
mUsers.add(userPref);
|
||||
}
|
||||
|
||||
mExplore = buildAction(R.string.storage_menu_explore);
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@@ -178,22 +178,25 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
|
||||
return;
|
||||
}
|
||||
|
||||
screen.addPreference(mGraph);
|
||||
screen.addPreference(mTotal);
|
||||
screen.addPreference(mAvailable);
|
||||
screen.addPreference(mSummary);
|
||||
|
||||
final boolean showUsers = !mUsers.isEmpty();
|
||||
final boolean showShared = (mSharedVolume != null) && mSharedVolume.isMountedReadable();
|
||||
|
||||
if (showUsers) {
|
||||
screen.addPreference(new PreferenceHeader(context, mCurrentUser.name));
|
||||
}
|
||||
|
||||
screen.addPreference(mApps);
|
||||
screen.addPreference(mDcim);
|
||||
screen.addPreference(mMusic);
|
||||
screen.addPreference(mDownloads);
|
||||
if (showShared) {
|
||||
screen.addPreference(mImages);
|
||||
screen.addPreference(mVideos);
|
||||
screen.addPreference(mAudio);
|
||||
screen.addPreference(mOther);
|
||||
}
|
||||
screen.addPreference(mCache);
|
||||
screen.addPreference(mMisc);
|
||||
|
||||
if (showShared) {
|
||||
screen.addPreference(mExplore);
|
||||
}
|
||||
if (showUsers) {
|
||||
screen.addPreference(new PreferenceHeader(context, R.string.storage_other_users));
|
||||
for (Preference pref : mUsers) {
|
||||
@@ -209,29 +212,29 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
|
||||
}
|
||||
|
||||
final File file = mVolume.getPath();
|
||||
mTotalSize = file.getTotalSpace();
|
||||
mAvailSize = file.getFreeSpace();
|
||||
final long totalBytes = file.getTotalSpace();
|
||||
final long freeBytes = file.getFreeSpace();
|
||||
final long usedBytes = totalBytes - freeBytes;
|
||||
|
||||
mTotal.setSummary(Formatter.formatFileSize(context, mTotalSize));
|
||||
mAvailable.setSummary(Formatter.formatFileSize(context, mAvailSize));
|
||||
|
||||
mGraph.clear();
|
||||
mGraph.addEntry(0, (mTotalSize - mAvailSize) / (float) mTotalSize,
|
||||
android.graphics.Color.GRAY);
|
||||
mGraph.commit();
|
||||
final BytesResult result = Formatter.formatBytes(getResources(), usedBytes, 0);
|
||||
mSummary.setTitle(TextUtils.expandTemplate(getText(R.string.storage_size_large),
|
||||
result.value, result.units));
|
||||
mSummary.setSummary(getString(R.string.storage_volume_used,
|
||||
Formatter.formatFileSize(context, totalBytes)));
|
||||
mSummary.setPercent((int) ((usedBytes * 100) / totalBytes));
|
||||
|
||||
mMeasure.forceMeasure();
|
||||
}
|
||||
|
||||
private UsageBarPreference buildGraph() {
|
||||
final UsageBarPreference pref = new UsageBarPreference(getActivity());
|
||||
private StorageItemPreference buildItem(int titleRes) {
|
||||
final StorageItemPreference pref = new StorageItemPreference(getActivity(), titleRes);
|
||||
pref.setOrder(mNextOrder++);
|
||||
return pref;
|
||||
}
|
||||
|
||||
private StorageItemPreference buildItem(int titleRes, int colorRes) {
|
||||
final StorageItemPreference pref = new StorageItemPreference(getActivity(), titleRes,
|
||||
colorRes);
|
||||
private Preference buildAction(int titleRes) {
|
||||
final Preference pref = new Preference(getActivity());
|
||||
pref.setTitle(titleRes);
|
||||
pref.setOrder(mNextOrder++);
|
||||
return pref;
|
||||
}
|
||||
@@ -341,27 +344,40 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
|
||||
intent = Utils.onBuildStartFragmentIntent(getActivity(),
|
||||
ManageApplications.class.getName(), args, null, R.string.apps_storage, null,
|
||||
false);
|
||||
} else if (pref == mDownloads) {
|
||||
intent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS).putExtra(
|
||||
DownloadManager.INTENT_EXTRAS_SORT_BY_SIZE, true);
|
||||
|
||||
} else if (pref == mMusic) {
|
||||
intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("audio/mp3");
|
||||
} else if (pref == mImages) {
|
||||
intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
|
||||
intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "images_root"));
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
|
||||
} else if (pref == mDcim) {
|
||||
intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
|
||||
intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
||||
} else if (pref == mVideos) {
|
||||
intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
|
||||
intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "videos_root"));
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
|
||||
} else if (pref == mAudio) {
|
||||
intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
|
||||
intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root"));
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
|
||||
} else if (pref == mOther) {
|
||||
OtherInfoFragment.show(this, mStorageManager.getBestVolumeDescription(mVolume),
|
||||
mSharedVolume);
|
||||
return true;
|
||||
|
||||
} else if (pref == mCache) {
|
||||
ConfirmClearCacheFragment.show(this);
|
||||
return true;
|
||||
|
||||
} else if (pref == mMisc) {
|
||||
} else if (pref == mExplore) {
|
||||
intent = mSharedVolume.buildBrowseIntent();
|
||||
}
|
||||
|
||||
if (mUsers.contains(pref)) {
|
||||
UserInfoFragment.show(this, pref.getTitle(), pref.getSummary());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (intent != null) {
|
||||
try {
|
||||
startActivity(intent);
|
||||
@@ -381,39 +397,31 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
|
||||
};
|
||||
|
||||
private void updateDetails(MeasurementDetails details) {
|
||||
mGraph.clear();
|
||||
|
||||
updatePreference(mApps, details.appsSize);
|
||||
|
||||
final long dcimSize = totalValues(details.mediaSize, Environment.DIRECTORY_DCIM,
|
||||
final long imagesSize = totalValues(details.mediaSize, Environment.DIRECTORY_DCIM,
|
||||
Environment.DIRECTORY_MOVIES, Environment.DIRECTORY_PICTURES);
|
||||
updatePreference(mDcim, dcimSize);
|
||||
updatePreference(mImages, imagesSize);
|
||||
|
||||
final long musicSize = totalValues(details.mediaSize, Environment.DIRECTORY_MUSIC,
|
||||
final long videosSize = totalValues(details.mediaSize, Environment.DIRECTORY_MOVIES);
|
||||
updatePreference(mVideos, videosSize);
|
||||
|
||||
final long audioSize = totalValues(details.mediaSize, Environment.DIRECTORY_MUSIC,
|
||||
Environment.DIRECTORY_ALARMS, Environment.DIRECTORY_NOTIFICATIONS,
|
||||
Environment.DIRECTORY_RINGTONES, Environment.DIRECTORY_PODCASTS);
|
||||
updatePreference(mMusic, musicSize);
|
||||
|
||||
final long downloadsSize = totalValues(details.mediaSize, Environment.DIRECTORY_DOWNLOADS);
|
||||
updatePreference(mDownloads, downloadsSize);
|
||||
updatePreference(mAudio, audioSize);
|
||||
|
||||
updatePreference(mCache, details.cacheSize);
|
||||
updatePreference(mMisc, details.miscSize);
|
||||
updatePreference(mOther, details.miscSize);
|
||||
|
||||
for (StorageItemPreference userPref : mUsers) {
|
||||
final long userSize = details.usersSize.get(userPref.userHandle);
|
||||
updatePreference(userPref, userSize);
|
||||
}
|
||||
|
||||
mGraph.commit();
|
||||
}
|
||||
|
||||
private void updatePreference(StorageItemPreference pref, long size) {
|
||||
pref.setSummary(Formatter.formatFileSize(getActivity(), size));
|
||||
if (size > 0) {
|
||||
final int order = pref.getOrder();
|
||||
mGraph.addEntry(order, size / (float) mTotalSize, pref.color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -507,11 +515,78 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
|
||||
}
|
||||
}
|
||||
|
||||
public static class OtherInfoFragment extends DialogFragment {
|
||||
public static void show(Fragment parent, String title, VolumeInfo sharedVol) {
|
||||
if (!parent.isAdded()) return;
|
||||
|
||||
final OtherInfoFragment dialog = new OtherInfoFragment();
|
||||
dialog.setTargetFragment(parent, 0);
|
||||
final Bundle args = new Bundle();
|
||||
args.putString(Intent.EXTRA_TITLE, title);
|
||||
args.putParcelable(Intent.EXTRA_INTENT, sharedVol.buildBrowseIntent());
|
||||
dialog.setArguments(args);
|
||||
dialog.show(parent.getFragmentManager(), TAG_OTHER_INFO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Context context = getActivity();
|
||||
|
||||
final String title = getArguments().getString(Intent.EXTRA_TITLE);
|
||||
final Intent intent = getArguments().getParcelable(Intent.EXTRA_INTENT);
|
||||
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setMessage(
|
||||
TextUtils.expandTemplate(getText(R.string.storage_detail_dialog_other), title));
|
||||
|
||||
builder.setPositiveButton(R.string.storage_menu_explore,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
|
||||
return builder.create();
|
||||
}
|
||||
}
|
||||
|
||||
public static class UserInfoFragment extends DialogFragment {
|
||||
public static void show(Fragment parent, CharSequence userLabel, CharSequence userSize) {
|
||||
if (!parent.isAdded()) return;
|
||||
|
||||
final UserInfoFragment dialog = new UserInfoFragment();
|
||||
dialog.setTargetFragment(parent, 0);
|
||||
final Bundle args = new Bundle();
|
||||
args.putCharSequence(Intent.EXTRA_TITLE, userLabel);
|
||||
args.putCharSequence(Intent.EXTRA_SUBJECT, userSize);
|
||||
dialog.setArguments(args);
|
||||
dialog.show(parent.getFragmentManager(), TAG_USER_INFO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Context context = getActivity();
|
||||
|
||||
final CharSequence userLabel = getArguments().getCharSequence(Intent.EXTRA_TITLE);
|
||||
final CharSequence userSize = getArguments().getCharSequence(Intent.EXTRA_SUBJECT);
|
||||
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setMessage(TextUtils.expandTemplate(
|
||||
getText(R.string.storage_detail_dialog_user), userLabel, userSize));
|
||||
|
||||
builder.setPositiveButton(android.R.string.ok, null);
|
||||
|
||||
return builder.create();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog to request user confirmation before clearing all cache data.
|
||||
*/
|
||||
public static class ConfirmClearCacheFragment extends DialogFragment {
|
||||
public static void show(PrivateVolumeSettings parent) {
|
||||
public static void show(Fragment parent) {
|
||||
if (!parent.isAdded()) return;
|
||||
|
||||
final ConfirmClearCacheFragment dialog = new ConfirmClearCacheFragment();
|
||||
|
@@ -30,7 +30,9 @@ import android.os.storage.VolumeRecord;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.text.format.Formatter.BytesResult;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
@@ -58,18 +60,13 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
|
||||
|
||||
private int mNextOrder = 0;
|
||||
|
||||
private UsageBarPreference mGraph;
|
||||
private StorageItemPreference mTotal;
|
||||
private StorageItemPreference mAvailable;
|
||||
private StorageSummaryPreference mSummary;
|
||||
|
||||
private Preference mMount;
|
||||
private Preference mUnmount;
|
||||
private Preference mFormatPublic;
|
||||
private Preference mFormatPrivate;
|
||||
|
||||
private long mTotalSize;
|
||||
private long mAvailSize;
|
||||
|
||||
@Override
|
||||
protected int getMetricsCategory() {
|
||||
return MetricsLogger.DEVICEINFO_STORAGE;
|
||||
@@ -103,9 +100,7 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
|
||||
|
||||
addPreferencesFromResource(R.xml.device_info_storage_volume);
|
||||
|
||||
mGraph = buildGraph();
|
||||
mTotal = buildItem(R.string.memory_size, 0);
|
||||
mAvailable = buildItem(R.string.memory_available, R.color.memory_avail);
|
||||
mSummary = new StorageSummaryPreference(context);
|
||||
|
||||
mMount = buildAction(R.string.storage_menu_mount);
|
||||
mUnmount = buildAction(R.string.storage_menu_unmount);
|
||||
@@ -128,21 +123,19 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
|
||||
}
|
||||
|
||||
if (mVolume.isMountedReadable()) {
|
||||
screen.addPreference(mGraph);
|
||||
screen.addPreference(mTotal);
|
||||
screen.addPreference(mAvailable);
|
||||
screen.addPreference(mSummary);
|
||||
|
||||
final File file = mVolume.getPath();
|
||||
mTotalSize = file.getTotalSpace();
|
||||
mAvailSize = file.getFreeSpace();
|
||||
final long totalBytes = file.getTotalSpace();
|
||||
final long freeBytes = file.getFreeSpace();
|
||||
final long usedBytes = totalBytes - freeBytes;
|
||||
|
||||
mTotal.setSummary(Formatter.formatFileSize(context, mTotalSize));
|
||||
mAvailable.setSummary(Formatter.formatFileSize(context, mAvailSize));
|
||||
|
||||
mGraph.clear();
|
||||
mGraph.addEntry(0, (mTotalSize - mAvailSize) / (float) mTotalSize,
|
||||
android.graphics.Color.GRAY);
|
||||
mGraph.commit();
|
||||
final BytesResult result = Formatter.formatBytes(getResources(), usedBytes, 0);
|
||||
mSummary.setTitle(TextUtils.expandTemplate(getText(R.string.storage_size_large),
|
||||
result.value, result.units));
|
||||
mSummary.setSummary(getString(R.string.storage_volume_used,
|
||||
Formatter.formatFileSize(context, totalBytes)));
|
||||
mSummary.setPercent((int) ((usedBytes * 100) / totalBytes));
|
||||
}
|
||||
|
||||
if (mVolume.getState() == VolumeInfo.STATE_UNMOUNTED) {
|
||||
@@ -157,19 +150,6 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
|
||||
}
|
||||
}
|
||||
|
||||
private UsageBarPreference buildGraph() {
|
||||
final UsageBarPreference pref = new UsageBarPreference(getActivity());
|
||||
pref.setOrder(mNextOrder++);
|
||||
return pref;
|
||||
}
|
||||
|
||||
private StorageItemPreference buildItem(int titleRes, int colorRes) {
|
||||
final StorageItemPreference pref = new StorageItemPreference(getActivity(), titleRes,
|
||||
colorRes);
|
||||
pref.setOrder(mNextOrder++);
|
||||
return pref;
|
||||
}
|
||||
|
||||
private Preference buildAction(int titleRes) {
|
||||
final Preference pref = new Preference(getActivity());
|
||||
pref.setTitle(titleRes);
|
||||
|
@@ -17,52 +17,27 @@
|
||||
package com.android.settings.deviceinfo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.graphics.drawable.shapes.RectShape;
|
||||
import android.os.UserHandle;
|
||||
import android.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
public class StorageItemPreference extends Preference {
|
||||
public final int color;
|
||||
public final int userHandle;
|
||||
|
||||
public StorageItemPreference(Context context, int titleRes, int colorRes) {
|
||||
this(context, context.getText(titleRes), colorRes, UserHandle.USER_NULL);
|
||||
public StorageItemPreference(Context context, int titleRes) {
|
||||
this(context, context.getText(titleRes), UserHandle.USER_NULL);
|
||||
}
|
||||
|
||||
public StorageItemPreference(
|
||||
Context context, CharSequence title, int colorRes, int userHandle) {
|
||||
public StorageItemPreference(Context context, CharSequence title, int userHandle) {
|
||||
super(context);
|
||||
|
||||
if (colorRes != 0) {
|
||||
this.color = context.getColor(colorRes);
|
||||
|
||||
final Resources res = context.getResources();
|
||||
final int width = res.getDimensionPixelSize(R.dimen.device_memory_usage_button_width);
|
||||
final int height = res.getDimensionPixelSize(R.dimen.device_memory_usage_button_height);
|
||||
setIcon(createRectShape(width, height, this.color));
|
||||
} else {
|
||||
this.color = Color.MAGENTA;
|
||||
}
|
||||
|
||||
setTitle(title);
|
||||
setSummary(R.string.memory_calculating_size);
|
||||
|
||||
this.userHandle = userHandle;
|
||||
}
|
||||
|
||||
private static ShapeDrawable createRectShape(int width, int height, int color) {
|
||||
ShapeDrawable shape = new ShapeDrawable(new RectShape());
|
||||
shape.setIntrinsicHeight(height);
|
||||
shape.setIntrinsicWidth(width);
|
||||
shape.getPaint().setColor(color);
|
||||
return shape;
|
||||
}
|
||||
|
||||
public void setLoading() {
|
||||
setSummary(R.string.memory_calculating_size);
|
||||
}
|
||||
|
@@ -23,9 +23,9 @@ import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserManager;
|
||||
import android.os.storage.DiskInfo;
|
||||
import android.os.storage.StorageEventListener;
|
||||
import android.os.storage.StorageManager;
|
||||
@@ -35,6 +35,8 @@ import android.preference.Preference;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.text.format.Formatter.BytesResult;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -45,6 +47,7 @@ import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settings.search.SearchIndexableRaw;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -59,14 +62,24 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
||||
private static final String TAG_VOLUME_UNMOUNTED = "volume_unmounted";
|
||||
private static final String TAG_DISK_INIT = "disk_init";
|
||||
|
||||
// TODO: badging to indicate devices running low on storage
|
||||
static final int COLOR_PUBLIC = Color.parseColor("#ff9e9e9e");
|
||||
static final int COLOR_WARNING = Color.parseColor("#fff4511e");
|
||||
|
||||
static final int[] COLOR_PRIVATE = new int[] {
|
||||
Color.parseColor("#ff26a69a"),
|
||||
Color.parseColor("#ffab47bc"),
|
||||
Color.parseColor("#fff2a600"),
|
||||
Color.parseColor("#ffec407a"),
|
||||
Color.parseColor("#ffc0ca33"),
|
||||
};
|
||||
|
||||
private UserManager mUserManager;
|
||||
private StorageManager mStorageManager;
|
||||
|
||||
private PreferenceCategory mInternalCategory;
|
||||
private PreferenceCategory mExternalCategory;
|
||||
|
||||
private StorageSummaryPreference mInternalSummary;
|
||||
|
||||
@Override
|
||||
protected int getMetricsCategory() {
|
||||
return MetricsLogger.DEVICEINFO_STORAGE;
|
||||
@@ -83,8 +96,6 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
||||
|
||||
final Context context = getActivity();
|
||||
|
||||
mUserManager = context.getSystemService(UserManager.class);
|
||||
|
||||
mStorageManager = context.getSystemService(StorageManager.class);
|
||||
mStorageManager.registerListener(mStorageListener);
|
||||
|
||||
@@ -93,7 +104,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
||||
mInternalCategory = (PreferenceCategory) findPreference("storage_internal");
|
||||
mExternalCategory = (PreferenceCategory) findPreference("storage_external");
|
||||
|
||||
// TODO: if only one volume visible, shortcut into it
|
||||
mInternalSummary = new StorageSummaryPreference(context);
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
@@ -124,14 +135,28 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
||||
mInternalCategory.removeAll();
|
||||
mExternalCategory.removeAll();
|
||||
|
||||
mInternalCategory.addPreference(mInternalSummary);
|
||||
|
||||
int privateCount = 0;
|
||||
long privateUsedBytes = 0;
|
||||
long privateTotalBytes = 0;
|
||||
|
||||
final List<VolumeInfo> volumes = mStorageManager.getVolumes();
|
||||
Collections.sort(volumes, VolumeInfo.getDescriptionComparator());
|
||||
|
||||
for (VolumeInfo vol : volumes) {
|
||||
if (vol.getType() == VolumeInfo.TYPE_PRIVATE) {
|
||||
mInternalCategory.addPreference(new StorageVolumePreference(context, vol));
|
||||
final int color = COLOR_PRIVATE[privateCount++ % COLOR_PRIVATE.length];
|
||||
mInternalCategory.addPreference(
|
||||
new StorageVolumePreference(context, vol, color));
|
||||
if (vol.isMountedReadable()) {
|
||||
final File path = vol.getPath();
|
||||
privateUsedBytes += path.getTotalSpace() - path.getFreeSpace();
|
||||
privateTotalBytes += path.getTotalSpace();
|
||||
}
|
||||
} else if (vol.getType() == VolumeInfo.TYPE_PUBLIC) {
|
||||
mExternalCategory.addPreference(new StorageVolumePreference(context, vol));
|
||||
mExternalCategory.addPreference(
|
||||
new StorageVolumePreference(context, vol, COLOR_PUBLIC));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,12 +187,28 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
||||
}
|
||||
}
|
||||
|
||||
final BytesResult result = Formatter.formatBytes(getResources(), privateUsedBytes, 0);
|
||||
mInternalSummary.setTitle(TextUtils.expandTemplate(getText(R.string.storage_size_large),
|
||||
result.value, result.units));
|
||||
mInternalSummary.setSummary(getString(R.string.storage_volume_used_total,
|
||||
Formatter.formatFileSize(context, privateTotalBytes)));
|
||||
|
||||
if (mInternalCategory.getPreferenceCount() > 0) {
|
||||
getPreferenceScreen().addPreference(mInternalCategory);
|
||||
}
|
||||
if (mExternalCategory.getPreferenceCount() > 0) {
|
||||
getPreferenceScreen().addPreference(mExternalCategory);
|
||||
}
|
||||
|
||||
if (mInternalCategory.getPreferenceCount() == 2
|
||||
&& mExternalCategory.getPreferenceCount() == 0) {
|
||||
// Only showing primary internal storage, so just shortcut
|
||||
final Bundle args = new Bundle();
|
||||
args.putString(VolumeInfo.EXTRA_VOLUME_ID, VolumeInfo.ID_PRIVATE_INTERNAL);
|
||||
startFragment(this, PrivateVolumeSettings.class.getCanonicalName(),
|
||||
-1, 0, args);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.deviceinfo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.Preference;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
public class StorageSummaryPreference extends Preference {
|
||||
private int mPercent = -1;
|
||||
|
||||
public StorageSummaryPreference(Context context) {
|
||||
super(context);
|
||||
|
||||
setLayoutResource(R.layout.storage_summary);
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
public void setPercent(int percent) {
|
||||
mPercent = percent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(View view) {
|
||||
final ProgressBar progress = (ProgressBar) view.findViewById(android.R.id.progress);
|
||||
if (mPercent != -1) {
|
||||
progress.setVisibility(View.VISIBLE);
|
||||
progress.setProgress(mPercent);
|
||||
} else {
|
||||
progress.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
super.onBindView(view);
|
||||
}
|
||||
}
|
@@ -17,12 +17,17 @@
|
||||
package com.android.settings.deviceinfo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.os.storage.VolumeInfo;
|
||||
import android.preference.Preference;
|
||||
import android.text.format.Formatter;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -38,32 +43,53 @@ public class StorageVolumePreference extends Preference {
|
||||
private final StorageManager mStorageManager;
|
||||
private final VolumeInfo mVolume;
|
||||
|
||||
public StorageVolumePreference(Context context, VolumeInfo volume) {
|
||||
private int mColor;
|
||||
private int mUsedPercent = -1;
|
||||
|
||||
public StorageVolumePreference(Context context, VolumeInfo volume, int color) {
|
||||
super(context);
|
||||
|
||||
mStorageManager = context.getSystemService(StorageManager.class);
|
||||
mVolume = volume;
|
||||
mColor = color;
|
||||
|
||||
setLayoutResource(R.layout.storage_volume);
|
||||
|
||||
setKey(volume.getId());
|
||||
setTitle(mStorageManager.getBestVolumeDescription(volume));
|
||||
|
||||
Drawable icon;
|
||||
if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(volume.getId())) {
|
||||
icon = context.getDrawable(R.drawable.ic_settings_storage);
|
||||
} else {
|
||||
icon = context.getDrawable(R.drawable.ic_sim_sd);
|
||||
}
|
||||
|
||||
if (volume.isMountedReadable()) {
|
||||
// TODO: move statfs() to background thread
|
||||
final File path = volume.getPath();
|
||||
final long usedBytes = path.getTotalSpace() - path.getFreeSpace();
|
||||
final long freeBytes = path.getFreeSpace();
|
||||
final long totalBytes = path.getTotalSpace();
|
||||
final long usedBytes = totalBytes - freeBytes;
|
||||
|
||||
final String used = Formatter.formatFileSize(context, usedBytes);
|
||||
final String total = Formatter.formatFileSize(context, path.getTotalSpace());
|
||||
final String total = Formatter.formatFileSize(context, totalBytes);
|
||||
setSummary(context.getString(R.string.storage_volume_summary, used, total));
|
||||
mUsedPercent = (int) ((usedBytes * 100) / totalBytes);
|
||||
|
||||
if (freeBytes < mStorageManager.getStorageLowBytes(path)) {
|
||||
mColor = StorageSettings.COLOR_WARNING;
|
||||
icon = context.getDrawable(R.drawable.ic_warning_24dp);
|
||||
}
|
||||
|
||||
} else {
|
||||
setSummary(volume.getStateDescription());
|
||||
mUsedPercent = -1;
|
||||
}
|
||||
|
||||
// TODO: better icons
|
||||
if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(volume.getId())) {
|
||||
setIcon(context.getDrawable(R.drawable.ic_settings_storage));
|
||||
} else {
|
||||
setIcon(context.getDrawable(R.drawable.ic_sim_sd));
|
||||
}
|
||||
icon.mutate();
|
||||
icon.setTint(mColor);
|
||||
setIcon(icon);
|
||||
|
||||
if (volume.getType() == VolumeInfo.TYPE_PUBLIC
|
||||
&& volume.isMountedReadable()) {
|
||||
@@ -73,12 +99,21 @@ public class StorageVolumePreference extends Preference {
|
||||
|
||||
@Override
|
||||
protected void onBindView(View view) {
|
||||
final TextView unmount = (TextView) view.findViewById(R.id.unmount);
|
||||
final ImageView unmount = (ImageView) view.findViewById(R.id.unmount);
|
||||
if (unmount != null) {
|
||||
unmount.setText("\u23CF");
|
||||
unmount.getDrawable().setTint(Color.parseColor("#8a000000"));
|
||||
unmount.setOnClickListener(mUnmountListener);
|
||||
}
|
||||
|
||||
final ProgressBar progress = (ProgressBar) view.findViewById(android.R.id.progress);
|
||||
if (mVolume.getType() == VolumeInfo.TYPE_PRIVATE && mUsedPercent != -1) {
|
||||
progress.setVisibility(View.VISIBLE);
|
||||
progress.setProgress(mUsedPercent);
|
||||
progress.setProgressTintList(ColorStateList.valueOf(mColor));
|
||||
} else {
|
||||
progress.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
super.onBindView(view);
|
||||
}
|
||||
|
||||
|
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.deviceinfo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.Preference;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.google.android.collect.Lists;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Creates a percentage bar chart inside a preference.
|
||||
*/
|
||||
public class UsageBarPreference extends Preference {
|
||||
private PercentageBarChart mChart = null;
|
||||
|
||||
private final List<PercentageBarChart.Entry> mEntries = Lists.newArrayList();
|
||||
|
||||
public UsageBarPreference(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public UsageBarPreference(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public UsageBarPreference(Context context, AttributeSet attrs, int defStyle) {
|
||||
this(context, attrs, defStyle, 0);
|
||||
}
|
||||
|
||||
public UsageBarPreference(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
setLayoutResource(R.layout.preference_memoryusage);
|
||||
}
|
||||
|
||||
public void addEntry(int order, float percentage, int color) {
|
||||
mEntries.add(PercentageBarChart.createEntry(order, percentage, color));
|
||||
Collections.sort(mEntries);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(View view) {
|
||||
super.onBindView(view);
|
||||
|
||||
mChart = (PercentageBarChart) view.findViewById(R.id.percentage_bar_chart);
|
||||
mChart.setEntries(mEntries);
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
if (mChart != null) {
|
||||
mChart.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mEntries.clear();
|
||||
}
|
||||
}
|
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.settings.widget;
|
||||
|
||||
import static android.net.TrafficStats.GB_IN_BYTES;
|
||||
import static android.net.TrafficStats.MB_IN_BYTES;
|
||||
|
||||
import android.content.Context;
|
||||
@@ -29,8 +28,11 @@ import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.text.format.Formatter.BytesResult;
|
||||
import android.text.format.Time;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
@@ -533,33 +535,11 @@ public class ChartDataUsageView extends ChartView {
|
||||
|
||||
@Override
|
||||
public long buildLabel(Resources res, SpannableStringBuilder builder, long value) {
|
||||
|
||||
final CharSequence unit;
|
||||
final long unitFactor;
|
||||
if (value < 1000 * MB_IN_BYTES) {
|
||||
unit = res.getText(com.android.internal.R.string.megabyteShort);
|
||||
unitFactor = MB_IN_BYTES;
|
||||
} else {
|
||||
unit = res.getText(com.android.internal.R.string.gigabyteShort);
|
||||
unitFactor = GB_IN_BYTES;
|
||||
}
|
||||
|
||||
final double result = (double) value / unitFactor;
|
||||
final double resultRounded;
|
||||
final CharSequence size;
|
||||
|
||||
if (result < 10) {
|
||||
size = String.format("%.1f", result);
|
||||
resultRounded = (unitFactor * Math.round(result * 10)) / 10;
|
||||
} else {
|
||||
size = String.format("%.0f", result);
|
||||
resultRounded = unitFactor * Math.round(result);
|
||||
}
|
||||
|
||||
setText(builder, sSpanSize, size, "^1");
|
||||
setText(builder, sSpanUnit, unit, "^2");
|
||||
|
||||
return (long) resultRounded;
|
||||
final BytesResult result = Formatter.formatBytes(res, value,
|
||||
Formatter.FLAG_SHORTER | Formatter.FLAG_CALCULATE_ROUNDED);
|
||||
setText(builder, sSpanSize, result.value, "^1");
|
||||
setText(builder, sSpanUnit, result.units, "^2");
|
||||
return result.roundedBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user