Update application dir
This commit is contained in:
parent
e48e1aef9f
commit
ccd966c50b
2 changed files with 383 additions and 379 deletions
|
@ -19,6 +19,7 @@ import net.osmand.plus.OsmandSettings.MetricsConstants;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.Version;
|
import net.osmand.plus.Version;
|
||||||
import net.osmand.plus.dashboard.DashChooseAppDirFragment;
|
import net.osmand.plus.dashboard.DashChooseAppDirFragment;
|
||||||
|
import net.osmand.plus.dashboard.DashChooseAppDirFragment.ChooseAppDirFragment;
|
||||||
import net.osmand.plus.dashboard.DashChooseAppDirFragment.MoveFilesToDifferentDirectory;
|
import net.osmand.plus.dashboard.DashChooseAppDirFragment.MoveFilesToDifferentDirectory;
|
||||||
import net.osmand.plus.download.DownloadActivity;
|
import net.osmand.plus.download.DownloadActivity;
|
||||||
import net.osmand.plus.download.DownloadActivityType;
|
import net.osmand.plus.download.DownloadActivityType;
|
||||||
|
@ -26,8 +27,6 @@ import net.osmand.plus.helpers.FileNameTranslationHelper;
|
||||||
import net.osmand.plus.render.NativeOsmandLibrary;
|
import net.osmand.plus.render.NativeOsmandLibrary;
|
||||||
import net.osmand.plus.voice.CommandPlayer;
|
import net.osmand.plus.voice.CommandPlayer;
|
||||||
import net.osmand.render.RenderingRulesStorage;
|
import net.osmand.render.RenderingRulesStorage;
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.AlertDialog.Builder;
|
import android.app.AlertDialog.Builder;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
|
@ -308,11 +307,11 @@ public class SettingsGeneralActivity extends SettingsBaseActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
|
||||||
public void showAppDirDialog(){
|
public void showAppDirDialog(){
|
||||||
if(Build.VERSION.SDK_INT >= 19) {
|
if(Build.VERSION.SDK_INT >= 19) {
|
||||||
ChooseAppDirDialogFragment newFragment = ChooseAppDirDialogFragment.newInstance();
|
showAppDirDialogV19();
|
||||||
newFragment.show(getFragmentManager(), "dialog");
|
return;
|
||||||
}
|
}
|
||||||
AlertDialog.Builder editalert = new AlertDialog.Builder(SettingsGeneralActivity.this);
|
AlertDialog.Builder editalert = new AlertDialog.Builder(SettingsGeneralActivity.this);
|
||||||
editalert.setTitle(R.string.application_dir);
|
editalert.setTitle(R.string.application_dir);
|
||||||
|
@ -336,34 +335,14 @@ public class SettingsGeneralActivity extends SettingsBaseActivity {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
private void showAppDirDialogV19() {
|
||||||
public static class ChooseAppDirDialogFragment extends android.app.DialogFragment {
|
Builder bld = new AlertDialog.Builder(this);
|
||||||
|
ChooseAppDirFragment frg = new DashChooseAppDirFragment.ChooseAppDirFragment(this, (Dialog) null);
|
||||||
|
bld.setView(frg.initView(getLayoutInflater(), null));
|
||||||
|
AlertDialog dlg = bld.show();
|
||||||
|
frg.setDialog(dlg);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
|
||||||
Bundle args = getArguments();
|
|
||||||
final DashChooseAppDirFragment ssf = new DashChooseAppDirFragment();
|
|
||||||
ssf.setArguments(args);
|
|
||||||
ssf.onAttach(getActivity());
|
|
||||||
AlertDialog dlg = new AlertDialog.Builder(getActivity())
|
|
||||||
.setView(ssf.onCreateView(getActivity().getLayoutInflater(), null, savedInstanceState))
|
|
||||||
.setNegativeButton(R.string.shared_string_cancel, null)
|
|
||||||
.setPositiveButton(R.string.shared_string_ok, new OnClickListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
android.view.View.OnClickListener cf = ssf.getConfirmListener();
|
|
||||||
cf.onClick(null);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.create();
|
|
||||||
return dlg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ChooseAppDirDialogFragment newInstance() {
|
|
||||||
return new ChooseAppDirDialogFragment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void addMiscPreferences(PreferenceGroup misc) {
|
private void addMiscPreferences(PreferenceGroup misc) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import net.osmand.util.Algorithms;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
@ -32,6 +33,7 @@ import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.StatFs;
|
import android.os.StatFs;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.support.v4.app.FragmentActivity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -48,25 +50,12 @@ import android.widget.Toast;
|
||||||
public class DashChooseAppDirFragment extends DashBaseFragment {
|
public class DashChooseAppDirFragment extends DashBaseFragment {
|
||||||
|
|
||||||
public static final String TAG = "DASH_CHOOSE_APP_DIR_FRAGMENT";
|
public static final String TAG = "DASH_CHOOSE_APP_DIR_FRAGMENT";
|
||||||
public static final int VERSION_DEFAULTLOCATION_CHANGED = 19;
|
private ChooseAppDirFragment fragment;
|
||||||
private TextView locationPath;
|
|
||||||
private TextView locationDesc;
|
|
||||||
MessageFormat formatGb = new MessageFormat("{0, number,#.##} GB", Locale.US);
|
|
||||||
private View copyMapsBtn;
|
|
||||||
private ImageView editBtn;
|
|
||||||
private View confirmBtn;
|
|
||||||
private boolean mapsCopied = false;
|
|
||||||
private TextView warningReadonly;
|
|
||||||
private int type = -1;
|
|
||||||
private File selectedFile = new File("/");
|
|
||||||
private File currentAppFile;
|
|
||||||
private OsmandSettings settings;
|
|
||||||
private Activity activity;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Activity activity) {
|
public void onAttach(Activity activity) {
|
||||||
super.onAttach(activity);
|
super.onAttach(activity);
|
||||||
this.activity = activity;
|
fragment = new ChooseAppDirFragment(activity, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,348 +66,355 @@ public class DashChooseAppDirFragment extends DashBaseFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
return initView(inflater, container);
|
return fragment.initView(inflater, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFreeSpace(File dir) {
|
|
||||||
if(dir.canRead()){
|
|
||||||
StatFs fs = new StatFs(dir.getAbsolutePath());
|
|
||||||
return formatGb.format(new Object[]{(float) (fs.getAvailableBlocks()) * fs.getBlockSize() / (1 << 30) });
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateView() {
|
|
||||||
if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT ) {
|
|
||||||
locationPath.setText(R.string.storage_directory_default);
|
|
||||||
} else if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE) {
|
|
||||||
locationPath.setText(R.string.storage_directory_external);
|
|
||||||
} else if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_OBB) {
|
|
||||||
locationPath.setText(R.string.storage_directory_multiuser);
|
|
||||||
} else if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED) {
|
|
||||||
locationPath.setText(R.string.storage_directory_manual);
|
|
||||||
} else if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED) {
|
|
||||||
locationPath.setText(R.string.storage_directory_manual);
|
|
||||||
}
|
|
||||||
locationDesc.setText(selectedFile.getAbsolutePath() + " \u2022 " + getFreeSpace(selectedFile));
|
|
||||||
boolean copyFiles = !currentAppFile.getAbsolutePath().equals(selectedFile.getAbsolutePath()) &&
|
|
||||||
!mapsCopied;
|
|
||||||
if (copyFiles) {
|
|
||||||
copyFiles = false;
|
|
||||||
File[] lf = currentAppFile.listFiles();
|
|
||||||
if (lf != null) {
|
|
||||||
for (File f : lf) {
|
|
||||||
if (f != null) {
|
|
||||||
if (f.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) {
|
|
||||||
copyFiles = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
warningReadonly.setVisibility(copyFiles ? View.VISIBLE : View.GONE);
|
|
||||||
if(copyFiles) {
|
|
||||||
if(OsmandSettings.isWritable(currentAppFile)) {
|
|
||||||
warningReadonly.setText(getString(R.string.android_19_location_disabled, currentAppFile.getAbsolutePath()));
|
|
||||||
} else {
|
|
||||||
warningReadonly.setText(getString(R.string.application_dir_change_warning3));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copyMapsBtn.setVisibility(copyFiles ? View.VISIBLE : View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public View initView(LayoutInflater inflater, ViewGroup container) {
|
|
||||||
View view = inflater.inflate(R.layout.dash_storage_type_fragment, container, false);
|
|
||||||
settings = getMyApplication().getSettings();
|
|
||||||
locationPath = (TextView) view.findViewById(R.id.location_path);
|
|
||||||
locationDesc = (TextView) view.findViewById(R.id.location_desc);
|
|
||||||
warningReadonly = (TextView) view.findViewById(R.id.android_19_location_changed);
|
|
||||||
currentAppFile = settings.getExternalStorageDirectory();
|
|
||||||
selectedFile = currentAppFile;
|
|
||||||
if (settings.getExternalStorageDirectoryTypeV19() >= 0) {
|
|
||||||
type = settings.getExternalStorageDirectoryTypeV19();
|
|
||||||
} else {
|
|
||||||
ValueHolder<Integer> vh = new ValueHolder<Integer>();
|
|
||||||
settings.getExternalStorageDirectory(vh);
|
|
||||||
if (vh.value != null && vh.value >= 0) {
|
|
||||||
type = vh.value;
|
|
||||||
} else {
|
|
||||||
type = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
editBtn = (ImageView) view.findViewById(R.id.edit_icon);
|
|
||||||
copyMapsBtn = view.findViewById(R.id.copy_maps);
|
|
||||||
confirmBtn = view.findViewById(R.id.confirm);
|
|
||||||
addListeners();
|
|
||||||
updateView();
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
|
||||||
protected void showSelectDialog19() {
|
|
||||||
AlertDialog.Builder editalert = new AlertDialog.Builder(activity);
|
|
||||||
editalert.setTitle(R.string.application_dir);
|
|
||||||
final List<String> items = new ArrayList<String>();
|
|
||||||
final List<String> paths = new ArrayList<String>();
|
|
||||||
final TIntArrayList types = new TIntArrayList();
|
|
||||||
int selected = -1;
|
|
||||||
if(type == OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED) {
|
|
||||||
items.add(getString(R.string.storage_directory_manual));
|
|
||||||
paths.add(selectedFile.getAbsolutePath());
|
|
||||||
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED);
|
|
||||||
}
|
|
||||||
File df = settings.getDefaultInternalStorage();
|
|
||||||
if(type == OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT ||
|
|
||||||
OsmandSettings.isWritable(df)) {
|
|
||||||
if(type == OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT) {
|
|
||||||
selected = items.size();
|
|
||||||
}
|
|
||||||
items.add(getString(R.string.storage_directory_default));
|
|
||||||
paths.add(df.getAbsolutePath());
|
|
||||||
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
File[] externals = getMyApplication().getExternalFilesDirs(null);
|
|
||||||
if(externals != null) {
|
|
||||||
int i = 1;
|
|
||||||
for(File external : externals) {
|
|
||||||
if(external != null) {
|
|
||||||
if(selectedFile.getAbsolutePath().equals(external.getAbsolutePath()) ) {
|
|
||||||
selected = items.size();
|
|
||||||
}
|
|
||||||
items.add(getString(R.string.storage_directory_external) + " " + (i++));
|
|
||||||
paths.add(external.getAbsolutePath());
|
|
||||||
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
File[] obbDirs = getMyApplication().getObbDirs();
|
|
||||||
if(obbDirs != null) {
|
|
||||||
int i = 1;
|
|
||||||
for(File obb : obbDirs) {
|
|
||||||
if(obb != null) {
|
|
||||||
if(selectedFile.getAbsolutePath().equals(obb.getAbsolutePath()) ) {
|
|
||||||
selected = items.size();
|
|
||||||
}
|
|
||||||
items.add(getString(R.string.storage_directory_multiuser) + " " + (i++));
|
|
||||||
paths.add(obb.getAbsolutePath());
|
|
||||||
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_OBB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String pth = settings.getInternalAppPath().getAbsolutePath();
|
|
||||||
if(selectedFile.getAbsolutePath().equals(pth) ) {
|
|
||||||
selected = items.size();
|
|
||||||
}
|
|
||||||
items.add(getString(R.string.storage_directory_internal_app));
|
|
||||||
paths.add(pth);
|
|
||||||
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_INTERNAL_FILE);
|
|
||||||
|
|
||||||
items.add(getString(R.string.storage_directory_manual) + getString(R.string.shared_string_ellipsis));
|
|
||||||
paths.add("");
|
|
||||||
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED);
|
|
||||||
|
|
||||||
editalert.setSingleChoiceItems(items.toArray(new String[items.size()]),
|
|
||||||
selected, new DialogInterface.OnClickListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
if (which == items.size() - 1) {
|
|
||||||
dialog.dismiss();
|
|
||||||
showOtherDialog();
|
|
||||||
} else {
|
|
||||||
mapsCopied = false;
|
|
||||||
type = types.get(which);
|
|
||||||
selectedFile = new File(paths.get(which));
|
|
||||||
dialog.dismiss();
|
|
||||||
updateView();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
editalert.setNegativeButton(R.string.shared_string_dismiss, null);
|
|
||||||
editalert.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showOtherDialog(){
|
|
||||||
AlertDialog.Builder editalert = new AlertDialog.Builder(activity);
|
|
||||||
editalert.setTitle(R.string.application_dir);
|
|
||||||
final EditText input = new EditText(activity);
|
|
||||||
input.setText(selectedFile.getAbsolutePath());
|
|
||||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
|
|
||||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
||||||
LinearLayout.LayoutParams.MATCH_PARENT);
|
|
||||||
lp.leftMargin = lp.rightMargin = 5;
|
|
||||||
lp.bottomMargin = lp.topMargin = 5;
|
|
||||||
input.setLayoutParams(lp);
|
|
||||||
settings.getExternalStorageDirectory().getAbsolutePath();
|
|
||||||
editalert.setView(input);
|
|
||||||
editalert.setNegativeButton(R.string.shared_string_cancel, null);
|
|
||||||
editalert.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int whichButton) {
|
|
||||||
selectedFile = new File(input.getText().toString());
|
|
||||||
mapsCopied = false;
|
|
||||||
updateView();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
editalert.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addListeners() {
|
|
||||||
editBtn.setOnClickListener(new View.OnClickListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
|
||||||
showOtherDialog();
|
|
||||||
} else {
|
|
||||||
showSelectDialog19();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
copyMapsBtn.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
MoveFilesToDifferentDirectory task = new MoveFilesToDifferentDirectory(activity, currentAppFile,
|
|
||||||
selectedFile) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Boolean result) {
|
|
||||||
super.onPostExecute(result);
|
|
||||||
if (result) {
|
|
||||||
mapsCopied = true;
|
|
||||||
getMyApplication().getResourceManager().resetStoreDirectory();
|
|
||||||
} else {
|
|
||||||
AccessibleToast.makeText(activity, R.string.copying_osmand_file_failed, Toast.LENGTH_SHORT)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
updateView();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
task.execute();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
confirmBtn.setOnClickListener(getConfirmListener());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public OnClickListener getConfirmListener() {
|
|
||||||
return new View.OnClickListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
boolean wr = OsmandSettings.isWritable(selectedFile);
|
|
||||||
if(wr) {
|
|
||||||
boolean changed = !currentAppFile.getAbsolutePath().equals(selectedFile.getAbsolutePath());
|
|
||||||
getMyApplication().setExternalStorageDirectory(type, selectedFile.getAbsolutePath());
|
|
||||||
if(changed) {
|
|
||||||
reloadData();
|
|
||||||
}
|
|
||||||
if (activity instanceof FragmentActivity) {
|
|
||||||
((FragmentActivity)activity).getSupportFragmentManager().beginTransaction().remove(DashChooseAppDirFragment.this)
|
|
||||||
.commit();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
AccessibleToast.makeText(activity, R.string.specified_directiory_not_writeable,
|
|
||||||
Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void reloadData() {
|
|
||||||
new ReloadData(activity, getMyApplication()).execute((Void)null );
|
|
||||||
}
|
|
||||||
|
|
||||||
public OsmandApplication getMyApplication(){
|
|
||||||
if (activity == null){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (OsmandApplication) activity.getApplication();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ReloadData extends AsyncTask<Void, Void, Boolean> {
|
|
||||||
private Context ctx;
|
|
||||||
protected ProgressImplementation progress;
|
|
||||||
private OsmandApplication app;
|
|
||||||
|
|
||||||
public ReloadData(Context ctx, OsmandApplication app) {
|
|
||||||
this.ctx = ctx;
|
|
||||||
this.app = app;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPreExecute() {
|
|
||||||
progress = ProgressImplementation.createProgressDialog(ctx, ctx.getString(R.string.loading_data),
|
|
||||||
ctx.getString(R.string.loading_data), ProgressDialog.STYLE_HORIZONTAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Boolean result) {
|
|
||||||
if (progress.getDialog().isShowing()) {
|
|
||||||
progress.getDialog().dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Boolean doInBackground(Void... params) {
|
|
||||||
app.getResourceManager().reloadIndexes(progress, new ArrayList<String>());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isDashNeeded(OsmandSettings settings) {
|
public static boolean isDashNeeded(OsmandSettings settings) {
|
||||||
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO
|
return !settings.isExternalStorageDirectorySpecifiedV19();
|
||||||
return true;
|
|
||||||
// return !settings.isExternalStorageDirectorySpecifiedV19();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HashSet<String> getExternalMounts() {
|
|
||||||
final HashSet<String> out = new HashSet<String>();
|
|
||||||
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
|
|
||||||
String s = "";
|
|
||||||
try {
|
|
||||||
final Process process = new ProcessBuilder().command("mount")
|
|
||||||
.redirectErrorStream(true).start();
|
|
||||||
process.waitFor();
|
|
||||||
final InputStream is = process.getInputStream();
|
|
||||||
final byte[] buffer = new byte[1024];
|
|
||||||
while (is.read(buffer) != -1) {
|
|
||||||
s = s + new String(buffer);
|
|
||||||
}
|
|
||||||
is.close();
|
|
||||||
} catch (final Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse output
|
|
||||||
final String[] lines = s.split("\n");
|
|
||||||
for (String line : lines) {
|
|
||||||
if (!line.toLowerCase(Locale.US).contains("asec")) {
|
|
||||||
if (line.matches(reg)) {
|
|
||||||
String[] parts = line.split(" ");
|
|
||||||
for (String part : parts) {
|
|
||||||
if (part.startsWith("/"))
|
|
||||||
if (!part.toLowerCase(Locale.US).contains("vold"))
|
|
||||||
out.add(part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class ChooseAppDirFragment {
|
||||||
|
public static final int VERSION_DEFAULTLOCATION_CHANGED = 19;
|
||||||
|
private TextView locationPath;
|
||||||
|
private TextView locationDesc;
|
||||||
|
MessageFormat formatGb = new MessageFormat("{0, number,#.##} GB", Locale.US);
|
||||||
|
private View copyMapsBtn;
|
||||||
|
private ImageView editBtn;
|
||||||
|
private View confirmBtn;
|
||||||
|
private boolean mapsCopied = false;
|
||||||
|
private TextView warningReadonly;
|
||||||
|
private int type = -1;
|
||||||
|
private File selectedFile = new File("/");
|
||||||
|
private File currentAppFile;
|
||||||
|
private OsmandSettings settings;
|
||||||
|
private Activity activity;
|
||||||
|
private Fragment fragment;
|
||||||
|
private Dialog dlg;
|
||||||
|
|
||||||
|
public ChooseAppDirFragment(Activity activity, Fragment f) {
|
||||||
|
this.activity = activity;
|
||||||
|
this.fragment = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChooseAppDirFragment(Activity activity, Dialog dlg) {
|
||||||
|
this.activity = activity;
|
||||||
|
this.dlg = dlg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFreeSpace(File dir) {
|
||||||
|
if (dir.canRead()) {
|
||||||
|
StatFs fs = new StatFs(dir.getAbsolutePath());
|
||||||
|
return formatGb
|
||||||
|
.format(new Object[] { (float) (fs.getAvailableBlocks()) * fs.getBlockSize() / (1 << 30) });
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateView() {
|
||||||
|
if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT) {
|
||||||
|
locationPath.setText(R.string.storage_directory_default);
|
||||||
|
} else if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE) {
|
||||||
|
locationPath.setText(R.string.storage_directory_external);
|
||||||
|
} else if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_OBB) {
|
||||||
|
locationPath.setText(R.string.storage_directory_multiuser);
|
||||||
|
} else if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED) {
|
||||||
|
locationPath.setText(R.string.storage_directory_manual);
|
||||||
|
} else if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED) {
|
||||||
|
locationPath.setText(R.string.storage_directory_manual);
|
||||||
|
}
|
||||||
|
locationDesc.setText(selectedFile.getAbsolutePath() + " \u2022 " + getFreeSpace(selectedFile));
|
||||||
|
boolean copyFiles = !currentAppFile.getAbsolutePath().equals(selectedFile.getAbsolutePath()) && !mapsCopied;
|
||||||
|
if (copyFiles) {
|
||||||
|
copyFiles = false;
|
||||||
|
File[] lf = currentAppFile.listFiles();
|
||||||
|
if (lf != null) {
|
||||||
|
for (File f : lf) {
|
||||||
|
if (f != null) {
|
||||||
|
if (f.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) {
|
||||||
|
copyFiles = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
warningReadonly.setVisibility(copyFiles ? View.VISIBLE : View.GONE);
|
||||||
|
if (copyFiles) {
|
||||||
|
if (!OsmandSettings.isWritable(currentAppFile)) {
|
||||||
|
warningReadonly.setText(activity.getString(R.string.android_19_location_disabled,
|
||||||
|
currentAppFile.getAbsolutePath()));
|
||||||
|
} else {
|
||||||
|
warningReadonly.setText(getString(R.string.application_dir_change_warning3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
copyMapsBtn.setVisibility(copyFiles ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public View initView(LayoutInflater inflater, ViewGroup container) {
|
||||||
|
View view = inflater.inflate(R.layout.dash_storage_type_fragment, container, false);
|
||||||
|
settings = getMyApplication().getSettings();
|
||||||
|
locationPath = (TextView) view.findViewById(R.id.location_path);
|
||||||
|
locationDesc = (TextView) view.findViewById(R.id.location_desc);
|
||||||
|
warningReadonly = (TextView) view.findViewById(R.id.android_19_location_changed);
|
||||||
|
currentAppFile = settings.getExternalStorageDirectory();
|
||||||
|
selectedFile = currentAppFile;
|
||||||
|
if (settings.getExternalStorageDirectoryTypeV19() >= 0) {
|
||||||
|
type = settings.getExternalStorageDirectoryTypeV19();
|
||||||
|
} else {
|
||||||
|
ValueHolder<Integer> vh = new ValueHolder<Integer>();
|
||||||
|
settings.getExternalStorageDirectory(vh);
|
||||||
|
if (vh.value != null && vh.value >= 0) {
|
||||||
|
type = vh.value;
|
||||||
|
} else {
|
||||||
|
type = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
editBtn = (ImageView) view.findViewById(R.id.edit_icon);
|
||||||
|
copyMapsBtn = view.findViewById(R.id.copy_maps);
|
||||||
|
confirmBtn = view.findViewById(R.id.confirm);
|
||||||
|
addListeners();
|
||||||
|
updateView();
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getString(int string) {
|
||||||
|
return activity.getString(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||||
|
protected void showSelectDialog19() {
|
||||||
|
AlertDialog.Builder editalert = new AlertDialog.Builder(activity);
|
||||||
|
editalert.setTitle(R.string.application_dir);
|
||||||
|
final List<String> items = new ArrayList<String>();
|
||||||
|
final List<String> paths = new ArrayList<String>();
|
||||||
|
final TIntArrayList types = new TIntArrayList();
|
||||||
|
int selected = -1;
|
||||||
|
if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED) {
|
||||||
|
items.add(getString(R.string.storage_directory_manual));
|
||||||
|
paths.add(selectedFile.getAbsolutePath());
|
||||||
|
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED);
|
||||||
|
}
|
||||||
|
File df = settings.getDefaultInternalStorage();
|
||||||
|
if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT || OsmandSettings.isWritable(df)) {
|
||||||
|
if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT) {
|
||||||
|
selected = items.size();
|
||||||
|
}
|
||||||
|
items.add(getString(R.string.storage_directory_default));
|
||||||
|
paths.add(df.getAbsolutePath());
|
||||||
|
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
File[] externals = getMyApplication().getExternalFilesDirs(null);
|
||||||
|
if (externals != null) {
|
||||||
|
int i = 1;
|
||||||
|
for (File external : externals) {
|
||||||
|
if (external != null) {
|
||||||
|
if (selectedFile.getAbsolutePath().equals(external.getAbsolutePath())) {
|
||||||
|
selected = items.size();
|
||||||
|
}
|
||||||
|
items.add(getString(R.string.storage_directory_external) + " " + (i++));
|
||||||
|
paths.add(external.getAbsolutePath());
|
||||||
|
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File[] obbDirs = getMyApplication().getObbDirs();
|
||||||
|
if (obbDirs != null) {
|
||||||
|
int i = 1;
|
||||||
|
for (File obb : obbDirs) {
|
||||||
|
if (obb != null) {
|
||||||
|
if (selectedFile.getAbsolutePath().equals(obb.getAbsolutePath())) {
|
||||||
|
selected = items.size();
|
||||||
|
}
|
||||||
|
items.add(getString(R.string.storage_directory_multiuser) + " " + (i++));
|
||||||
|
paths.add(obb.getAbsolutePath());
|
||||||
|
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_OBB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String pth = settings.getInternalAppPath().getAbsolutePath();
|
||||||
|
if (selectedFile.getAbsolutePath().equals(pth)) {
|
||||||
|
selected = items.size();
|
||||||
|
}
|
||||||
|
items.add(getString(R.string.storage_directory_internal_app));
|
||||||
|
paths.add(pth);
|
||||||
|
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_INTERNAL_FILE);
|
||||||
|
|
||||||
|
items.add(getString(R.string.storage_directory_manual) + getString(R.string.shared_string_ellipsis));
|
||||||
|
paths.add("");
|
||||||
|
types.add(OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED);
|
||||||
|
|
||||||
|
editalert.setSingleChoiceItems(items.toArray(new String[items.size()]), selected,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
if (which == items.size() - 1) {
|
||||||
|
dialog.dismiss();
|
||||||
|
showOtherDialog();
|
||||||
|
} else {
|
||||||
|
mapsCopied = false;
|
||||||
|
type = types.get(which);
|
||||||
|
selectedFile = new File(paths.get(which));
|
||||||
|
dialog.dismiss();
|
||||||
|
updateView();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editalert.setNegativeButton(R.string.shared_string_dismiss, null);
|
||||||
|
editalert.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showOtherDialog() {
|
||||||
|
AlertDialog.Builder editalert = new AlertDialog.Builder(activity);
|
||||||
|
editalert.setTitle(R.string.application_dir);
|
||||||
|
final EditText input = new EditText(activity);
|
||||||
|
input.setText(selectedFile.getAbsolutePath());
|
||||||
|
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT);
|
||||||
|
lp.leftMargin = lp.rightMargin = 5;
|
||||||
|
lp.bottomMargin = lp.topMargin = 5;
|
||||||
|
input.setLayoutParams(lp);
|
||||||
|
settings.getExternalStorageDirectory().getAbsolutePath();
|
||||||
|
editalert.setView(input);
|
||||||
|
editalert.setNegativeButton(R.string.shared_string_cancel, null);
|
||||||
|
editalert.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
selectedFile = new File(input.getText().toString());
|
||||||
|
mapsCopied = false;
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editalert.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addListeners() {
|
||||||
|
editBtn.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
||||||
|
showOtherDialog();
|
||||||
|
} else {
|
||||||
|
showSelectDialog19();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
copyMapsBtn.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
MoveFilesToDifferentDirectory task = new MoveFilesToDifferentDirectory(activity, currentAppFile,
|
||||||
|
selectedFile) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
super.onPostExecute(result);
|
||||||
|
if (result) {
|
||||||
|
mapsCopied = true;
|
||||||
|
getMyApplication().getResourceManager().resetStoreDirectory();
|
||||||
|
} else {
|
||||||
|
AccessibleToast.makeText(activity, R.string.copying_osmand_file_failed,
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
task.execute();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
confirmBtn.setOnClickListener(getConfirmListener());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnClickListener getConfirmListener() {
|
||||||
|
return new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
boolean wr = OsmandSettings.isWritable(selectedFile);
|
||||||
|
if (wr) {
|
||||||
|
boolean changed = !currentAppFile.getAbsolutePath().equals(selectedFile.getAbsolutePath());
|
||||||
|
getMyApplication().setExternalStorageDirectory(type, selectedFile.getAbsolutePath());
|
||||||
|
if (changed) {
|
||||||
|
reloadData();
|
||||||
|
}
|
||||||
|
if (fragment != null && activity instanceof FragmentActivity) {
|
||||||
|
((FragmentActivity) activity).getSupportFragmentManager().beginTransaction()
|
||||||
|
.remove(fragment).commit();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AccessibleToast.makeText(activity, R.string.specified_directiory_not_writeable,
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
if(dlg != null) {
|
||||||
|
dlg.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void reloadData() {
|
||||||
|
new ReloadData(activity, getMyApplication()).execute((Void) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OsmandApplication getMyApplication() {
|
||||||
|
if (activity == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (OsmandApplication) activity.getApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static HashSet<String> getExternalMounts() {
|
||||||
|
final HashSet<String> out = new HashSet<String>();
|
||||||
|
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
|
||||||
|
String s = "";
|
||||||
|
try {
|
||||||
|
final Process process = new ProcessBuilder().command("mount").redirectErrorStream(true).start();
|
||||||
|
process.waitFor();
|
||||||
|
final InputStream is = process.getInputStream();
|
||||||
|
final byte[] buffer = new byte[1024];
|
||||||
|
while (is.read(buffer) != -1) {
|
||||||
|
s = s + new String(buffer);
|
||||||
|
}
|
||||||
|
is.close();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse output
|
||||||
|
final String[] lines = s.split("\n");
|
||||||
|
for (String line : lines) {
|
||||||
|
if (!line.toLowerCase(Locale.US).contains("asec")) {
|
||||||
|
if (line.matches(reg)) {
|
||||||
|
String[] parts = line.split(" ");
|
||||||
|
for (String part : parts) {
|
||||||
|
if (part.startsWith("/"))
|
||||||
|
if (!part.toLowerCase(Locale.US).contains("vold"))
|
||||||
|
out.add(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDialog(Dialog dlg) {
|
||||||
|
this.dlg = dlg;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static class MoveFilesToDifferentDirectory extends AsyncTask<Void, Void, Boolean> {
|
public static class MoveFilesToDifferentDirectory extends AsyncTask<Void, Void, Boolean> {
|
||||||
|
|
||||||
|
@ -514,4 +510,33 @@ public class DashChooseAppDirFragment extends DashBaseFragment {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ReloadData extends AsyncTask<Void, Void, Boolean> {
|
||||||
|
private Context ctx;
|
||||||
|
protected ProgressImplementation progress;
|
||||||
|
private OsmandApplication app;
|
||||||
|
|
||||||
|
public ReloadData(Context ctx, OsmandApplication app) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
progress = ProgressImplementation.createProgressDialog(ctx, ctx.getString(R.string.loading_data),
|
||||||
|
ctx.getString(R.string.loading_data), ProgressDialog.STYLE_HORIZONTAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
if (progress.getDialog().isShowing()) {
|
||||||
|
progress.getDialog().dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean doInBackground(Void... params) {
|
||||||
|
app.getResourceManager().reloadIndexes(progress, new ArrayList<String>());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue