[android] review fixes

This commit is contained in:
ExMix 2014-05-08 12:41:04 +03:00 committed by Alex Zolotarev
parent 0b64872239
commit 63c0f9df1f
9 changed files with 276 additions and 302 deletions

View file

@ -107,6 +107,17 @@ namespace jni
return env->NewStringUTF(s);
}
jclass GetStringClass(JNIEnv * env)
{
static jclass stringClass = env->FindClass(GetStringClassName());
return stringClass;
}
char const * GetStringClassName()
{
return "java/lang/String";
}
JNIEnv * GetEnv()
{
JNIEnv * env;

View file

@ -32,6 +32,9 @@ namespace jni
return ToJavaString(env, s.c_str());
}
jclass GetStringClass(JNIEnv * env);
char const * GetStringClassName();
string DescribeException();
shared_ptr<jobject> make_global_ref(jobject obj);

View file

@ -958,10 +958,9 @@ extern "C"
}
JNIEXPORT jobjectArray JNICALL
Java_com_mapswithme_maps_Framework_nativeGetMovablefilesExt(JNIEnv * env, jclass thiz)
Java_com_mapswithme_maps_Framework_nativeGetMovableFilesExt(JNIEnv * env, jclass thiz)
{
jstring fakeString = jni::ToJavaString(env, "");
jclass stringClass = env->GetObjectClass(fakeString);
jclass stringClass = jni::GetStringClass(env);
string exts[] = { DATA_FILE_EXTENSION, FONT_FILE_EXTENSION};
jobjectArray resultArray = env->NewObjectArray(ARRAY_SIZE(exts), stringClass, NULL);
@ -979,9 +978,9 @@ extern "C"
}
JNIEXPORT void JNICALL
Java_com_mapswithme_maps_Framework_nativeSetWritableDir(JNIEnv * env, jclass thiz, jstring _newPath)
Java_com_mapswithme_maps_Framework_nativeSetWritableDir(JNIEnv * env, jclass thiz, jstring jNewPath)
{
string newPath = jni::ToNativeString(env, _newPath);
string newPath = jni::ToNativeString(env, jNewPath);
g_framework->RemoveLocalMaps();
android::Platform::Instance().SetStoragePath(newPath);
g_framework->AddLocalMaps();

View file

@ -9,9 +9,9 @@ extern "C"
{
JNIEXPORT jstring JNICALL
Java_com_mapswithme_util_StoragePathManager_nativeGenerateUniqueBookmarkName(JNIEnv * env, jclass thiz, jstring _baseName)
Java_com_mapswithme_util_StoragePathManager_nativeGenerateUniqueBookmarkName(JNIEnv * env, jclass thiz, jstring jBaseName)
{
string baseName = jni::ToNativeString(env, _baseName);
string baseName = jni::ToNativeString(env, jBaseName);
string bookmarkFileName = BookmarkCategory::GenerateUniqueFileName(GetPlatform().SettingsDir(), baseName);
return jni::ToJavaString(env, bookmarkFileName);
}

View file

@ -57,10 +57,10 @@ import com.mapswithme.maps.widget.MapInfoView.State;
import com.mapswithme.util.ConnectionState;
import com.mapswithme.util.ShareAction;
import com.mapswithme.util.StoragePathManager;
import com.mapswithme.util.StoragePathManager.SetStoragePathListener;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.Yota;
import com.mapswithme.util.StoragePathManager.SetStoragePathListener;
import com.mapswithme.util.statistics.Statistics;
import com.nvidia.devtech.NvEventQueueActivity;
@ -79,6 +79,7 @@ public class MWMActivity extends NvEventQueueActivity
private MWMApplication mApplication = null;
private BroadcastReceiver m_externalStorageReceiver = null;
private StoragePathManager m_pathManager = new StoragePathManager();
private AlertDialog m_storageDisconnectedDialog = null;
private ImageButton mLocationButton;
@ -117,11 +118,6 @@ public class MWMActivity extends NvEventQueueActivity
{
return mApplication.getLocationState();
}
private StoragePathManager GetPathManager()
{
return mApplication.GetPathManager();
}
private void startLocation()
{
@ -320,7 +316,7 @@ public class MWMActivity extends NvEventQueueActivity
private boolean m_needCheckUpdate = true;
private boolean mRenderingInitialized = false;
private void ShowAlertDlg(int tittleID)
{
new AlertDialog.Builder(this)
@ -334,18 +330,17 @@ public class MWMActivity extends NvEventQueueActivity
.create()
.show();
}
private void checkKitkatMigrationMove()
{
final String KmlMovedFlag = "KmlBeenMoved";
final String KitKatMigrationCompleted = "KitKatMigrationCompleted";
final boolean kmlMoved = MWMApplication.get().nativeGetBoolean(KmlMovedFlag, false);
final boolean mapsCpy = MWMApplication.get().nativeGetBoolean(KitKatMigrationCompleted, false);
StoragePathManager pathManager = mApplication.GetPathManager();
if (!kmlMoved)
{
if (pathManager.MoveBookmarks())
if (m_pathManager.MoveBookmarks())
mApplication.nativeSetBoolean(KmlMovedFlag, true);
else
{
@ -353,7 +348,7 @@ public class MWMActivity extends NvEventQueueActivity
return;
}
}
if (!mapsCpy)
{
SetStoragePathListener listener = new SetStoragePathListener()
@ -364,14 +359,14 @@ public class MWMActivity extends NvEventQueueActivity
mApplication.nativeSetBoolean(KitKatMigrationCompleted, true);
ShowAlertDlg(R.string.kitkat_migrate_ok);
}
@Override
public void MoveFilesFailed()
{
ShowAlertDlg(R.string.kitkat_migrate_failed);
}
};
pathManager.CheckWritableDir(this, listener);
m_pathManager.CheckWritableDir(this, listener);
}
}
@ -1139,7 +1134,7 @@ public class MWMActivity extends NvEventQueueActivity
}
};
GetPathManager().StartExtStorageWatching(this, m_externalStorageReceiver);
m_pathManager.StartExtStorageWatching(this, m_externalStorageReceiver);
updateExternalStorageState();
}
@ -1209,7 +1204,7 @@ public class MWMActivity extends NvEventQueueActivity
private void stopWatchingExternalStorage()
{
GetPathManager().StopExtStorageWatching();
m_pathManager.StopExtStorageWatching();
m_externalStorageReceiver = null;
}

View file

@ -21,7 +21,6 @@ import com.mapswithme.maps.guides.GuideInfo;
import com.mapswithme.maps.guides.GuidesUtils;
import com.mapswithme.maps.location.LocationService;
import com.mapswithme.util.FbUtil;
import com.mapswithme.util.StoragePathManager;
import com.mapswithme.util.Utils;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.SimpleLogger;
@ -35,7 +34,6 @@ public class MWMApplication extends android.app.Application implements MapStorag
private static MWMApplication mSelf;
private StoragePathManager m_pathManager = new StoragePathManager();
private LocationService m_location = null;
private LocationState m_locationState = null;
private MapStorage m_storage = null;
@ -102,11 +100,6 @@ public class MWMApplication extends android.app.Application implements MapStorag
}
}
}
public StoragePathManager GetPathManager()
{
return m_pathManager;
}
@Override
public void onCountryProgress(Index idx, long current, long total)

View file

@ -28,6 +28,7 @@ import android.webkit.WebViewClient;
import com.mapswithme.maps.MWMApplication;
import com.mapswithme.maps.R;
import com.mapswithme.util.StoragePathManager;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.Yota;
@ -36,8 +37,8 @@ import com.mapswithme.util.statistics.Statistics;
public class SettingsActivity extends PreferenceActivity
{
private final static String ZOOM_BUTTON_ENABLED = "ZoomButtonsEnabled";
private BroadcastReceiver m_receiver = null;
private Preference m_storagePreference = null;
private StoragePathManager m_pathManager = new StoragePathManager();
@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
@ -138,20 +139,19 @@ public class SettingsActivity extends PreferenceActivity
return true;
}
});
m_storagePreference = findPreference(getString(R.string.pref_storage_activity));
yotaSetup();
storagePathSetup();
}
@SuppressWarnings("deprecation")
private void storagePathSetup()
{
PreferenceScreen screen = getPreferenceScreen();
if (Yota.isYota())
screen.removePreference(m_storagePreference);
else if (MWMApplication.get().GetPathManager().HasMoreThanOnceStorage())
else if (m_pathManager.HasMoreThanOnceStorage())
screen.addPreference(m_storagePreference);
else
screen.removePreference(m_storagePreference);
@ -192,12 +192,12 @@ public class SettingsActivity extends PreferenceActivity
Statistics.INSTANCE.stopActivity(this);
}
@Override
protected void onResume()
{
super.onResume();
m_receiver = new BroadcastReceiver()
BroadcastReceiver receiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
@ -205,15 +205,15 @@ public class SettingsActivity extends PreferenceActivity
storagePathSetup();
}
};
MWMApplication.get().GetPathManager().StartExtStorageWatching(this, m_receiver);
m_pathManager.StartExtStorageWatching(this, receiver);
storagePathSetup();
}
@Override
protected void onPause()
{
super.onPause();
MWMApplication.get().GetPathManager().StopExtStorageWatching();
m_receiver = null;
m_pathManager.StopExtStorageWatching();
}
@Override
@ -239,7 +239,7 @@ public class SettingsActivity extends PreferenceActivity
{
app.nativeSetBoolean(ZOOM_BUTTON_ENABLED, isEnabled);
}
public static void onAboutDialogClicked(Activity parent)
{
final String url = "file:///android_asset/about.html";
@ -260,7 +260,7 @@ public class SettingsActivity extends PreferenceActivity
aAnim.setDuration(750);
myWebView.startAnimation(aAnim);
}
@Override
public boolean shouldOverrideUrlLoading(WebView v, String url)
{
@ -271,7 +271,7 @@ public class SettingsActivity extends PreferenceActivity
Intent mailIntent = CreateEmailIntent(ctx,
parser.getTo(),
parser.getSubject(),
parser.getBody(),
parser.getBody(),
parser.getCc());
ctx.startActivity(mailIntent);
v.reload();
@ -280,7 +280,7 @@ public class SettingsActivity extends PreferenceActivity
else
return false;
}
private Intent CreateEmailIntent(Context context,
String address,
String subject,
@ -323,6 +323,6 @@ public class SettingsActivity extends PreferenceActivity
myWebView.loadUrl(url);
}
private native boolean isDownloadingActive();
}

View file

@ -1,36 +1,15 @@
package com.mapswithme.maps.settings;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.TextView;
import com.mapswithme.maps.MWMApplication;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.MapsWithMeBaseListActivity;
import com.mapswithme.util.StoragePathManager;
import com.mapswithme.util.Utils;
public class StoragePathActivity extends MapsWithMeBaseListActivity
{
private static String TAG = "StoragePathActivity";
private StoragePathManager m_pathManager = new StoragePathManager();
private StoragePathManager.StoragePathAdapter getAdapter()
{
@ -41,8 +20,6 @@ public class StoragePathActivity extends MapsWithMeBaseListActivity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setListAdapter(MWMApplication.get().GetPathManager().GetAdapter());
}
@Override
@ -52,18 +29,19 @@ public class StoragePathActivity extends MapsWithMeBaseListActivity
if (position != 0)
getAdapter().onItemClick(position);
}
@Override
protected void onResume()
{
super.onResume();
MWMApplication.get().GetPathManager().StartExtStorageWatching(this, null);
m_pathManager.StartExtStorageWatching(this, null);
setListAdapter(m_pathManager.GetAdapter());
}
@Override
protected void onPause()
{
super.onPause();
MWMApplication.get().GetPathManager().StopExtStorageWatching();
m_pathManager.StopExtStorageWatching();
}
}

View file

@ -7,7 +7,6 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
@ -15,9 +14,6 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import com.mapswithme.maps.Framework;
import com.mapswithme.maps.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
@ -38,13 +34,16 @@ import android.widget.BaseAdapter;
import android.widget.CheckedTextView;
import android.widget.TextView;
import com.mapswithme.maps.Framework;
import com.mapswithme.maps.R;
public class StoragePathManager
{
public static class StorageItem
{
public final String m_path;
public final long m_size;
public final long m_size;
StorageItem(String path, long size)
{
m_path = path;
@ -54,9 +53,11 @@ public class StoragePathManager
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
StorageItem other = (StorageItem)o;
if (o == this)
return true;
if (o == null)
return false;
StorageItem other = (StorageItem) o;
return m_size == other.m_size || m_path.equals(other.m_size);
}
@ -66,66 +67,46 @@ public class StoragePathManager
return Long.valueOf(m_size).hashCode();
}
}
public interface OnStorageItemClickListener
{
void onItemClick(int position);
}
public interface SetStoragePathListener
{
void MoveFilesFinished(String newPath);
void MoveFilesFailed();
}
public static class StoragePathAdapter extends BaseAdapter
implements OnStorageItemClickListener
abstract public static class StoragePathAdapter extends BaseAdapter
{
@Override
public int getCount(){ return 0; }
@Override
public Object getItem(int position) { return null; }
@Override
public long getItemId(int position) { return 0; }
@Override
public View getView(int position, View convertView, ViewGroup parent) { return null; }
@Override
public void onItemClick(int position) {}
abstract public void onItemClick(int position);
};
/// ListView adapter
// / ListView adapter
private class StoragePathAdapterImpl extends StoragePathAdapter
{
private static final String TAG = "StoragePathAdapter";
/// @name Different row types.
//@{
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private static final int HEADERS_COUNT = 1;
private static final int TYPES_COUNT = 2;
//@}
// / @name Different row types.
// @{
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private static final int HEADERS_COUNT = 1;
private static final int TYPES_COUNT = 2;
// @}
private final LayoutInflater m_inflater;
private final Activity m_context;
private final int m_listItemHeight;
private List<StorageItem> m_items = null;
private int m_current = -1;
private long m_sizeNeeded;
private final Activity m_context;
private final int m_listItemHeight;
private List<StorageItem> m_items = null;
private int m_current = -1;
private long m_sizeNeeded;
public StoragePathAdapterImpl(Activity context)
{
m_context = context;
m_inflater = m_context.getLayoutInflater();
m_listItemHeight = (int)Utils.getAttributeDimension(context, android.R.attr.listPreferredItemHeight);
m_listItemHeight = (int) Utils.getAttributeDimension(context, android.R.attr.listPreferredItemHeight);
}
@Override
public int getItemViewType(int position)
{
@ -166,41 +147,41 @@ public class StoragePathManager
switch (getItemViewType(position))
{
case TYPE_HEADER:
{
if (convertView == null)
case TYPE_HEADER:
{
convertView = m_inflater.inflate(android.R.layout.simple_list_item_1, null);
convertView.setMinimumHeight(m_listItemHeight);
if (convertView == null)
{
convertView = m_inflater.inflate(android.R.layout.simple_list_item_1, null);
convertView.setMinimumHeight(m_listItemHeight);
}
final TextView v = (TextView) convertView;
v.setText(m_context.getString(R.string.maps) + ": " + getSizeString(m_sizeNeeded));
break;
}
final TextView v = (TextView) convertView;
v.setText(m_context.getString(R.string.maps) + ": " + getSizeString(m_sizeNeeded));
break;
}
case TYPE_ITEM:
{
final int index = getIndexFromPos(position);
final StorageItem item = m_items.get(index);
if (convertView == null)
case TYPE_ITEM:
{
convertView = m_inflater.inflate(android.R.layout.simple_list_item_single_choice, null);
convertView.setMinimumHeight(m_listItemHeight);
}
final int index = getIndexFromPos(position);
final StorageItem item = m_items.get(index);
final CheckedTextView v = (CheckedTextView) convertView;
v.setText(item.m_path + ": " + getSizeString(item.m_size));
v.setChecked(index == m_current);
v.setEnabled((index == m_current) || isAvailable(index));
break;
}
if (convertView == null)
{
convertView = m_inflater.inflate(android.R.layout.simple_list_item_single_choice, null);
convertView.setMinimumHeight(m_listItemHeight);
}
final CheckedTextView v = (CheckedTextView) convertView;
v.setText(item.m_path + ": " + getSizeString(item.m_size));
v.setChecked(index == m_current);
v.setEnabled((index == m_current) || isAvailable(index));
break;
}
}
return convertView;
}
@Override
public void onItemClick(int position)
{
@ -208,7 +189,7 @@ public class StoragePathManager
if (isAvailable(index))
onStorageItemClick(index);
}
public void updateList(ArrayList<StorageItem> items, int currentItemIndex, long dirSize)
{
m_sizeNeeded = dirSize;
@ -235,38 +216,38 @@ public class StoragePathManager
}
// left 1 digit after the comma and add postfix string
return String.format("%.1f %s", (double)size / (double)current, arrS[i]);
return String.format("%.1f %s", (double) size / (double) current, arrS[i]);
}
private boolean isAvailable(int index)
{
assert(index >= 0 && index < m_items.size());
assert (index >= 0 && index < m_items.size());
return ((m_current != index) && (m_items.get(index).m_size >= m_sizeNeeded));
}
private int getIndexFromPos(int position)
{
final int index = position - HEADERS_COUNT;
assert(index >= 0 && index < m_items.size());
assert (index >= 0 && index < m_items.size());
return index;
}
}
private static String TAG = "StoragePathManager";
private static String MWM_DIR_POSTFIX = "/MapsWithMe/";
private BroadcastReceiver m_externalListener;
private BroadcastReceiver m_internalListener;
private Activity m_context = null;
private ArrayList<StorageItem> m_items = null;
private StoragePathAdapterImpl m_adapter = null;
private int m_currentItemIndex = -1;
private static String TAG = "StoragePathManager";
private static String MWM_DIR_POSTFIX = "/MapsWithMe/";
private BroadcastReceiver m_externalListener;
private BroadcastReceiver m_internalListener;
private Activity m_context = null;
private ArrayList<StorageItem> m_items = null;
private StoragePathAdapterImpl m_adapter = null;
private int m_currentItemIndex = -1;
public void StartExtStorageWatching(Activity context, BroadcastReceiver listener)
{
m_context = context;
m_externalListener = listener;
m_internalListener = new BroadcastReceiver()
{
@Override
@ -274,11 +255,11 @@ public class StoragePathManager
{
if (m_externalListener != null)
m_externalListener.onReceive(context, intent);
UpdateExternalStorages();
}
};
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addAction(Intent.ACTION_MEDIA_REMOVED);
@ -290,11 +271,11 @@ public class StoragePathManager
filter.addAction(Intent.ACTION_MEDIA_CHECKING);
filter.addAction(Intent.ACTION_MEDIA_NOFS);
filter.addDataScheme("file");
m_context.registerReceiver(m_internalListener, filter);
UpdateExternalStorages();
}
public StoragePathAdapter GetAdapter()
{
if (m_adapter == null)
@ -302,10 +283,10 @@ public class StoragePathManager
m_adapter = new StoragePathAdapterImpl(m_context);
UpdateExternalStorages();
}
return m_adapter;
}
public void StopExtStorageWatching()
{
if (m_internalListener != null)
@ -316,51 +297,52 @@ public class StoragePathManager
m_adapter = null;
}
}
public boolean HasMoreThanOnceStorage()
{
return m_items.size() > 1;
}
public void UpdateExternalStorages()
{
ArrayList<String> pathes = new ArrayList<String>();
if (Utils.apiEqualOrGreaterThan(android.os.Build.VERSION_CODES.KITKAT))
{
File[] files = m_context.getExternalFilesDirs(null);
if (files != null)
{
File primaryStorageDir = m_context.getExternalFilesDir(null);
for(File f : files)
for (File f : files)
{
// On kitkat and Greater we ignore private folder on primary storage
// like "PrimaryStorage/Android/data/com.mapswithme.maps.pro/file/" because
// like "PrimaryStorage/Android/data/com.mapswithme.maps.pro/file/"
// because
// we can write to root of PrimaryStorage/
if (f != null && !f.equals(primaryStorageDir))
pathes.add(f.getPath());
}
}
}
ParseMountFile("/etc/vold.conf", VOLD_MODE, pathes);
ParseMountFile("/etc/vold.fstab", VOLD_MODE, pathes);
ParseMountFile("/system/etc/vold.fstab", VOLD_MODE, pathes);
ParseMountFile("/proc/mounts", MOUNTS_MODE, pathes);
ArrayList<StorageItem> items = new ArrayList<StorageItem>();
for (String path : pathes)
AddStorage(path, items);
AddStorage(Environment.getExternalStorageDirectory().getAbsolutePath(), items);
String writableDir = GetWritableDirRoot();
StorageItem currentItem = AddStorage(writableDir, items);
LinkedHashSet<StorageItem> itemsSet = new LinkedHashSet<StorageItem>(items);
if (currentItem != null)
itemsSet.remove(currentItem);
m_items = new ArrayList<StorageItem>(itemsSet);
if (currentItem != null)
{
@ -372,28 +354,30 @@ public class StoragePathManager
if (m_adapter != null)
m_adapter.updateList(m_items, m_currentItemIndex, GetMWMDirSize());
}
/// @name Assume that MapsWithMe folder doesn't have inner folders and symbolic links.
//@{
// / @name Assume that MapsWithMe folder doesn't have inner folders and
// symbolic links.
// @{
public long GetMWMDirSize()
{
String writableDir = Framework.GetWritableDir();
final File dir = new File(writableDir);
assert(dir.exists());
assert(dir.isDirectory());
assert (dir.exists());
assert (dir.isDirectory());
long size = 0;
for (final File f : dir.listFiles())
{
assert(f.isFile());
assert (f.isFile());
size += f.length();
}
return size;
}
//@}
// @}
public boolean MoveBookmarks()
{
ArrayList<String> pathes = new ArrayList<String>();
@ -404,7 +388,7 @@ public class StoragePathManager
ParseMountFile("/system/etc/vold.fstab", VOLD_MODE, pathes);
ParseMountFile("/proc/mounts", MOUNTS_MODE, pathes);
}
ArrayList<String> approvedPathes = new ArrayList<String>();
for (String path : pathes)
{
@ -417,24 +401,24 @@ public class StoragePathManager
final String writableDir = Framework.GetWritableDir();
final String bookmarkDir = Framework.GetBookmarksDir();
final String bookmarkFileExt = Framework.GetBookmarkFileExt();
LinkedHashSet<File> bookmarks = new LinkedHashSet<File>();
if (!settingsDir.equals(writableDir))
approvedPathes.add(writableDir);
for (String path : approvedPathes)
{
if (!path.equals(settingsDir))
AccamulateFiles(path, bookmarkFileExt, bookmarks);
}
long bookmarksSize = 0;
for (File f : bookmarks)
bookmarksSize += f.length();
if (GetFreeBytesAtPath(bookmarkDir) < bookmarksSize)
return false;
for (File f : bookmarks)
{
String name = f.getName();
@ -445,32 +429,32 @@ public class StoragePathManager
copyFile(f, new File(name));
f.delete();
}
catch(IOException e)
catch (IOException e)
{
return false;
}
}
Framework.ReloadBookmarks();
return true;
}
private void AccamulateFiles(final String dirPath, final String filesExtension, Set<File> result)
{
File f = new File(dirPath);
File[] bookmarks = f.listFiles(new FileFilter()
{
@Override
public boolean accept(File pathname)
{
@Override
public boolean accept(File pathname)
{
return pathname.getName().endsWith(filesExtension);
}
});
return pathname.getName().endsWith(filesExtension);
}
});
result.addAll(Arrays.asList(bookmarks));
}
private void onStorageItemClick(int index)
{
final StorageItem oldItem = (m_currentItemIndex != -1) ? m_items.get(m_currentItemIndex) : null;
@ -484,55 +468,50 @@ public class StoragePathManager
return;
}
new AlertDialog.Builder(m_context)
.setCancelable(false)
.setTitle(R.string.move_maps)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dlg, int which)
new AlertDialog.Builder(m_context).setCancelable(false).setTitle(R.string.move_maps)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
{
SetStoragePathImpl(m_context, new StoragePathManager.SetStoragePathListener()
@Override
public void onClick(DialogInterface dlg, int which)
{
@Override
public void MoveFilesFinished(String newPath)
SetStoragePathImpl(m_context, new StoragePathManager.SetStoragePathListener()
{
UpdateExternalStorages();
}
@Override
public void MoveFilesFailed()
{
UpdateExternalStorages();
}
}, item, oldItem, R.string.wait_several_minutes);
@Override
public void MoveFilesFinished(String newPath)
{
UpdateExternalStorages();
}
dlg.dismiss();
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dlg, int which)
@Override
public void MoveFilesFailed()
{
UpdateExternalStorages();
}
}, item, oldItem, R.string.wait_several_minutes);
dlg.dismiss();
}
}).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener()
{
dlg.dismiss();
}
})
.create()
.show();
@Override
public void onClick(DialogInterface dlg, int which)
{
dlg.dismiss();
}
}).create().show();
}
public void CheckWritableDir(Context context, SetStoragePathListener listener)
{
if (Utils.apiLowerThan(android.os.Build.VERSION_CODES.KITKAT))
return;
final String settingsDir = Framework.GetSettingsDir();
final String writableDir = Framework.GetWritableDir();
if (settingsDir.equals(writableDir))
return;
if (IsDirWritable(writableDir))
return;
@ -541,21 +520,22 @@ public class StoragePathManager
{
if (item.m_size > size)
{
SetStoragePathImpl(context, listener, item, new StorageItem(GetWritableDirRoot(), 0), R.string.kitkat_optimization_in_progress);
SetStoragePathImpl(context, listener, item, new StorageItem(GetWritableDirRoot(), 0),
R.string.kitkat_optimization_in_progress);
return;
}
}
listener.MoveFilesFailed();
}
private void SetStoragePathImpl(Context context, SetStoragePathListener listener,
StorageItem newStorage, StorageItem oldStorage, int messageId)
private void SetStoragePathImpl(Context context, SetStoragePathListener listener, StorageItem newStorage,
StorageItem oldStorage, int messageId)
{
MoveFilesTask task = new MoveFilesTask(context, listener, newStorage, oldStorage, messageId);
task.execute("");
}
static private boolean DoMoveMaps(StorageItem newStorage, StorageItem oldStorage)
{
String fullOldPath = GetItemFullPath(oldStorage);
@ -564,16 +544,16 @@ public class StoragePathManager
File newDir = new File(fullNewPath);
if (!newDir.exists())
newDir.mkdir();
assert(IsDirWritable(fullNewPath));
assert(newDir.isDirectory());
assert(oldDir.isDirectory());
assert (IsDirWritable(fullNewPath));
assert (newDir.isDirectory());
assert (oldDir.isDirectory());
final String[] extensions = Framework.GetMovableFilesExt();
File[] internalFiles = oldDir.listFiles(new FileFilter()
{
@Override
public boolean accept(File pathname)
{
@ -585,7 +565,7 @@ public class StoragePathManager
return false;
}
});
try
{
for (File moveFile : internalFiles)
@ -597,46 +577,46 @@ public class StoragePathManager
new File(fullNewPath + moveFile.getName()).delete();
return false;
}
Framework.SetWritableDir(fullNewPath);
for (File moveFile : internalFiles)
moveFile.delete();
return true;
}
private static void copyFile(File source, File dest) throws IOException
{
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try
{
inputChannel = new FileInputStream(source).getChannel();
outputChannel = new FileOutputStream(dest).getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
inputChannel = new FileInputStream(source).getChannel();
outputChannel = new FileOutputStream(dest).getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
}
finally
{
inputChannel.close();
outputChannel.close();
inputChannel.close();
outputChannel.close();
}
}
private class MoveFilesTask extends AsyncTask<String, Void, Boolean>
{
private final ProgressDialog m_dlg;
private final StorageItem m_newStorage;
private final StorageItem m_oldStorage;
private final ProgressDialog m_dlg;
private final StorageItem m_newStorage;
private final StorageItem m_oldStorage;
private final SetStoragePathListener m_listener;
public MoveFilesTask(Context context, SetStoragePathListener listener,
StorageItem newStorage, StorageItem oldStorage, int messageID)
public MoveFilesTask(Context context, SetStoragePathListener listener, StorageItem newStorage,
StorageItem oldStorage, int messageID)
{
m_newStorage = newStorage;
m_oldStorage = oldStorage;
m_listener = listener;
m_dlg = new ProgressDialog(context);
m_dlg.setMessage(context.getString(messageID));
m_dlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
@ -666,18 +646,17 @@ public class StoragePathManager
m_dlg.dismiss();
}
catch (final Exception e)
{
}
{}
if (result)
m_listener.MoveFilesFinished(m_newStorage.m_path);
else
m_listener.MoveFilesFailed();
UpdateExternalStorages();
}
}
static private StorageItem AddStorage(String path, ArrayList<StorageItem> items)
{
try
@ -690,12 +669,13 @@ public class StoragePathManager
final long size = GetFreeBytesAtPath(path);
final StorageItem item = new StorageItem(path, size);
items.add(item);
return item;
if (size > 0)
{
final StorageItem item = new StorageItem(path, size);
items.add(item);
return item;
}
}
else
Log.i(TAG, "File error for storage: " + path);
}
catch (final IllegalArgumentException ex)
{
@ -705,10 +685,10 @@ public class StoragePathManager
return null;
}
private static int VOLD_MODE = 1;
private static int VOLD_MODE = 1;
private static int MOUNTS_MODE = 2;
// http://stackoverflow.com/questions/8151779/find-sd-card-volume-label-on-android
// http://stackoverflow.com/questions/5694933/find-an-external-sd-card-location
// http://stackoverflow.com/questions/14212969/file-canwrite-returns-false-on-some-devices-although-write-external-storage-pe
@ -724,7 +704,8 @@ public class StoragePathManager
while (true)
{
final String line = reader.readLine();
if (line == null) break;
if (line == null)
break;
// standard regexp for all possible whitespaces (space, tab, etc)
final String[] arr = line.split("\\s+");
@ -748,7 +729,7 @@ public class StoragePathManager
}
else
{
assert(mode == MOUNTS_MODE);
assert (mode == MOUNTS_MODE);
Log.i(TAG, "Label = " + arr[start + 0] + "; Path = " + arr[start + 1]);
final String prefixes[] = { "tmpfs", "/dev/block/vold", "/dev/fuse", "/mnt/media_rw" };
@ -768,47 +749,61 @@ public class StoragePathManager
Utils.closeStream(reader);
}
}
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
static private long GetFreeBytesAtPath(String path)
{
final StatFs stat = new StatFs(path);
final long size = Utils.apiLowerThan(android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
? (long)stat.getAvailableBlocks() * (long)stat.getBlockSize()
: stat.getAvailableBytes();
long size = 0;
try
{
if (Utils.apiLowerThan(android.os.Build.VERSION_CODES.GINGERBREAD))
{
final StatFs stat = new StatFs(path);
size = stat.getAvailableBlocks() * (long) stat.getBlockSize();
}
else
size = new File(path).getFreeSpace();
}
catch (RuntimeException e)
{
Log.d(TAG, e.getMessage());
Log.d(TAG, e.getStackTrace().toString());
}
return size;
}
static private boolean IsDirWritable(String path)
{
final File f = new File(path + "/testDir");
f.mkdir();
// we can't only call canWrite, because on KitKat (Samsung S4) this return true
// we can't only call canWrite, because on KitKat (Samsung S4) this return
// true
// for sdcard but actually it's read only
if (f.exists())
{
f.delete();
return true;
}
return false;
}
static private String GetItemFullPath(StorageItem item)
{
return item.m_path + MWM_DIR_POSTFIX;
}
static private String GetWritableDirRoot()
{
String writableDir = Framework.GetWritableDir();
int index = writableDir.lastIndexOf(MWM_DIR_POSTFIX);
if (index != -1)
writableDir = writableDir.substring(0, index);
return writableDir;
}
static private native String nativeGenerateUniqueBookmarkName(String baseName);
}