Merge pull request #7632 from osmandapp/DataStorageSettings
Data Storage
This commit is contained in:
commit
9545d00aea
17 changed files with 1737 additions and 26 deletions
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/secondary_btn_container"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:layout_marginBottom="@dimen/content_padding_half"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/button_icon"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="@dimen/standard_icon_size"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:src="@drawable/ic_action_folder"
|
||||
android:visibility="visible" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="top"
|
||||
android:orientation="vertical"
|
||||
android:paddingRight="@dimen/content_padding">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/button_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical|start"
|
||||
android:textColor="@color/text_color_primary_dark"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
android:visibility="visible"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="Button" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
|
@ -1,29 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_weight="1">
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_container"
|
||||
<FrameLayout
|
||||
android:id="@+id/secondary_btn_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:ignore="UselessParent">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/button_text"
|
||||
<LinearLayout
|
||||
android:id="@+id/button_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding_small"
|
||||
android:gravity="center"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="Button" />
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
</LinearLayout>
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/button_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding_small"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="Button" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_list_item_height"
|
||||
android:background="@android:drawable/list_selector_background"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/button_icon"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="@dimen/standard_icon_size"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:tint="?attr/active_color_basic"
|
||||
tools:visibility="visible"
|
||||
android:src="@drawable/ic_action_plus"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="top"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/button_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:singleLine="true"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_gravity="center_vertical"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
android:textColor="?attr/active_color_basic"
|
||||
tools:text="Some title" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
64
OsmAnd/res/layout/bottom_sheet_select_folder.xml
Normal file
64
OsmAnd/res/layout/bottom_sheet_select_folder.xml
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<net.osmand.plus.widgets.OsmandTextFieldBoxes
|
||||
android:id="@+id/edit_text_otfb"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dialog_button_ex_height"
|
||||
android:layout_marginTop="@dimen/text_margin_small"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
app:labelText="@string/enter_path_to_folder"
|
||||
app:primaryColor="?android:textColorPrimary"
|
||||
app:secondaryColor="?android:textColorSecondary">
|
||||
|
||||
<studio.carbonylgroup.textfieldboxes.ExtendedEditText
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
tools:text="Folder path ... " />
|
||||
|
||||
</net.osmand.plus.widgets.OsmandTextFieldBoxes>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/subHeaderPadding"
|
||||
android:layout_marginBottom="@dimen/content_padding"
|
||||
android:ellipsize="end"
|
||||
android:linksClickable="true"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_sub_text_size"
|
||||
tools:text="EditText description" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginBottom="@dimen/content_padding_half"
|
||||
android:background="?attr/divider_color" />
|
||||
|
||||
<include
|
||||
android:id="@+id/button"
|
||||
layout="@layout/bottom_sheet_item_btn_with_icon_and_text" />
|
||||
|
||||
</LinearLayout>
|
122
OsmAnd/res/layout/data_storage_list_item.xml
Normal file
122
OsmAnd/res/layout/data_storage_list_item.xml
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/selectable_list_item"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground">
|
||||
|
||||
<LinearLayout
|
||||
android:paddingTop="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding_small"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="@dimen/standard_icon_size"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/mm_storage_tank"
|
||||
android:tint="?attr/default_icon_color"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
tools:text="Internal application memory"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
tools:text="Free 1,34 • 14,6 / 16 Gb"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RadioButton
|
||||
android:id="@android:id/checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:background="@null"
|
||||
android:clickable="true"
|
||||
android:focusable="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/secondPart"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="@dimen/standard_icon_size"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="invisible"
|
||||
android:src="@drawable/mm_storage_tank"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/additionalDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
osmand:typeface="@string/font_roboto_regular"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
tools:text="@string/internal_app_storage_description" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/content_padding">
|
||||
|
||||
<View
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/list_divider"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
|
@ -11,8 +11,17 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
<string name="description_used_gb">Used %1$s GB</string>
|
||||
<string name="used_and_total_space_description">%1$s / %2$s GB</string>
|
||||
<string name="download_detailed_map">Download detailed %s map, to view this area.</string>
|
||||
<string name="shared_string_by_default">By default</string>
|
||||
<string name="enter_path_to_folder">Enter path to the folder</string>
|
||||
<string name="shared_string_select_folder">Select folder</string>
|
||||
<string name="paste_Osmand_data_folder_path">Paste path to the folder with OsmAnd data</string>
|
||||
<string name="change_osmand_data_folder_question">Change OsmAnd data folder?</string>
|
||||
<string name="move_maps_to_new_destination">Move to the new destination</string>
|
||||
<string name="internal_app_storage_description">Internal storage, hiden from user and other apps, so noone exept OsmAnd can’t get access to your data</string>
|
||||
<string name="change_data_storage_folder">Change data storage folder</string>
|
||||
<string name="plugins_settings">Plugin settings</string>
|
||||
<string name="logcat_buffer">Logcat buffer</string>
|
||||
<string name="application_profile_changed">Application profile changed to \"%s\"</string>
|
||||
|
|
10
OsmAnd/res/xml/data_storage.xml
Normal file
10
OsmAnd/res/xml/data_storage.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:title="@string/application_dir">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="application_profiles"
|
||||
android:layout="@layout/preference_category_with_descr"
|
||||
android:title="@string/change_data_storage_folder" />
|
||||
|
||||
</PreferenceScreen>
|
|
@ -21,6 +21,7 @@
|
|||
android:layout="@layout/preference_with_descr"
|
||||
android:persistent="false"
|
||||
android:title="@string/application_dir"
|
||||
app:fragment="net.osmand.plus.settings.DataStorageFragment"
|
||||
tools:icon="@drawable/ic_action_folder" />
|
||||
|
||||
<Preference
|
||||
|
|
|
@ -22,6 +22,7 @@ import android.net.Uri;
|
|||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
import android.os.StatFs;
|
||||
import android.support.annotation.AttrRes;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.ColorRes;
|
||||
|
@ -587,6 +588,28 @@ public class AndroidUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static float getFreeSpaceGb(File dir) {
|
||||
if (dir.canRead()) {
|
||||
StatFs fs = new StatFs(dir.getAbsolutePath());
|
||||
return (float) (fs.getBlockSize()) * fs.getAvailableBlocks() / (1 << 30);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static float getTotalSpaceGb(File dir) {
|
||||
if (dir.canRead()) {
|
||||
return (float) (dir.getTotalSpace()) / (1 << 30);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static float getUsedSpaceGb(File dir) {
|
||||
if (dir.canRead()) {
|
||||
return getTotalSpaceGb(dir) - getFreeSpaceGb(dir);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static CharSequence getStyledString(CharSequence baseString, CharSequence stringToInsertAndStyle,
|
||||
CharacterStyle baseStyle, CharacterStyle replaceStyle) {
|
||||
int indexOfPlaceholder = baseString.toString().indexOf(STRING_PLACEHOLDER);
|
||||
|
|
|
@ -324,35 +324,54 @@ public class UiUtilities {
|
|||
}
|
||||
|
||||
public static void setupDialogButton(boolean nightMode, View buttonView, DialogButtonType buttonType, CharSequence buttonText) {
|
||||
setupDialogButton(nightMode, buttonView, buttonType, buttonText, -1);
|
||||
}
|
||||
|
||||
public static void setupDialogButton(boolean nightMode, View buttonView, DialogButtonType buttonType, CharSequence buttonText, int iconResId) {
|
||||
Context ctx = buttonView.getContext();
|
||||
TextViewEx buttonTextView = (TextViewEx) buttonView.findViewById(R.id.button_text);
|
||||
boolean v21 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
|
||||
View buttonContainer = buttonView.findViewById(R.id.button_container);
|
||||
View secondaryBtnContainer = buttonView.findViewById(R.id.secondary_btn_container);
|
||||
|
||||
int iconAndTextNormalColor = -1;
|
||||
int iconAndTextPressedColor = -1;
|
||||
|
||||
switch (buttonType) {
|
||||
case PRIMARY:
|
||||
if (v21) {
|
||||
AndroidUtils.setBackground(ctx, buttonContainer, nightMode, R.drawable.ripple_solid_light, R.drawable.ripple_solid_dark);
|
||||
}
|
||||
AndroidUtils.setBackground(ctx, buttonView, nightMode, R.drawable.dlg_btn_primary_light, R.drawable.dlg_btn_primary_dark);
|
||||
buttonTextView.setTextColor(ContextCompat.getColorStateList(ctx, nightMode ? R.color.dlg_btn_primary_text_dark : R.color.dlg_btn_primary_text_light));
|
||||
AndroidUtils.setBackground(ctx, secondaryBtnContainer, nightMode, R.drawable.dlg_btn_primary_light, R.drawable.dlg_btn_primary_dark);
|
||||
iconAndTextNormalColor = nightMode ? R.color.dlg_btn_primary_text_dark : R.color.dlg_btn_primary_text_light;
|
||||
iconAndTextPressedColor = iconAndTextNormalColor;
|
||||
break;
|
||||
case SECONDARY:
|
||||
if (v21) {
|
||||
AndroidUtils.setBackground(ctx, buttonContainer, nightMode, R.drawable.ripple_solid_light, R.drawable.ripple_solid_dark);
|
||||
}
|
||||
AndroidUtils.setBackground(ctx, buttonView, nightMode, R.drawable.dlg_btn_secondary_light, R.drawable.dlg_btn_secondary_dark);
|
||||
buttonTextView.setTextColor(ContextCompat.getColorStateList(ctx, nightMode ? R.color.dlg_btn_secondary_text_dark : R.color.dlg_btn_secondary_text_light));
|
||||
AndroidUtils.setBackground(ctx, secondaryBtnContainer, nightMode, R.drawable.dlg_btn_secondary_light, R.drawable.dlg_btn_secondary_dark);
|
||||
iconAndTextNormalColor = nightMode ? R.color.dlg_btn_secondary_text_dark : R.color.dlg_btn_secondary_text_light;
|
||||
iconAndTextPressedColor = nightMode ? R.color.dlg_btn_primary_text_dark : R.color.dlg_btn_primary_text_light;
|
||||
break;
|
||||
case STROKED:
|
||||
if (v21) {
|
||||
AndroidUtils.setBackground(ctx, buttonContainer, nightMode, R.drawable.ripple_light, R.drawable.ripple_dark);
|
||||
}
|
||||
AndroidUtils.setBackground(ctx, buttonView, nightMode, R.drawable.dlg_btn_stroked_light, R.drawable.dlg_btn_stroked_dark);
|
||||
buttonTextView.setTextColor(ContextCompat.getColorStateList(ctx, nightMode ? R.color.dlg_btn_secondary_text_dark : R.color.dlg_btn_secondary_text_light));
|
||||
AndroidUtils.setBackground(ctx, secondaryBtnContainer, nightMode, R.drawable.dlg_btn_stroked_light, R.drawable.dlg_btn_stroked_dark);
|
||||
iconAndTextNormalColor = nightMode ? R.color.dlg_btn_secondary_text_dark : R.color.dlg_btn_secondary_text_light;
|
||||
iconAndTextPressedColor = nightMode ? R.color.dlg_btn_primary_text_dark : R.color.dlg_btn_primary_text_light;
|
||||
break;
|
||||
}
|
||||
buttonTextView.setText(buttonText);
|
||||
buttonTextView.setTextColor(ContextCompat.getColorStateList(ctx, iconAndTextNormalColor));
|
||||
buttonTextView.setEnabled(buttonView.isEnabled());
|
||||
if (iconResId != -1) {
|
||||
Drawable iconNormal = tintDrawable(ContextCompat.getDrawable(ctx, iconResId), ContextCompat.getColor(ctx, iconAndTextNormalColor));
|
||||
Drawable iconPressed = tintDrawable(ContextCompat.getDrawable(ctx, iconResId), ContextCompat.getColor(ctx, iconAndTextPressedColor));
|
||||
ImageView img = buttonView.findViewById(R.id.button_icon);
|
||||
img.setImageDrawable(AndroidUtils.createPressedStateListDrawable(iconNormal, iconPressed));
|
||||
}
|
||||
}
|
||||
|
||||
public static Context getThemedContext(Context context, boolean nightMode) {
|
||||
|
|
|
@ -93,7 +93,8 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
|
|||
VOICE_ANNOUNCES(VoiceAnnouncesFragment.class.getName(), true, R.xml.voice_announces, R.layout.profile_preference_toolbar_with_switch),
|
||||
VEHICLE_PARAMETERS(VehicleParametersFragment.class.getName(), true, R.xml.vehicle_parameters, R.layout.profile_preference_toolbar),
|
||||
MAP_DURING_NAVIGATION(MapDuringNavigationFragment.class.getName(), true, R.xml.map_during_navigation, R.layout.profile_preference_toolbar),
|
||||
TURN_SCREEN_ON(TurnScreenOnFragment.class.getName(), true, R.xml.turn_screen_on, R.layout.profile_preference_toolbar_with_switch);
|
||||
TURN_SCREEN_ON(TurnScreenOnFragment.class.getName(), true, R.xml.turn_screen_on, R.layout.profile_preference_toolbar_with_switch),
|
||||
DATA_STORAGE(DataStorageFragment.class.getName(), false, R.xml.data_storage, R.layout.global_preference_toolbar);
|
||||
|
||||
public final String fragmentName;
|
||||
public final boolean profileDependent;
|
||||
|
|
566
OsmAnd/src/net/osmand/plus/settings/DataStorageFragment.java
Normal file
566
OsmAnd/src/net/osmand/plus/settings/DataStorageFragment.java
Normal file
|
@ -0,0 +1,566 @@
|
|||
package net.osmand.plus.settings;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.preference.CheckBoxPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.ProgressImplementation;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.OsmandActionBarActivity;
|
||||
import net.osmand.plus.download.DownloadActivity;
|
||||
import net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet;
|
||||
import net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import static net.osmand.plus.settings.DataStorageItemsHolder.INTERNAL_STORAGE;
|
||||
import static net.osmand.plus.settings.DataStorageItemsHolder.MANUALLY_SPECIFIED;
|
||||
import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.CHOSEN_DIRECTORY;
|
||||
import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.MOVE_DATA;
|
||||
import static net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet.PATH_CHANGED;
|
||||
import static net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet.NEW_PATH;
|
||||
|
||||
public class DataStorageFragment extends BaseSettingsFragment {
|
||||
|
||||
private final static String CHANGE_DIRECTORY_BUTTON = "change_directory";
|
||||
|
||||
private ArrayList<DataStorageMenuItem> menuItems;
|
||||
private ArrayList<CheckBoxPreference> dataStorageRadioButtonsGroup;
|
||||
private Preference changeButton;
|
||||
private DataStorageMenuItem currentDataStorage;
|
||||
private String tmpManuallySpecifiedPath;
|
||||
private DataStorageItemsHolder itemsHolder;
|
||||
|
||||
private OsmandApplication app;
|
||||
private OsmandActionBarActivity activity;
|
||||
private OsmandSettings settings;
|
||||
|
||||
@Override
|
||||
protected void setupPreferences() {
|
||||
app = getMyApplication();
|
||||
activity = getMyActivity();
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
|
||||
if (screen == null || app == null || activity == null) {
|
||||
return;
|
||||
}
|
||||
settings = app.getSettings();
|
||||
|
||||
itemsHolder = DataStorageItemsHolder.refreshInfo(app);
|
||||
menuItems = itemsHolder.getStorageItems();
|
||||
dataStorageRadioButtonsGroup = new ArrayList<>();
|
||||
|
||||
for (DataStorageMenuItem item : menuItems) {
|
||||
CheckBoxPreference preference = new CheckBoxPreference(activity);
|
||||
preference.setKey(item.getKey());
|
||||
preference.setTitle(item.getTitle());
|
||||
preference.setIcon(item.getIconResId());
|
||||
preference.setLayoutResource(R.layout.data_storage_list_item);
|
||||
screen.addPreference(preference);
|
||||
dataStorageRadioButtonsGroup.add(preference);
|
||||
}
|
||||
|
||||
currentDataStorage = itemsHolder.getCurrentStorage();
|
||||
|
||||
changeButton = new Preference(app);
|
||||
changeButton.setKey(CHANGE_DIRECTORY_BUTTON);
|
||||
changeButton.setLayoutResource(R.layout.bottom_sheet_item_btn_with_icon_and_text);
|
||||
screen.addPreference(changeButton);
|
||||
|
||||
updateView(currentDataStorage.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
if (CHANGE_DIRECTORY_BUTTON.equals(preference.getKey())) {
|
||||
showFolderSelectionDialog();
|
||||
return false;
|
||||
}
|
||||
return super.onPreferenceClick(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
super.onPreferenceChange(preference, newValue);
|
||||
|
||||
if (newValue instanceof Bundle) {
|
||||
//results from BottomSheets
|
||||
Bundle resultData = (Bundle) newValue;
|
||||
if (resultData.containsKey(ChangeDataStorageBottomSheet.TAG)) {
|
||||
boolean moveMaps = resultData.getBoolean(MOVE_DATA);
|
||||
DataStorageMenuItem newDataStorage = resultData.getParcelable(CHOSEN_DIRECTORY);
|
||||
if (newDataStorage != null) {
|
||||
if (tmpManuallySpecifiedPath != null) {
|
||||
String directory = tmpManuallySpecifiedPath;
|
||||
tmpManuallySpecifiedPath = null;
|
||||
newDataStorage.setDirectory(directory);
|
||||
}
|
||||
if (moveMaps) {
|
||||
moveData(currentDataStorage, newDataStorage);
|
||||
} else {
|
||||
confirm(app, activity, newDataStorage, false);
|
||||
}
|
||||
}
|
||||
} else if (resultData.containsKey(SelectFolderBottomSheet.TAG)) {
|
||||
boolean pathChanged = resultData.getBoolean(PATH_CHANGED);
|
||||
if (pathChanged) {
|
||||
tmpManuallySpecifiedPath = resultData.getString(NEW_PATH);
|
||||
if (tmpManuallySpecifiedPath != null) {
|
||||
DataStorageMenuItem manuallySpecified = null;
|
||||
try {
|
||||
manuallySpecified = (DataStorageMenuItem) itemsHolder.getManuallySpecified().clone();
|
||||
manuallySpecified.setDirectory(tmpManuallySpecifiedPath);
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return false;
|
||||
}
|
||||
ChangeDataStorageBottomSheet.showInstance(getFragmentManager(), MANUALLY_SPECIFIED,
|
||||
currentDataStorage, manuallySpecified, this, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//show necessary dialog
|
||||
String key = preference.getKey();
|
||||
if (key != null) {
|
||||
DataStorageMenuItem newDataStorage = itemsHolder.getStorage(key);
|
||||
if (newDataStorage != null) {
|
||||
if (!currentDataStorage.getKey().equals(newDataStorage.getKey())) {
|
||||
if (newDataStorage.getType() == OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT
|
||||
&& !DownloadActivity.hasPermissionToWriteExternalStorage(activity)) {
|
||||
ActivityCompat.requestPermissions(activity,
|
||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||
DownloadActivity.PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
|
||||
} else if (key.equals(MANUALLY_SPECIFIED)) {
|
||||
showFolderSelectionDialog();
|
||||
} else {
|
||||
ChangeDataStorageBottomSheet.showInstance(getFragmentManager(), key,
|
||||
currentDataStorage, newDataStorage, DataStorageFragment.this, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindPreferenceViewHolder(Preference preference, PreferenceViewHolder holder) {
|
||||
super.onBindPreferenceViewHolder(preference, holder);
|
||||
String key = preference.getKey();
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
View itemView = holder.itemView;
|
||||
if (preference instanceof CheckBoxPreference) {
|
||||
DataStorageMenuItem item = itemsHolder.getStorage(key);
|
||||
if (item != null) {
|
||||
TextView tvTitle = itemView.findViewById(android.R.id.title);
|
||||
TextView tvSummary = itemView.findViewById(R.id.summary);
|
||||
TextView tvAdditionalDescription = itemView.findViewById(R.id.additionalDescription);
|
||||
ImageView icon = itemView.findViewById(android.R.id.icon);
|
||||
View divider = itemView.findViewById(R.id.divider);
|
||||
View secondPart = itemView.findViewById(R.id.secondPart);
|
||||
|
||||
tvTitle.setText(item.getTitle());
|
||||
icon.setImageResource(item.getIconResId());
|
||||
|
||||
String currentKey = item.getKey();
|
||||
|
||||
if (currentKey.equals(MANUALLY_SPECIFIED)) {
|
||||
tvSummary.setText(item.getDirectory());
|
||||
secondPart.setVisibility(View.GONE);
|
||||
tvAdditionalDescription.setVisibility(View.GONE);
|
||||
divider.setVisibility(View.GONE);
|
||||
} else {
|
||||
tvAdditionalDescription.setVisibility(View.VISIBLE);
|
||||
divider.setVisibility(View.VISIBLE);
|
||||
secondPart.setVisibility(View.VISIBLE);
|
||||
String space = getSpaceDescription(item.getDirectory());
|
||||
tvSummary.setText(space);
|
||||
if (currentKey.equals(INTERNAL_STORAGE)) {
|
||||
tvAdditionalDescription.setText(item.getDescription());
|
||||
} else {
|
||||
tvAdditionalDescription.setText(item.getDirectory());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (key.equals(CHANGE_DIRECTORY_BUTTON)) {
|
||||
ImageView icon = itemView.findViewById(R.id.button_icon);
|
||||
TextView title = itemView.findViewById(R.id.button_text);
|
||||
int colorResId = isNightMode() ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
|
||||
int color = ContextCompat.getColor(app, colorResId);
|
||||
Drawable drawable = UiUtilities.getColoredSelectableDrawable(app, color, 0.3f);
|
||||
AndroidUtils.setBackground(itemView, drawable);
|
||||
icon.setVisibility(View.INVISIBLE);
|
||||
title.setText(R.string.shared_string_change);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateView(String key) {
|
||||
//selection set up
|
||||
for (CheckBoxPreference preference : dataStorageRadioButtonsGroup) {
|
||||
String preferenceKey = preference.getKey();
|
||||
boolean checked = preferenceKey != null && preferenceKey.equals(key);
|
||||
preference.setChecked(checked);
|
||||
}
|
||||
boolean visible = key.equals(MANUALLY_SPECIFIED);
|
||||
changeButton.setVisible(visible);
|
||||
}
|
||||
|
||||
private void showFolderSelectionDialog() {
|
||||
DataStorageMenuItem manuallySpecified = itemsHolder.getManuallySpecified();
|
||||
if (manuallySpecified != null) {
|
||||
SelectFolderBottomSheet.showInstance(getFragmentManager(), manuallySpecified.getKey(),
|
||||
manuallySpecified.getDirectory(), DataStorageFragment.this,
|
||||
getString(R.string.storage_directory_manual), getString(R.string.paste_Osmand_data_folder_path),
|
||||
getString(R.string.shared_string_select_folder), false);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveData(final DataStorageMenuItem currentStorage, final DataStorageMenuItem newStorage) {
|
||||
File fromDirectory = new File(currentStorage.getDirectory());
|
||||
File toDirectory = new File(newStorage.getDirectory());
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
MoveFilesToDifferentDirectory task = new MoveFilesToDifferentDirectory(activity, fromDirectory, toDirectory) {
|
||||
|
||||
private MessageFormat formatMb = new MessageFormat("{0, number,##.#} MB", Locale.US);
|
||||
|
||||
@NonNull
|
||||
private String getFormattedSize(long sizeBytes) {
|
||||
int size = (int) ((sizeBytes + 512) >> 10);
|
||||
if (size >= 0) {
|
||||
if (size > 100) {
|
||||
return formatMb.format(new Object[]{(float) size / (1 << 10)});
|
||||
} else {
|
||||
return size + " kB";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private void showResultsDialog() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Context ctx = activity.get();
|
||||
if (ctx == null) {
|
||||
return;
|
||||
}
|
||||
int moved = getMovedCount();
|
||||
int copied = getCopiedCount();
|
||||
int failed = getFailedCount();
|
||||
sb.append(ctx.getString(R.string.files_moved, moved, getFormattedSize(getMovedSize()))).append("\n");
|
||||
if (copied > 0) {
|
||||
sb.append(ctx.getString(R.string.files_copied, copied, getFormattedSize(getCopiedSize()))).append("\n");
|
||||
}
|
||||
if (failed > 0) {
|
||||
sb.append(ctx.getString(R.string.files_failed, failed, getFormattedSize(getFailedSize()))).append("\n");
|
||||
}
|
||||
if (copied > 0 || failed > 0) {
|
||||
int count = copied + failed;
|
||||
sb.append(ctx.getString(R.string.files_present, count, getFormattedSize(getCopiedSize() + getFailedSize()), newStorage.getDirectory()));
|
||||
}
|
||||
AlertDialog.Builder bld = new AlertDialog.Builder(ctx);
|
||||
bld.setMessage(sb.toString());
|
||||
bld.setPositiveButton(R.string.shared_string_restart, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
confirm(app, activity.get(), newStorage, true);
|
||||
}
|
||||
});
|
||||
bld.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
super.onPostExecute(result);
|
||||
OsmandActionBarActivity a = this.activity.get();
|
||||
if (a == null) {
|
||||
return;
|
||||
}
|
||||
OsmandApplication app = a.getMyApplication();
|
||||
if (result) {
|
||||
app.getResourceManager().resetStoreDirectory();
|
||||
// immediately proceed with change (to not loose where maps are currently located)
|
||||
if (getCopiedCount() > 0 || getFailedCount() > 0) {
|
||||
showResultsDialog();
|
||||
} else {
|
||||
confirm(app, a, newStorage, false);
|
||||
}
|
||||
} else {
|
||||
showResultsDialog();
|
||||
Toast.makeText(a, R.string.copying_osmand_file_failed,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void confirm(OsmandApplication app, Activity activity, DataStorageMenuItem newStorageDirectory, boolean silentRestart) {
|
||||
String newDirectory = newStorageDirectory.getDirectory();
|
||||
int type = newStorageDirectory.getType();
|
||||
File newDirectoryFile = new File(newDirectory);
|
||||
boolean wr = OsmandSettings.isWritable(newDirectoryFile);
|
||||
if (wr) {
|
||||
app.setExternalStorageDirectory(type, newDirectory);
|
||||
reloadData();
|
||||
if (silentRestart) {
|
||||
android.os.Process.killProcess(android.os.Process.myPid());
|
||||
} else {
|
||||
app.restartApp(activity);
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(activity, R.string.specified_directiory_not_writeable,
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
updateAllSettings();
|
||||
}
|
||||
|
||||
private String getSpaceDescription(String path) {
|
||||
File dir = new File(path);
|
||||
File dirParent = dir.getParentFile();
|
||||
while (!dir.exists() && dirParent != null) {
|
||||
dir = dir.getParentFile();
|
||||
dirParent = dir.getParentFile();
|
||||
}
|
||||
if (dir.exists()) {
|
||||
DecimalFormat formatter = new DecimalFormat("#.##");
|
||||
return new StringBuilder(String.format(getString(R.string.free),
|
||||
String.valueOf(formatter.format(AndroidUtils.getFreeSpaceGb(dir)))))
|
||||
.append(" \u2022 ")
|
||||
.append(formatter.format(AndroidUtils.getUsedSpaceGb(dir)))
|
||||
.append(" / ")
|
||||
.append(formatter.format(AndroidUtils.getTotalSpaceGb(dir)))
|
||||
.append(" Gb")
|
||||
.toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
protected void reloadData() {
|
||||
new ReloadData(activity, getMyApplication()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
|
||||
}
|
||||
|
||||
public static class MoveFilesToDifferentDirectory extends AsyncTask<Void, Void, Boolean> {
|
||||
|
||||
protected WeakReference<OsmandActionBarActivity> activity;
|
||||
private WeakReference<Context> context;
|
||||
private File from;
|
||||
private File to;
|
||||
protected ProgressImplementation progress;
|
||||
private Runnable runOnSuccess;
|
||||
private int movedCount;
|
||||
private long movedSize;
|
||||
private int copiedCount;
|
||||
private long copiedSize;
|
||||
private int failedCount;
|
||||
private long failedSize;
|
||||
|
||||
public MoveFilesToDifferentDirectory(OsmandActionBarActivity activity, File from, File to) {
|
||||
this.activity = new WeakReference<>(activity);
|
||||
this.context = new WeakReference<>((Context) activity);
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
public void setRunOnSuccess(Runnable runOnSuccess) {
|
||||
this.runOnSuccess = runOnSuccess;
|
||||
}
|
||||
|
||||
public int getMovedCount() {
|
||||
return movedCount;
|
||||
}
|
||||
|
||||
public int getCopiedCount() {
|
||||
return copiedCount;
|
||||
}
|
||||
|
||||
public int getFailedCount() {
|
||||
return failedCount;
|
||||
}
|
||||
|
||||
public long getMovedSize() {
|
||||
return movedSize;
|
||||
}
|
||||
|
||||
public long getCopiedSize() {
|
||||
return copiedSize;
|
||||
}
|
||||
|
||||
public long getFailedSize() {
|
||||
return failedSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
Context ctx = context.get();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
movedCount = 0;
|
||||
copiedCount = 0;
|
||||
failedCount = 0;
|
||||
progress = ProgressImplementation.createProgressDialog(
|
||||
ctx, ctx.getString(R.string.copying_osmand_files),
|
||||
ctx.getString(R.string.copying_osmand_files_descr, to.getPath()),
|
||||
ProgressDialog.STYLE_HORIZONTAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (result != null) {
|
||||
Context ctx = context.get();
|
||||
if (ctx == null) {
|
||||
return;
|
||||
}
|
||||
if (result.booleanValue() && runOnSuccess != null) {
|
||||
runOnSuccess.run();
|
||||
} else if (!result.booleanValue()) {
|
||||
Toast.makeText(ctx, R.string.shared_string_io_error, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (progress.getDialog().isShowing()) {
|
||||
progress.getDialog().dismiss();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
//ignored
|
||||
}
|
||||
}
|
||||
|
||||
private void movingFiles(File f, File t, int depth) throws IOException {
|
||||
Context ctx = context.get();
|
||||
if (ctx == null) {
|
||||
return;
|
||||
}
|
||||
if (depth <= 2) {
|
||||
progress.startTask(ctx.getString(R.string.copying_osmand_one_file_descr, t.getName()), -1);
|
||||
}
|
||||
if (f.isDirectory()) {
|
||||
t.mkdirs();
|
||||
File[] lf = f.listFiles();
|
||||
if (lf != null) {
|
||||
for (int i = 0; i < lf.length; i++) {
|
||||
if (lf[i] != null) {
|
||||
movingFiles(lf[i], new File(t, lf[i].getName()), depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
f.delete();
|
||||
} else if (f.isFile()) {
|
||||
if (t.exists()) {
|
||||
Algorithms.removeAllFiles(t);
|
||||
}
|
||||
boolean rnm = false;
|
||||
long fileSize = f.length();
|
||||
try {
|
||||
rnm = f.renameTo(t);
|
||||
movedCount++;
|
||||
movedSize += fileSize;
|
||||
} catch (RuntimeException e) {
|
||||
}
|
||||
if (!rnm) {
|
||||
FileInputStream fin = new FileInputStream(f);
|
||||
FileOutputStream fout = new FileOutputStream(t);
|
||||
try {
|
||||
progress.startTask(ctx.getString(R.string.copying_osmand_one_file_descr, t.getName()), (int) (f.length() / 1024));
|
||||
Algorithms.streamCopy(fin, fout, progress, 1024);
|
||||
copiedCount++;
|
||||
copiedSize += fileSize;
|
||||
} catch (IOException e) {
|
||||
failedCount++;
|
||||
failedSize += fileSize;
|
||||
} finally {
|
||||
fin.close();
|
||||
fout.close();
|
||||
}
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
if (depth <= 2) {
|
||||
progress.finishTask();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
to.mkdirs();
|
||||
try {
|
||||
movingFiles(from, to, 0);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ReloadData extends AsyncTask<Void, Void, Boolean> {
|
||||
private WeakReference<Context> ctx;
|
||||
protected ProgressImplementation progress;
|
||||
private OsmandApplication app;
|
||||
|
||||
public ReloadData(Context ctx, OsmandApplication app) {
|
||||
this.ctx = new WeakReference<>(ctx);
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
Context c = ctx.get();
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
progress = ProgressImplementation.createProgressDialog(c, c.getString(R.string.loading_data),
|
||||
c.getString(R.string.loading_data), ProgressDialog.STYLE_HORIZONTAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
try {
|
||||
if (progress.getDialog().isShowing()) {
|
||||
progress.getDialog().dismiss();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
//ignored
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
app.getResourceManager().reloadIndexes(progress, new ArrayList<String>());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
200
OsmAnd/src/net/osmand/plus/settings/DataStorageItemsHolder.java
Normal file
200
OsmAnd/src/net/osmand/plus/settings/DataStorageItemsHolder.java
Normal file
|
@ -0,0 +1,200 @@
|
|||
package net.osmand.plus.settings;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import net.osmand.ValueHolder;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DataStorageItemsHolder {
|
||||
public final static String INTERNAL_STORAGE = "internal_storage";
|
||||
public final static String EXTERNAL_STORAGE = "external_storage";
|
||||
public final static String SHARED_STORAGE = "shared_storage";
|
||||
public final static String MULTIUSER_STORAGE = "multiuser_storage";
|
||||
public final static String MANUALLY_SPECIFIED = "manually_specified";
|
||||
|
||||
private ArrayList<DataStorageMenuItem> menuItems;
|
||||
private DataStorageMenuItem currentDataStorage;
|
||||
private DataStorageMenuItem manuallySpecified;
|
||||
|
||||
private int currentStorageType;
|
||||
private String currentStoragePath;
|
||||
|
||||
private OsmandApplication app;
|
||||
private OsmandSettings settings;
|
||||
|
||||
private DataStorageItemsHolder(OsmandApplication app) {
|
||||
this.app = app;
|
||||
this.settings = app.getSettings();
|
||||
prepareData();
|
||||
}
|
||||
|
||||
public static DataStorageItemsHolder refreshInfo(OsmandApplication app) {
|
||||
return new DataStorageItemsHolder(app);
|
||||
}
|
||||
|
||||
private void prepareData() {
|
||||
|
||||
if (app == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings.getExternalStorageDirectoryTypeV19() >= 0) {
|
||||
currentStorageType = settings.getExternalStorageDirectoryTypeV19();
|
||||
} else {
|
||||
ValueHolder<Integer> vh = new ValueHolder<Integer>();
|
||||
if (vh.value != null && vh.value >= 0) {
|
||||
currentStorageType = vh.value;
|
||||
} else {
|
||||
currentStorageType = 0;
|
||||
}
|
||||
}
|
||||
currentStoragePath = settings.getExternalStorageDirectory().getAbsolutePath();
|
||||
|
||||
menuItems = new ArrayList<>();
|
||||
|
||||
String path;
|
||||
File dir;
|
||||
int iconId;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
|
||||
//internal storage
|
||||
path = settings.getInternalAppPath().getAbsolutePath();
|
||||
dir = new File(path);
|
||||
iconId = R.drawable.ic_action_phone;
|
||||
|
||||
DataStorageMenuItem internalStorageItem = DataStorageMenuItem.builder()
|
||||
.buildKey(INTERNAL_STORAGE)
|
||||
.buildTitle(getString(R.string.storage_directory_internal_app))
|
||||
.buildDirectory(path)
|
||||
.buildDescription(getString(R.string.internal_app_storage_description))
|
||||
.buildType(OsmandSettings.EXTERNAL_STORAGE_TYPE_INTERNAL_FILE)
|
||||
.buildIconResId(iconId)
|
||||
.build();
|
||||
addItem(internalStorageItem);
|
||||
|
||||
//shared_storage
|
||||
dir = settings.getDefaultInternalStorage();
|
||||
path = dir.getAbsolutePath();
|
||||
iconId = R.drawable.ic_action_phone;
|
||||
|
||||
DataStorageMenuItem sharedStorageItem = DataStorageMenuItem.builder()
|
||||
.buildKey(SHARED_STORAGE)
|
||||
.buildTitle(getString(R.string.storage_directory_shared))
|
||||
.buildDirectory(path)
|
||||
.buildType(OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT)
|
||||
.buildIconResId(iconId)
|
||||
.build();
|
||||
addItem(sharedStorageItem);
|
||||
|
||||
//external storage
|
||||
File[] externals = app.getExternalFilesDirs(null);
|
||||
if (externals != null) {
|
||||
int i = 0;
|
||||
for (File external : externals) {
|
||||
if (external != null) {
|
||||
++i;
|
||||
dir = external;
|
||||
path = dir.getAbsolutePath();
|
||||
iconId = getIconForStorageType(dir);
|
||||
DataStorageMenuItem externalStorageItem = DataStorageMenuItem.builder()
|
||||
.buildKey(EXTERNAL_STORAGE + i)
|
||||
.buildTitle(getString(R.string.storage_directory_external) + " " + i)
|
||||
.buildDirectory(path)
|
||||
.buildType(OsmandSettings.EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE)
|
||||
.buildIconResId(iconId)
|
||||
.build();
|
||||
addItem(externalStorageItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//multi user storage
|
||||
File[] obbDirs = app.getObbDirs();
|
||||
if (obbDirs != null) {
|
||||
int i = 0;
|
||||
for (File obb : obbDirs) {
|
||||
if (obb != null) {
|
||||
++i;
|
||||
dir = obb;
|
||||
path = dir.getAbsolutePath();
|
||||
iconId = getIconForStorageType(dir);
|
||||
DataStorageMenuItem multiuserStorageItem = DataStorageMenuItem.builder()
|
||||
.buildKey(MULTIUSER_STORAGE + i)
|
||||
.buildTitle(getString(R.string.storage_directory_multiuser) + " " + i)
|
||||
.buildDirectory(path)
|
||||
.buildType(OsmandSettings.EXTERNAL_STORAGE_TYPE_OBB)
|
||||
.buildIconResId(iconId)
|
||||
.build();
|
||||
addItem(multiuserStorageItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//manually specified storage
|
||||
manuallySpecified = DataStorageMenuItem.builder()
|
||||
.buildKey(MANUALLY_SPECIFIED)
|
||||
.buildTitle(getString(R.string.storage_directory_manual))
|
||||
.buildDirectory(currentStoragePath)
|
||||
.buildType(OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED)
|
||||
.buildIconResId(R.drawable.ic_action_folder)
|
||||
.build();
|
||||
menuItems.add(manuallySpecified);
|
||||
|
||||
if (currentDataStorage == null) {
|
||||
currentDataStorage = manuallySpecified;
|
||||
}
|
||||
}
|
||||
|
||||
private String getString(int resId) {
|
||||
return app.getString(resId);
|
||||
}
|
||||
|
||||
public ArrayList<DataStorageMenuItem> getStorageItems() {
|
||||
return menuItems;
|
||||
}
|
||||
|
||||
private int getIconForStorageType(File dir) {
|
||||
return R.drawable.ic_action_folder;
|
||||
}
|
||||
|
||||
public DataStorageMenuItem getCurrentStorage() {
|
||||
return currentDataStorage;
|
||||
}
|
||||
|
||||
private void addItem(DataStorageMenuItem item) {
|
||||
if (currentStorageType == item.getType() && currentStoragePath.equals(item.getDirectory())) {
|
||||
currentDataStorage = item;
|
||||
}
|
||||
menuItems.add(item);
|
||||
}
|
||||
|
||||
public DataStorageMenuItem getManuallySpecified() {
|
||||
return manuallySpecified;
|
||||
}
|
||||
|
||||
public DataStorageMenuItem getStorage(String key) {
|
||||
if (menuItems != null && key != null) {
|
||||
for (DataStorageMenuItem menuItem : menuItems) {
|
||||
if (key.equals(menuItem.getKey())) {
|
||||
return menuItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getCurrentType() {
|
||||
return currentStorageType;
|
||||
}
|
||||
|
||||
public String getCurrentPath() {
|
||||
return currentStoragePath;
|
||||
}
|
||||
}
|
169
OsmAnd/src/net/osmand/plus/settings/DataStorageMenuItem.java
Normal file
169
OsmAnd/src/net/osmand/plus/settings/DataStorageMenuItem.java
Normal file
|
@ -0,0 +1,169 @@
|
|||
package net.osmand.plus.settings;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.IdRes;
|
||||
|
||||
public class DataStorageMenuItem implements Parcelable, Cloneable {
|
||||
|
||||
private String key;
|
||||
private int type;
|
||||
private String title;
|
||||
private String description;
|
||||
private String directory;
|
||||
@IdRes
|
||||
private int iconResId;
|
||||
|
||||
private DataStorageMenuItem(String key, int type, String title, String description,
|
||||
String directory, int iconResId) {
|
||||
this.key = key;
|
||||
this.type = type;
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.directory = directory;
|
||||
this.iconResId = iconResId;
|
||||
}
|
||||
|
||||
private DataStorageMenuItem(Parcel in) {
|
||||
key = in.readString();
|
||||
type = in.readInt();
|
||||
title = in.readString();
|
||||
description = in.readString();
|
||||
directory = in.readString();
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getDirectory() {
|
||||
return directory;
|
||||
}
|
||||
|
||||
public int getIconResId() {
|
||||
return iconResId;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public void setDirectory(String directory) {
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
public void setIconResId(int iconResId) {
|
||||
this.iconResId = iconResId;
|
||||
}
|
||||
|
||||
public static DataStorageMenuItemBuilder builder() {
|
||||
return new DataStorageMenuItemBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(key);
|
||||
dest.writeInt(type);
|
||||
dest.writeString(title);
|
||||
dest.writeString(description);
|
||||
dest.writeString(directory);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<DataStorageMenuItem> CREATOR = new Parcelable.Creator<DataStorageMenuItem>() {
|
||||
|
||||
@Override
|
||||
public DataStorageMenuItem createFromParcel(Parcel source) {
|
||||
return new DataStorageMenuItem(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStorageMenuItem[] newArray(int size) {
|
||||
return new DataStorageMenuItem[size];
|
||||
}
|
||||
};
|
||||
|
||||
public static class DataStorageMenuItemBuilder {
|
||||
private String key;
|
||||
private int type;
|
||||
private String title;
|
||||
private String description;
|
||||
private String directory;
|
||||
@IdRes
|
||||
private int iconResId;
|
||||
|
||||
public DataStorageMenuItemBuilder buildKey(String key) {
|
||||
this.key = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataStorageMenuItemBuilder buildType(int type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataStorageMenuItemBuilder buildTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataStorageMenuItemBuilder buildDescription(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataStorageMenuItemBuilder buildDirectory(String directory) {
|
||||
this.directory = directory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataStorageMenuItemBuilder buildIconResId(int iconResId) {
|
||||
this.iconResId = iconResId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataStorageMenuItem build() {
|
||||
return new DataStorageMenuItem(key, type, title, description, directory, iconResId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return DataStorageMenuItem.builder()
|
||||
.buildKey(this.key)
|
||||
.buildTitle(this.title)
|
||||
.buildDescription(this.description)
|
||||
.buildDirectory(this.directory)
|
||||
.buildType(this.type)
|
||||
.buildIconResId(this.iconResId)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import android.support.v7.preference.Preference;
|
|||
import android.support.v7.preference.SwitchPreferenceCompat;
|
||||
import android.util.Pair;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
|
@ -16,6 +17,9 @@ import net.osmand.plus.dialogs.SendAnalyticsBottomSheetDialogFragment;
|
|||
import net.osmand.plus.settings.preferences.ListPreferenceEx;
|
||||
import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
|
||||
public class GlobalSettingsFragment extends BaseSettingsFragment implements SendAnalyticsBottomSheetDialogFragment.OnSendAnalyticsPrefsUpdate, OnPreferenceChanged {
|
||||
|
||||
|
@ -134,9 +138,17 @@ public class GlobalSettingsFragment extends BaseSettingsFragment implements Send
|
|||
}
|
||||
|
||||
private void setupExternalStorageDirPref() {
|
||||
Preference externalStorageDir = (Preference) findPreference(OsmandSettings.EXTERNAL_STORAGE_DIR);
|
||||
Preference externalStorageDir = findPreference(OsmandSettings.EXTERNAL_STORAGE_DIR);
|
||||
externalStorageDir.setIcon(getContentIcon(R.drawable.ic_action_folder));
|
||||
|
||||
DataStorageItemsHolder holder = DataStorageItemsHolder.refreshInfo(app);
|
||||
DataStorageMenuItem currentStorage = holder.getCurrentStorage();
|
||||
File dir = new File(currentStorage.getDirectory());
|
||||
DecimalFormat formatter = new DecimalFormat("#.##");
|
||||
String summary = currentStorage.getTitle() +
|
||||
" \u2022 " +
|
||||
String.format(getString(R.string.description_used_gb),
|
||||
formatter.format(AndroidUtils.getUsedSpaceGb(dir)));
|
||||
externalStorageDir.setSummary(summary);
|
||||
}
|
||||
|
||||
private void setupSendAnonymousDataPref() {
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
package net.osmand.plus.settings.bottomsheets;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
|
||||
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||
import net.osmand.plus.settings.BaseSettingsFragment;
|
||||
import net.osmand.plus.settings.DataStorageMenuItem;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import static net.osmand.plus.settings.DataStorageItemsHolder.MANUALLY_SPECIFIED;
|
||||
|
||||
public class ChangeDataStorageBottomSheet extends BasePreferenceBottomSheet {
|
||||
|
||||
public static final String TAG = "ChangeDataStorageBottomSheet";
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(ChangeDataStorageBottomSheet.class);
|
||||
|
||||
private final static String CURRENT_DIRECTORY = "current_directory";
|
||||
private final static String NEW_DIRECTORY = "new_directory";
|
||||
|
||||
public final static String MOVE_DATA = "move_data";
|
||||
public final static String CHOSEN_DIRECTORY = "chosen_storage";
|
||||
|
||||
private DataStorageMenuItem currentDirectory;
|
||||
private DataStorageMenuItem newDirectory;
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
|
||||
Context ctx = getContext();
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
currentDirectory = savedInstanceState.getParcelable(CURRENT_DIRECTORY);
|
||||
newDirectory = savedInstanceState.getParcelable(NEW_DIRECTORY);
|
||||
}
|
||||
|
||||
if (ctx == null || currentDirectory == null || newDirectory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
items.add(new TitleItem(getString(R.string.change_osmand_data_folder_question)));
|
||||
|
||||
String from = currentDirectory.getKey().equals(MANUALLY_SPECIFIED) ? currentDirectory.getDirectory() : currentDirectory.getTitle();
|
||||
String to = newDirectory.getKey().equals(MANUALLY_SPECIFIED) ? newDirectory.getDirectory() : newDirectory.getTitle();
|
||||
String fullDescription = getString(R.string.application_dir_change_warning3) + "\n" + from + " > " + to;
|
||||
|
||||
SpannableStringBuilder coloredDescription = new SpannableStringBuilder(
|
||||
fullDescription);
|
||||
int startIndexFrom = fullDescription.indexOf(from);
|
||||
int endIndexFrom = startIndexFrom + from.length();
|
||||
int startIndexTo = fullDescription.indexOf(to);
|
||||
int endIndexTo = startIndexTo + to.length();
|
||||
int textColorPrimary = nightMode ? R.color.text_color_primary_dark : R.color.text_color_primary_light;
|
||||
int activeColor = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
|
||||
coloredDescription.setSpan(new ForegroundColorSpan(
|
||||
ContextCompat.getColor(ctx, activeColor)),
|
||||
startIndexFrom, endIndexFrom, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
coloredDescription.setSpan(new ForegroundColorSpan(
|
||||
ContextCompat.getColor(ctx, activeColor)),
|
||||
startIndexTo, endIndexTo, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
BottomSheetItemWithDescription description = (BottomSheetItemWithDescription) new BottomSheetItemWithDescription.Builder()
|
||||
.setDescription(coloredDescription)
|
||||
.setDescriptionColorId(textColorPrimary)
|
||||
.setLayoutId(R.layout.bottom_sheet_item_description_long)
|
||||
.create();
|
||||
items.add(description);
|
||||
|
||||
View spaceView = new FrameLayout(ctx);
|
||||
spaceView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
AndroidUtils.dpToPx(ctx, getResources().getDimension(R.dimen.content_padding))));
|
||||
|
||||
BaseBottomSheetItem space = new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(spaceView)
|
||||
.create();
|
||||
items.add(space);
|
||||
|
||||
//buttons
|
||||
View btnDontMoveView = View.inflate(ctx, R.layout.bottom_sheet_big_dialog_button_with_icon, null);
|
||||
UiUtilities.setupDialogButton(nightMode, btnDontMoveView, UiUtilities.DialogButtonType.SECONDARY,
|
||||
getString(R.string.dont_move_maps), currentDirectory.getIconResId());
|
||||
BaseBottomSheetItem btnDontMove = new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(btnDontMoveView)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
positiveButtonsClick(false);
|
||||
}
|
||||
})
|
||||
.create();
|
||||
items.add(btnDontMove);
|
||||
|
||||
View btnMoveView = View.inflate(ctx, R.layout.bottom_sheet_big_dialog_button_with_icon, null);
|
||||
UiUtilities.setupDialogButton(nightMode, btnMoveView, UiUtilities.DialogButtonType.PRIMARY,
|
||||
getString(R.string.move_maps_to_new_destination), R.drawable.ic_action_folder_move);
|
||||
BaseBottomSheetItem btnMove = new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(btnMoveView)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
positiveButtonsClick(true);
|
||||
}
|
||||
})
|
||||
.create();
|
||||
items.add(btnMove);
|
||||
|
||||
View btnCloseView = View.inflate(ctx, R.layout.bottom_sheet_big_dialog_button_with_icon, null);
|
||||
UiUtilities.setupDialogButton(nightMode, btnCloseView, UiUtilities.DialogButtonType.SECONDARY,
|
||||
getString(R.string.shared_string_cancel), R.drawable.ic_action_undo_dark);
|
||||
BaseBottomSheetItem btnClose = new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(btnCloseView)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
items.add(btnClose);
|
||||
|
||||
View bottomSpaceView = new FrameLayout(ctx);
|
||||
bottomSpaceView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
AndroidUtils.dpToPx(ctx, getResources().getDimension(R.dimen.content_padding_half))));
|
||||
|
||||
BaseBottomSheetItem bottomSpace = new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(bottomSpaceView )
|
||||
.create();
|
||||
items.add(bottomSpace);
|
||||
|
||||
}
|
||||
|
||||
public void setCurrentDirectory(DataStorageMenuItem currentDirectory) {
|
||||
this.currentDirectory = currentDirectory;
|
||||
}
|
||||
|
||||
public void setNewDirectory(DataStorageMenuItem newDirectory) {
|
||||
this.newDirectory = newDirectory;
|
||||
}
|
||||
|
||||
private void positiveButtonsClick(boolean moveData) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(TAG, true);
|
||||
bundle.putParcelable(CHOSEN_DIRECTORY, newDirectory);
|
||||
bundle.putBoolean(MOVE_DATA, moveData);
|
||||
Fragment fragment = getTargetFragment();
|
||||
if (fragment instanceof BaseSettingsFragment) {
|
||||
((BaseSettingsFragment) fragment).onPreferenceChange(getPreference(), bundle);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putParcelable(CURRENT_DIRECTORY, currentDirectory);
|
||||
outState.putParcelable(NEW_DIRECTORY, newDirectory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hideButtonsContainer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean showInstance(FragmentManager fm, String prefId, DataStorageMenuItem currentDirectory,
|
||||
DataStorageMenuItem newDirectory, Fragment target, boolean usedOnMap) {
|
||||
try {
|
||||
if (fm.findFragmentByTag(TAG) == null) {
|
||||
Bundle args = new Bundle();
|
||||
args.putString(PREFERENCE_ID, prefId);
|
||||
|
||||
ChangeDataStorageBottomSheet fragment = new ChangeDataStorageBottomSheet();
|
||||
fragment.setCurrentDirectory(currentDirectory);
|
||||
fragment.setNewDirectory(newDirectory);
|
||||
fragment.setTargetFragment(target, 0);
|
||||
fragment.setUsedOnMap(usedOnMap);
|
||||
fragment.show(fm, TAG);
|
||||
return true;
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
package net.osmand.plus.settings.bottomsheets;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||
import net.osmand.plus.settings.BaseSettingsFragment;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
|
||||
public class SelectFolderBottomSheet extends BasePreferenceBottomSheet {
|
||||
|
||||
public static final String TAG = "SelectFolderBottomSheet";
|
||||
private static final Log LOG = PlatformUtil.getLog(SelectFolderBottomSheet.class);
|
||||
private static final int CHOOSE_FOLDER_REQUEST_CODE = 0;
|
||||
|
||||
private static final String EDIT_TEXT_PREFERENCE_KEY = "edit_text_preference_key";
|
||||
private static final String DIALOG_TITLE = "dialog_title";
|
||||
private static final String DESCRIPTION = "description";
|
||||
private static final String BTN_TITLE = "btn_title";
|
||||
private static final String ET_WAS_FOCUSED = "edit_text_was_focused";
|
||||
public static final String NEW_PATH = "path";
|
||||
public static final String PATH_CHANGED = "changed";
|
||||
|
||||
private EditText editText;
|
||||
|
||||
private String currentPath;
|
||||
private String dialogTitle;
|
||||
private String btnTitle;
|
||||
private String description;
|
||||
private boolean etWasFocused;
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
final Context ctx = getContext();
|
||||
|
||||
String text = null;
|
||||
if (savedInstanceState != null) {
|
||||
String folderPath = savedInstanceState.getString(NEW_PATH);
|
||||
if (folderPath != null) {
|
||||
currentPath = folderPath;
|
||||
}
|
||||
text = savedInstanceState.getString(EDIT_TEXT_PREFERENCE_KEY);
|
||||
dialogTitle = savedInstanceState.getString(DIALOG_TITLE);
|
||||
description = savedInstanceState.getString(DESCRIPTION);
|
||||
btnTitle = savedInstanceState.getString(BTN_TITLE);
|
||||
etWasFocused = savedInstanceState.getBoolean(ET_WAS_FOCUSED);
|
||||
}
|
||||
|
||||
if (ctx == null || currentPath == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dialogTitle != null) {
|
||||
items.add(new TitleItem(dialogTitle));
|
||||
}
|
||||
|
||||
View mainView = View.inflate(ctx, R.layout.bottom_sheet_select_folder, null);
|
||||
|
||||
TextView tvDescription = mainView.findViewById(R.id.description);
|
||||
TextView tvBtnTitle = mainView.findViewById(R.id.title);
|
||||
editText = mainView.findViewById(R.id.text);
|
||||
|
||||
View divider = mainView.findViewById(R.id.divider);
|
||||
View btnOpenChoseDialog = mainView.findViewById(R.id.button);
|
||||
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
// if (btnTitle != null) {
|
||||
// tvBtnTitle.setText(btnTitle);
|
||||
// int colorResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
|
||||
// int color = ContextCompat.getColor(ctx, colorResId);
|
||||
// Drawable drawable = UiUtilities.getColoredSelectableDrawable(ctx, color, 0.3f);
|
||||
// AndroidUtils.setBackground(btnOpenChoseDialog, drawable);
|
||||
// btnOpenChoseDialog.setOnClickListener(new View.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// openDocumentTree();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// } else {
|
||||
divider.setVisibility(GONE);
|
||||
btnOpenChoseDialog.setVisibility(GONE);
|
||||
// }
|
||||
|
||||
if (text != null) {
|
||||
editText.setText(text);
|
||||
}
|
||||
|
||||
if (description != null) {
|
||||
tvDescription.setText(description);
|
||||
}
|
||||
|
||||
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus && !etWasFocused) {
|
||||
etWasFocused = true;
|
||||
editText.setText(currentPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
BaseBottomSheetItem baseItem = new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(mainView)
|
||||
.create();
|
||||
items.add(baseItem);
|
||||
|
||||
}
|
||||
|
||||
public static boolean showInstance(FragmentManager fm, String prefId, String currentPath, Fragment target,
|
||||
String dialogTitle, String description, String btnTitle, boolean usedOnMap) {
|
||||
try {
|
||||
if (fm.findFragmentByTag(TAG) == null) {
|
||||
Bundle args = new Bundle();
|
||||
args.putString(PREFERENCE_ID, prefId);
|
||||
|
||||
SelectFolderBottomSheet fragment = new SelectFolderBottomSheet();
|
||||
fragment.setCurrentPath(currentPath);
|
||||
fragment.setTargetFragment(target, 0);
|
||||
fragment.setDialogTitle(dialogTitle);
|
||||
fragment.setDescription(description);
|
||||
fragment.setBtnTitle(btnTitle);
|
||||
fragment.setUsedOnMap(usedOnMap);
|
||||
fragment.show(fm, TAG);
|
||||
}
|
||||
return true;
|
||||
} catch (RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDismissButtonTextId() {
|
||||
return R.string.shared_string_close;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getRightBottomButtonTextId() {
|
||||
return R.string.shared_string_apply;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRightBottomButtonClick() {
|
||||
Fragment fragment = getTargetFragment();
|
||||
if (fragment instanceof BaseSettingsFragment) {
|
||||
String newPath = editText.getText().toString();
|
||||
if (!newPath.equals("")) {
|
||||
boolean pathChanged = !newPath.equals(currentPath);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(TAG, true);
|
||||
bundle.putString(NEW_PATH, newPath);
|
||||
bundle.putBoolean(PATH_CHANGED, pathChanged);
|
||||
((BaseSettingsFragment) fragment).onPreferenceChange(getPreference(), bundle);
|
||||
}
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(EDIT_TEXT_PREFERENCE_KEY, editText.getText().toString());
|
||||
outState.putString(NEW_PATH, currentPath);
|
||||
outState.putString(DIALOG_TITLE, dialogTitle);
|
||||
outState.putString(DESCRIPTION, description);
|
||||
outState.putString(BTN_TITLE, btnTitle);
|
||||
outState.putBoolean(ET_WAS_FOCUSED, etWasFocused);
|
||||
}
|
||||
|
||||
public void setCurrentPath(String currentPath) {
|
||||
this.currentPath = currentPath;
|
||||
}
|
||||
|
||||
public void setDialogTitle(String dialogTitle) {
|
||||
this.dialogTitle = dialogTitle;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public void setBtnTitle(String btnTitle) {
|
||||
this.btnTitle = btnTitle;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue