Fix #6740
This commit is contained in:
parent
03144c7a2b
commit
15326798b1
16 changed files with 622 additions and 248 deletions
|
@ -1210,11 +1210,11 @@ public class OsmandAidlApi {
|
|||
if (!destinationExists) {
|
||||
GpxDataItem gpxDataItem = new GpxDataItem(destination, col);
|
||||
gpxDataItem.setApiImported(true);
|
||||
app.getGpxDatabase().add(gpxDataItem);
|
||||
app.getGpxDbHelper().add(gpxDataItem);
|
||||
} else {
|
||||
GpxDataItem item = app.getGpxDatabase().getItem(destination);
|
||||
GpxDataItem item = app.getGpxDbHelper().getItem(destination);
|
||||
if (item != null) {
|
||||
app.getGpxDatabase().updateColor(item, col);
|
||||
app.getGpxDbHelper().updateColor(item, col);
|
||||
}
|
||||
}
|
||||
final GpxSelectionHelper helper = app.getSelectedGpxHelper();
|
||||
|
@ -1435,7 +1435,7 @@ public class OsmandAidlApi {
|
|||
}
|
||||
|
||||
boolean getImportedGpxV2(List<net.osmand.aidlapi.gpx.AGpxFile> files) {
|
||||
List<GpxDataItem> gpxDataItems = app.getGpxDatabase().getItems();
|
||||
List<GpxDataItem> gpxDataItems = app.getGpxDbHelper().getItems();
|
||||
for (GpxDataItem dataItem : gpxDataItems) {
|
||||
File file = dataItem.getFile();
|
||||
if (file.exists()) {
|
||||
|
@ -1460,7 +1460,7 @@ public class OsmandAidlApi {
|
|||
}
|
||||
|
||||
boolean getImportedGpx(List<AGpxFile> files) {
|
||||
List<GpxDataItem> gpxDataItems = app.getGpxDatabase().getItems();
|
||||
List<GpxDataItem> gpxDataItems = app.getGpxDbHelper().getItems();
|
||||
for (GpxDataItem dataItem : gpxDataItems) {
|
||||
File file = dataItem.getFile();
|
||||
if (file.exists()) {
|
||||
|
@ -1480,7 +1480,7 @@ public class OsmandAidlApi {
|
|||
}
|
||||
|
||||
String getGpxColor(String gpxFileName) {
|
||||
List<GpxDataItem> gpxDataItems = app.getGpxDatabase().getItems();
|
||||
List<GpxDataItem> gpxDataItems = app.getGpxDbHelper().getItems();
|
||||
for (GpxDataItem dataItem : gpxDataItems) {
|
||||
File file = dataItem.getFile();
|
||||
if (file.exists()) {
|
||||
|
@ -1499,10 +1499,10 @@ public class OsmandAidlApi {
|
|||
if (!Algorithms.isEmpty(fileName)) {
|
||||
final File f = app.getAppPath(IndexConstants.GPX_INDEX_DIR + fileName);
|
||||
if (f.exists()) {
|
||||
GpxDataItem item = app.getGpxDatabase().getItem(f);
|
||||
GpxDataItem item = app.getGpxDbHelper().getItem(f);
|
||||
if (item != null && item.isApiImported()) {
|
||||
Algorithms.removeAllFiles(f);
|
||||
app.getGpxDatabase().remove(f);
|
||||
app.getGpxDbHelper().remove(f);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -482,7 +482,7 @@ public class AppInitializer implements IProgress {
|
|||
app.notificationHelper = startupInit(new NotificationHelper(app), NotificationHelper.class);
|
||||
app.liveMonitoringHelper = startupInit(new LiveMonitoringHelper(app), LiveMonitoringHelper.class);
|
||||
app.selectedGpxHelper = startupInit(new GpxSelectionHelper(app, app.savingTrackHelper), GpxSelectionHelper.class);
|
||||
app.gpxDatabase = startupInit(new GPXDatabase(app), GPXDatabase.class);
|
||||
app.gpxDbHelper = startupInit(new GpxDbHelper(app), GpxDbHelper.class);
|
||||
app.favorites = startupInit(new FavouritesDbHelper(app), FavouritesDbHelper.class);
|
||||
app.waypointHelper = startupInit(new WaypointHelper(app), WaypointHelper.class);
|
||||
app.aidlApi = startupInit(new OsmandAidlApi(app), OsmandAidlApi.class);
|
||||
|
@ -669,6 +669,7 @@ public class AppInitializer implements IProgress {
|
|||
notifyEvent(InitEvents.NATIVE_INITIALIZED);
|
||||
|
||||
app.favorites.loadFavorites();
|
||||
app.gpxDbHelper.loadGpxItems();
|
||||
notifyEvent(InitEvents.FAVORITES_INITIALIZED);
|
||||
app.poiFilters.reloadAllPoiFilters();
|
||||
app.poiFilters.loadSelectedPoiFilters();
|
||||
|
|
|
@ -199,13 +199,35 @@ public class GPXDatabase {
|
|||
public void setShowAsMarkers(boolean showAsMarkers) {
|
||||
this.showAsMarkers = showAsMarkers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return file != null ? file.hashCode() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof GpxDataItem)) {
|
||||
return false;
|
||||
}
|
||||
final GpxDataItem other = (GpxDataItem) obj;
|
||||
if (file == null || other.file == null) {
|
||||
return false;
|
||||
}
|
||||
return file.equals(other.file);
|
||||
}
|
||||
}
|
||||
|
||||
public GPXDatabase(OsmandApplication app) {
|
||||
GPXDatabase(OsmandApplication app) {
|
||||
context = app;
|
||||
// init database
|
||||
SQLiteConnection db = openConnection(false);
|
||||
if (db != null) {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
|
||||
private SQLiteConnection openConnection(boolean readonly) {
|
||||
SQLiteConnection openConnection(boolean readonly) {
|
||||
SQLiteConnection conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly);
|
||||
if (conn.getVersion() < DB_VERSION) {
|
||||
if (readonly) {
|
||||
|
@ -225,6 +247,7 @@ public class GPXDatabase {
|
|||
|
||||
private void onCreate(SQLiteConnection db) {
|
||||
db.execSQL(GPX_TABLE_CREATE);
|
||||
db.execSQL("CREATE INDEX IF NOT EXISTS " + GPX_INDEX_NAME_DIR + " ON " + GPX_TABLE_NAME + " (" + GPX_COL_NAME + ", " + GPX_COL_DIR + ");");
|
||||
}
|
||||
|
||||
private void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) {
|
||||
|
@ -401,7 +424,7 @@ public class GPXDatabase {
|
|||
|
||||
public boolean remove(File file) {
|
||||
SQLiteConnection db = openConnection(false);
|
||||
if (db != null){
|
||||
if (db != null) {
|
||||
try {
|
||||
String fileName = getFileName(file);
|
||||
String fileDir = getFileDir(file);
|
||||
|
@ -421,7 +444,7 @@ public class GPXDatabase {
|
|||
|
||||
public boolean add(GpxDataItem item) {
|
||||
SQLiteConnection db = openConnection(false);
|
||||
if (db != null){
|
||||
if (db != null) {
|
||||
try {
|
||||
insert(item, db);
|
||||
} finally {
|
||||
|
@ -442,7 +465,7 @@ public class GPXDatabase {
|
|||
"" : itemFile.getParentFile().getName();
|
||||
}
|
||||
|
||||
private void insert(GpxDataItem item, SQLiteConnection db) {
|
||||
void insert(GpxDataItem item, SQLiteConnection db) {
|
||||
String fileName = getFileName(item.file);
|
||||
String fileDir = getFileDir(item.file);
|
||||
GPXTrackAnalysis a = item.getAnalysis();
|
||||
|
@ -482,22 +505,30 @@ public class GPXDatabase {
|
|||
SQLiteConnection db = openConnection(false);
|
||||
if (db != null) {
|
||||
try {
|
||||
String fileName = getFileName(item.file);
|
||||
String fileDir = getFileDir(item.file);
|
||||
db.execSQL(GPX_TABLE_UPDATE_ANALYSIS + " WHERE " + GPX_COL_NAME + " = ? AND " + GPX_COL_DIR + " = ?",
|
||||
new Object[]{ a.totalDistance, a.totalTracks, a.startTime, a.endTime,
|
||||
a.timeSpan, a.timeMoving, a.totalDistanceMoving, a.diffElevationUp,
|
||||
a.diffElevationDown, a.avgElevation, a.minElevation, a.maxElevation,
|
||||
a.maxSpeed, a.avgSpeed, a.points, a.wptPoints, item.file.lastModified(),
|
||||
Algorithms.encodeStringSet(a.wptCategoryNames), fileName, fileDir });
|
||||
return updateAnalysis(item, a, db);
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updateAnalysis(GpxDataItem item, GPXTrackAnalysis a, SQLiteConnection db) {
|
||||
if (a == null) {
|
||||
return false;
|
||||
}
|
||||
String fileName = getFileName(item.file);
|
||||
String fileDir = getFileDir(item.file);
|
||||
db.execSQL(GPX_TABLE_UPDATE_ANALYSIS + " WHERE " + GPX_COL_NAME + " = ? AND " + GPX_COL_DIR + " = ?",
|
||||
new Object[]{a.totalDistance, a.totalTracks, a.startTime, a.endTime,
|
||||
a.timeSpan, a.timeMoving, a.totalDistanceMoving, a.diffElevationUp,
|
||||
a.diffElevationDown, a.avgElevation, a.minElevation, a.maxElevation,
|
||||
a.maxSpeed, a.avgSpeed, a.points, a.wptPoints, item.file.lastModified(),
|
||||
Algorithms.encodeStringSet(a.wptCategoryNames), fileName, fileDir});
|
||||
item.analysis = a;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean clearAnalysis(GpxDataItem item) {
|
||||
SQLiteConnection db = openConnection(false);
|
||||
if (db != null) {
|
||||
|
@ -584,19 +615,23 @@ public class GPXDatabase {
|
|||
return item;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<GpxDataItem> getItems() {
|
||||
List<GpxDataItem> items = new ArrayList<>();
|
||||
SQLiteConnection db = openConnection(true);
|
||||
SQLiteConnection db = openConnection(false);
|
||||
if (db != null) {
|
||||
try {
|
||||
SQLiteCursor query = db.rawQuery(GPX_TABLE_SELECT, null);
|
||||
if (query != null && query.moveToFirst()) {
|
||||
do {
|
||||
items.add(readItem(query));
|
||||
} while (query.moveToNext());
|
||||
}
|
||||
if (query != null) {
|
||||
query.close();
|
||||
try {
|
||||
if (query.moveToFirst()) {
|
||||
do {
|
||||
items.add(readItem(query));
|
||||
} while (query.moveToNext());
|
||||
}
|
||||
} finally {
|
||||
query.close();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
db.close();
|
||||
|
@ -608,23 +643,58 @@ public class GPXDatabase {
|
|||
@Nullable
|
||||
public GpxDataItem getItem(File file) {
|
||||
GpxDataItem result = null;
|
||||
SQLiteConnection db = openConnection(true);
|
||||
if (db != null){
|
||||
SQLiteConnection db = openConnection(false);
|
||||
if (db != null) {
|
||||
try {
|
||||
String fileName = getFileName(file);
|
||||
String fileDir = getFileDir(file);
|
||||
SQLiteCursor query = db.rawQuery(GPX_TABLE_SELECT + " WHERE " + GPX_COL_NAME + " = ? AND " +
|
||||
GPX_COL_DIR + " = ?", new String[] { fileName, fileDir });
|
||||
if ( query != null && query.moveToFirst()) {
|
||||
result = readItem(query);
|
||||
}
|
||||
if (query != null) {
|
||||
query.close();
|
||||
}
|
||||
result = getItem(file, db);
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GpxDataItem getItem(File file, SQLiteConnection db) {
|
||||
GpxDataItem result = null;
|
||||
String fileName = getFileName(file);
|
||||
String fileDir = getFileDir(file);
|
||||
SQLiteCursor query = db.rawQuery(GPX_TABLE_SELECT + " WHERE " + GPX_COL_NAME + " = ? AND " +
|
||||
GPX_COL_DIR + " = ?", new String[]{fileName, fileDir});
|
||||
if (query != null) {
|
||||
try {
|
||||
if (query.moveToFirst()) {
|
||||
result = readItem(query);
|
||||
}
|
||||
} finally {
|
||||
query.close();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<GpxDataItem> getSplitItems() {
|
||||
List<GpxDataItem> items = new ArrayList<>();
|
||||
SQLiteConnection db = openConnection(false);
|
||||
if (db != null) {
|
||||
try {
|
||||
SQLiteCursor query = db.rawQuery(GPX_TABLE_SELECT + " WHERE " + GPX_COL_SPLIT_TYPE + " != ?", new String[] { String.valueOf(0) });
|
||||
if (query != null) {
|
||||
try {
|
||||
if (query.moveToFirst()) {
|
||||
do {
|
||||
items.add(readItem(query));
|
||||
} while (query.moveToNext());
|
||||
}
|
||||
} finally {
|
||||
query.close();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
|
265
OsmAnd/src/net/osmand/plus/GpxDbHelper.java
Normal file
265
OsmAnd/src/net/osmand/plus/GpxDbHelper.java
Normal file
|
@ -0,0 +1,265 @@
|
|||
package net.osmand.plus;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||
import net.osmand.plus.api.SQLiteAPI;
|
||||
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class GpxDbHelper {
|
||||
|
||||
private static final int MAX_ITEMS_CACHE_SIZE = 5000;
|
||||
|
||||
private OsmandApplication app;
|
||||
private GPXDatabase db;
|
||||
private Map<File, GpxDataItem> itemsCache = new ConcurrentHashMap<>();
|
||||
|
||||
private ConcurrentLinkedQueue<File> readingItems = new ConcurrentLinkedQueue<>();
|
||||
private Map<File, GpxDataItem> readingItemsMap = new ConcurrentHashMap<>();
|
||||
private Map<File, GpxDataItemCallback> readingItemsCallbacks = new ConcurrentHashMap<>();
|
||||
private GpxReaderTask readerTask;
|
||||
|
||||
public interface GpxDataItemCallback {
|
||||
|
||||
boolean isCancelled();
|
||||
|
||||
void onGpxDataItemReady(GpxDataItem item);
|
||||
}
|
||||
|
||||
GpxDbHelper(OsmandApplication app) {
|
||||
this.app = app;
|
||||
db = new GPXDatabase(app);
|
||||
}
|
||||
|
||||
void loadGpxItems() {
|
||||
List<GpxDataItem> items = getItems();
|
||||
for (GpxDataItem item : items) {
|
||||
putToCache(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateItemsCacheSize() {
|
||||
if (itemsCache.size() > MAX_ITEMS_CACHE_SIZE) {
|
||||
itemsCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private GpxDataItem putToCache(GpxDataItem item) {
|
||||
updateItemsCacheSize();
|
||||
return itemsCache.put(item.getFile(), item);
|
||||
}
|
||||
|
||||
private void removeFromCache(GpxDataItem item) {
|
||||
itemsCache.remove(item.getFile());
|
||||
}
|
||||
|
||||
public boolean rename(File currentFile, File newFile) {
|
||||
boolean res = db.rename(currentFile, newFile);
|
||||
itemsCache.remove(currentFile);
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean updateColor(GpxDataItem item, int color) {
|
||||
boolean res = db.updateColor(item, color);
|
||||
putToCache(item);
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean updateShowAsMarkers(GpxDataItem item, boolean showAsMarkers) {
|
||||
boolean res = db.updateShowAsMarkers(item, showAsMarkers);
|
||||
putToCache(item);
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean updateSplit(@NonNull GpxDataItem item, int splitType, double splitInterval) {
|
||||
boolean res = db.updateSplit(item, splitType, splitInterval);
|
||||
putToCache(item);
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean remove(File file) {
|
||||
boolean res = db.remove(file);
|
||||
itemsCache.remove(file);
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean remove(GpxDataItem item) {
|
||||
boolean res = db.remove(item);
|
||||
itemsCache.remove(item.getFile());
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean add(GpxDataItem item) {
|
||||
boolean res = db.add(item);
|
||||
putToCache(item);
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean updateAnalysis(GpxDataItem item, GPXTrackAnalysis a) {
|
||||
boolean res = db.updateAnalysis(item, a);
|
||||
putToCache(item);
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean clearAnalysis(GpxDataItem item) {
|
||||
boolean res = db.clearAnalysis(item);
|
||||
itemsCache.remove(item.getFile());
|
||||
return res;
|
||||
}
|
||||
|
||||
public List<GpxDataItem> getItems() {
|
||||
return db.getItems();
|
||||
}
|
||||
|
||||
public GpxDataItem getItem(File file) {
|
||||
return getItem(file, null);
|
||||
}
|
||||
|
||||
public GpxDataItem getItem(File file, @Nullable GpxDataItemCallback callback) {
|
||||
GpxDataItem item = itemsCache.get(file);
|
||||
if (item == null && !isGpxReading(file)) {
|
||||
readGpxItem(file, item, callback);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public List<GpxDataItem> getSplitItems() {
|
||||
return db.getSplitItems();
|
||||
}
|
||||
|
||||
public boolean isRead() {
|
||||
GpxReaderTask readerTask = this.readerTask;
|
||||
return readerTask == null || !readerTask.isReading();
|
||||
}
|
||||
|
||||
private boolean isGpxReading(@NonNull File gpxFile) {
|
||||
GpxReaderTask analyser = this.readerTask;
|
||||
return readingItems.contains(gpxFile)
|
||||
|| (analyser != null && gpxFile.equals(analyser.getGpxFile()));
|
||||
}
|
||||
|
||||
private void readGpxItem(@NonNull File gpxFile, @Nullable GpxDataItem item, @Nullable GpxDataItemCallback callback) {
|
||||
readingItemsMap.put(gpxFile, item != null ? item : new GpxDataItem(null, null));
|
||||
if (callback != null) {
|
||||
readingItemsCallbacks.put(gpxFile, callback);
|
||||
}
|
||||
readingItems.add(gpxFile);
|
||||
if (readerTask == null) {
|
||||
startReading();
|
||||
}
|
||||
}
|
||||
|
||||
private void startReading() {
|
||||
readerTask = new GpxReaderTask();
|
||||
readerTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void stopReading() {
|
||||
if (readerTask != null) {
|
||||
readerTask.cancel(false);
|
||||
readerTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private class GpxReaderTask extends AsyncTask<Void, GpxDataItem, Void> {
|
||||
|
||||
private File gpxFile;
|
||||
|
||||
public File getGpxFile() {
|
||||
return gpxFile;
|
||||
}
|
||||
|
||||
public boolean isReading() {
|
||||
return readingItems.size() > 0 || gpxFile != null;
|
||||
}
|
||||
|
||||
private boolean isAnalyseNeeded(@NonNull File gpxFile, @Nullable GpxDataItem item) {
|
||||
return item == null
|
||||
|| item.getFileLastModifiedTime() != gpxFile.lastModified()
|
||||
|| item.getAnalysis() == null
|
||||
|| item.getAnalysis().wptCategoryNames == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
SQLiteConnection conn = db.openConnection(false);
|
||||
if (conn != null) {
|
||||
try {
|
||||
gpxFile = readingItems.poll();
|
||||
while (gpxFile != null && !isCancelled()) {
|
||||
GpxDataItem item = readingItemsMap.remove(gpxFile);
|
||||
if (item.getFile() == null) {
|
||||
item = db.getItem(gpxFile, conn);
|
||||
}
|
||||
if (isAnalyseNeeded(gpxFile, item)) {
|
||||
GPXFile f = GPXUtilities.loadGPXFile(gpxFile);
|
||||
GPXTrackAnalysis analysis = f.getAnalysis(gpxFile.lastModified());
|
||||
if (item == null || item.getFile() == null) {
|
||||
item = new GpxDataItem(gpxFile, analysis);
|
||||
db.insert(item, conn);
|
||||
putToCache(item);
|
||||
} else {
|
||||
db.updateAnalysis(item, analysis, conn);
|
||||
putToCache(item);
|
||||
}
|
||||
} else {
|
||||
putToCache(item);
|
||||
}
|
||||
|
||||
if (!isCancelled()) {
|
||||
publishProgress(item);
|
||||
}
|
||||
gpxFile = readingItems.poll();
|
||||
}
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
} else {
|
||||
cancel(false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(Void aVoid) {
|
||||
readingItems.clear();
|
||||
readingItemsMap.clear();
|
||||
readingItemsCallbacks.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(GpxDataItem... values) {
|
||||
GpxDataItem item = values[0];
|
||||
GpxDataItemCallback callback = readingItemsCallbacks.remove(item.getFile());
|
||||
if (callback != null) {
|
||||
if (callback.isCancelled()) {
|
||||
stopReading();
|
||||
} else {
|
||||
callback.onGpxDataItemReady(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
if (readingItems.size() > 0 && !isCancelled()) {
|
||||
startReading();
|
||||
} else {
|
||||
readerTask = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -152,29 +152,27 @@ public class GpxSelectionHelper {
|
|||
}
|
||||
|
||||
public void processSplit() {
|
||||
List<GpxDataItem> items = app.getGpxDatabase().getItems();
|
||||
List<GpxDataItem> items = app.getGpxDbHelper().getSplitItems();
|
||||
for (GpxDataItem dataItem : items) {
|
||||
if (dataItem.getSplitType() != 0) {
|
||||
SelectedGpxFile selectedGpxFile = getSelectedFileByPath(dataItem.getFile().getAbsolutePath());
|
||||
if (selectedGpxFile != null && selectedGpxFile.getGpxFile() != null) {
|
||||
GPXFile gpxFile = selectedGpxFile.getGpxFile();
|
||||
List<GpxDisplayGroup> groups = app.getSelectedGpxHelper().collectDisplayGroups(gpxFile);
|
||||
if (dataItem.getSplitType() == GPXDatabase.GPX_SPLIT_TYPE_NO_SPLIT) {
|
||||
for (GpxDisplayGroup model : groups) {
|
||||
model.noSplit(app);
|
||||
}
|
||||
selectedGpxFile.setDisplayGroups(groups);
|
||||
} else if (dataItem.getSplitType() == GPXDatabase.GPX_SPLIT_TYPE_DISTANCE) {
|
||||
for (GpxDisplayGroup model : groups) {
|
||||
model.splitByDistance(app, dataItem.getSplitInterval());
|
||||
}
|
||||
selectedGpxFile.setDisplayGroups(groups);
|
||||
} else if (dataItem.getSplitType() == GPXDatabase.GPX_SPLIT_TYPE_TIME) {
|
||||
for (GpxDisplayGroup model : groups) {
|
||||
model.splitByTime(app, (int) dataItem.getSplitInterval());
|
||||
}
|
||||
selectedGpxFile.setDisplayGroups(groups);
|
||||
SelectedGpxFile selectedGpxFile = getSelectedFileByPath(dataItem.getFile().getAbsolutePath());
|
||||
if (selectedGpxFile != null && selectedGpxFile.getGpxFile() != null) {
|
||||
GPXFile gpxFile = selectedGpxFile.getGpxFile();
|
||||
List<GpxDisplayGroup> groups = app.getSelectedGpxHelper().collectDisplayGroups(gpxFile);
|
||||
if (dataItem.getSplitType() == GPXDatabase.GPX_SPLIT_TYPE_NO_SPLIT) {
|
||||
for (GpxDisplayGroup model : groups) {
|
||||
model.noSplit(app);
|
||||
}
|
||||
selectedGpxFile.setDisplayGroups(groups);
|
||||
} else if (dataItem.getSplitType() == GPXDatabase.GPX_SPLIT_TYPE_DISTANCE) {
|
||||
for (GpxDisplayGroup model : groups) {
|
||||
model.splitByDistance(app, dataItem.getSplitInterval());
|
||||
}
|
||||
selectedGpxFile.setDisplayGroups(groups);
|
||||
} else if (dataItem.getSplitType() == GPXDatabase.GPX_SPLIT_TYPE_TIME) {
|
||||
for (GpxDisplayGroup model : groups) {
|
||||
model.splitByTime(app, (int) dataItem.getSplitInterval());
|
||||
}
|
||||
selectedGpxFile.setDisplayGroups(groups);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -622,7 +620,7 @@ public class GpxSelectionHelper {
|
|||
}
|
||||
|
||||
public SelectedGpxFile selectGpxFile(GPXFile gpx, boolean show, boolean notShowNavigationDialog, boolean syncGroup, boolean selectedByUser, boolean canAddToMarkers) {
|
||||
GpxDataItem dataItem = app.getGpxDatabase().getItem(new File(gpx.path));
|
||||
GpxDataItem dataItem = app.getGpxDbHelper().getItem(new File(gpx.path));
|
||||
if (canAddToMarkers && show && dataItem != null && dataItem.isShowAsMarkers()) {
|
||||
app.getMapMarkersHelper().addOrEnableGroup(gpx);
|
||||
}
|
||||
|
|
|
@ -370,9 +370,9 @@ public class MapMarkersHelper {
|
|||
}
|
||||
|
||||
private void updateGpxShowAsMarkers(File file) {
|
||||
GPXDatabase.GpxDataItem dataItem = ctx.getGpxDatabase().getItem(file);
|
||||
GPXDatabase.GpxDataItem dataItem = ctx.getGpxDbHelper().getItem(file);
|
||||
if (dataItem != null) {
|
||||
ctx.getGpxDatabase().updateShowAsMarkers(dataItem, true);
|
||||
ctx.getGpxDbHelper().updateShowAsMarkers(dataItem, true);
|
||||
dataItem.setShowAsMarkers(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,6 @@ public class OsmandApplication extends MultiDexApplication {
|
|||
FavouritesDbHelper favorites;
|
||||
CommandPlayer player;
|
||||
GpxSelectionHelper selectedGpxHelper;
|
||||
GPXDatabase gpxDatabase;
|
||||
SavingTrackHelper savingTrackHelper;
|
||||
AnalyticsHelper analyticsHelper;
|
||||
NotificationHelper notificationHelper;
|
||||
|
@ -137,6 +136,7 @@ public class OsmandApplication extends MultiDexApplication {
|
|||
MapViewTrackingUtilities mapViewTrackingUtilities;
|
||||
LockHelper lockHelper;
|
||||
SettingsHelper settingsHelper;
|
||||
GpxDbHelper gpxDbHelper;
|
||||
|
||||
private RoutingConfiguration.Builder routingConfig;
|
||||
private Locale preferredLocale = null;
|
||||
|
@ -316,8 +316,8 @@ public class OsmandApplication extends MultiDexApplication {
|
|||
return selectedGpxHelper;
|
||||
}
|
||||
|
||||
public GPXDatabase getGpxDatabase() {
|
||||
return gpxDatabase;
|
||||
public GpxDbHelper getGpxDbHelper() {
|
||||
return gpxDbHelper;
|
||||
}
|
||||
|
||||
public FavouritesDbHelper getFavorites() {
|
||||
|
|
|
@ -235,7 +235,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
|
|||
GPXFile gpx = data.get(f);
|
||||
GPXTrackAnalysis analysis = gpx.getAnalysis(fout.lastModified());
|
||||
GpxDataItem item = new GpxDataItem(fout, analysis);
|
||||
ctx.getGpxDatabase().add(item);
|
||||
ctx.getGpxDbHelper().add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -337,7 +337,7 @@ public class TrackActivity extends TabActivity {
|
|||
|
||||
private void onGPXFileReady(@Nullable GPXFile gpxFile) {
|
||||
setGpx(gpxFile);
|
||||
setGpxDataItem(file != null ? app.getGpxDatabase().getItem(file) : null);
|
||||
setGpxDataItem(file != null ? app.getGpxDbHelper().getItem(file) : null);
|
||||
|
||||
WindowManager mgr = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
|
||||
if (gpxFile != null && mgr != null) {
|
||||
|
|
|
@ -73,7 +73,10 @@ import net.osmand.PlatformUtil;
|
|||
import net.osmand.plus.ContextMenuAdapter;
|
||||
import net.osmand.plus.ContextMenuItem;
|
||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||
import net.osmand.plus.GpxDbHelper;
|
||||
import net.osmand.plus.GpxDbHelper.GpxDataItemCallback;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.OsmAndConstants;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
|
@ -437,6 +440,59 @@ public class GpxUiHelper {
|
|||
return dlg;
|
||||
}
|
||||
|
||||
private static class DialogGpxDataItemCallback implements GpxDataItemCallback {
|
||||
private static final int UPDATE_GPX_ITEM_MSG_ID = OsmAndConstants.UI_HANDLER_LOCATION_SERVICE + 6;
|
||||
private static final long MIN_UPDATE_INTERVAL = 500;
|
||||
|
||||
private OsmandApplication app;
|
||||
private long lastUpdateTime;
|
||||
private boolean updateEnable = true;
|
||||
private ArrayAdapter<String> listAdapter;
|
||||
|
||||
DialogGpxDataItemCallback(OsmandApplication app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public boolean isUpdateEnable() {
|
||||
return updateEnable;
|
||||
}
|
||||
|
||||
public void setUpdateEnable(boolean updateEnable) {
|
||||
this.updateEnable = updateEnable;
|
||||
}
|
||||
|
||||
public ArrayAdapter<String> getListAdapter() {
|
||||
return listAdapter;
|
||||
}
|
||||
|
||||
public void setListAdapter(ArrayAdapter<String> listAdapter) {
|
||||
this.listAdapter = listAdapter;
|
||||
}
|
||||
|
||||
private Runnable updateItemsProc = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (updateEnable) {
|
||||
lastUpdateTime = System.currentTimeMillis();
|
||||
listAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return !updateEnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGpxDataItemReady(GpxDataItem item) {
|
||||
if (System.currentTimeMillis() - lastUpdateTime > MIN_UPDATE_INTERVAL) {
|
||||
updateItemsProc.run();
|
||||
}
|
||||
app.runMessageInUIThreadAndCancelPrevious(UPDATE_GPX_ITEM_MSG_ID, updateItemsProc, MIN_UPDATE_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
private static AlertDialog createDialog(final Activity activity,
|
||||
final boolean showCurrentGpx,
|
||||
final boolean multipleChoice,
|
||||
|
@ -451,12 +507,11 @@ public class GpxUiHelper {
|
|||
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(activity, themeRes));
|
||||
final int layout = R.layout.gpx_track_item;
|
||||
final Map<String, String> gpxAppearanceParams = new HashMap<>();
|
||||
final DialogGpxDataItemCallback gpxDataItemCallback = new DialogGpxDataItemCallback(app);
|
||||
|
||||
final ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(activity, layout, R.id.title,
|
||||
adapter.getItemNames()) {
|
||||
|
||||
List<GpxDataItem> dataItems = null;
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return showCurrentGpx && position == 0 ? 1 : 0;
|
||||
|
@ -468,18 +523,14 @@ public class GpxUiHelper {
|
|||
}
|
||||
|
||||
private GpxDataItem getDataItem(GPXInfo info) {
|
||||
if (dataItems != null) {
|
||||
for (GpxDataItem item : dataItems) {
|
||||
if (item.getFile().getAbsolutePath().endsWith(info.fileName)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return app.getGpxDbHelper().getItem(
|
||||
new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), info.getFileName()),
|
||||
gpxDataItemCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
@NonNull
|
||||
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
|
||||
// User super class to create the View
|
||||
View v = convertView;
|
||||
boolean checkLayout = getItemViewType(position) == 0;
|
||||
|
@ -487,13 +538,10 @@ public class GpxUiHelper {
|
|||
v = View.inflate(new ContextThemeWrapper(activity, themeRes), layout, null);
|
||||
}
|
||||
|
||||
if (dataItems == null) {
|
||||
dataItems = app.getGpxDatabase().getItems();
|
||||
}
|
||||
|
||||
final ContextMenuItem item = adapter.getItem(position);
|
||||
GPXInfo info = list.get(position);
|
||||
updateGpxInfoView(v, item.getTitle(), info, getDataItem(info), showCurrentGpx && position == 0, app);
|
||||
boolean currentlyRecordingTrack = showCurrentGpx && position == 0;
|
||||
updateGpxInfoView(v, item.getTitle(), info, currentlyRecordingTrack ? null : getDataItem(info), currentlyRecordingTrack, app);
|
||||
|
||||
if (item.getSelected() == null) {
|
||||
v.findViewById(R.id.check_item).setVisibility(View.GONE);
|
||||
|
@ -535,6 +583,7 @@ public class GpxUiHelper {
|
|||
public void onClick(DialogInterface dialog, int position) {
|
||||
}
|
||||
};
|
||||
gpxDataItemCallback.setListAdapter(listAdapter);
|
||||
builder.setAdapter(listAdapter, onClickListener);
|
||||
if (multipleChoice) {
|
||||
if (showAppearanceSetting) {
|
||||
|
@ -721,6 +770,12 @@ public class GpxUiHelper {
|
|||
}
|
||||
}
|
||||
});
|
||||
dlg.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
gpxDataItemCallback.setUpdateEnable(false);
|
||||
}
|
||||
});
|
||||
dlg.show();
|
||||
try {
|
||||
dlg.getListView().setFastScrollEnabled(true);
|
||||
|
|
|
@ -17,8 +17,6 @@ import android.support.annotation.NonNull;
|
|||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
@ -47,7 +45,6 @@ import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
|||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerHalfItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||
import net.osmand.plus.myplaces.FavoritesActivity;
|
||||
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
@ -630,11 +627,11 @@ public class ImportHelper {
|
|||
File file = new File(gpxFile.path);
|
||||
if (!destinationExists) {
|
||||
GPXDatabase.GpxDataItem item = new GPXDatabase.GpxDataItem(file, gpxFile.getColor(0));
|
||||
app.getGpxDatabase().add(item);
|
||||
app.getGpxDbHelper().add(item);
|
||||
} else {
|
||||
GPXDatabase.GpxDataItem item = app.getGpxDatabase().getItem(file);
|
||||
GPXDatabase.GpxDataItem item = app.getGpxDbHelper().getItem(file);
|
||||
if (item != null) {
|
||||
app.getGpxDatabase().clearAnalysis(item);
|
||||
app.getGpxDbHelper().clearAnalysis(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.osmand.plus.mapmarkers;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
|
@ -13,8 +14,9 @@ import net.osmand.GPXUtilities;
|
|||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.plus.GPXDatabase;
|
||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||
import net.osmand.plus.GpxDbHelper;
|
||||
import net.osmand.plus.GpxDbHelper.GpxDataItemCallback;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
|
@ -24,18 +26,47 @@ import net.osmand.plus.mapmarkers.adapters.TracksGroupsAdapter;
|
|||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheetDialogFragment {
|
||||
|
||||
private OsmandApplication app;
|
||||
private GpxDbHelper dbHelper;
|
||||
|
||||
private ProcessGpxTask asyncProcessor;
|
||||
private List<GpxDataItem> gpxList;
|
||||
|
||||
private ProgressBar progressBar;
|
||||
private RecyclerView recyclerView;
|
||||
private TextView lookingForTracksText;
|
||||
|
||||
private GpxDataItemCallback gpxDataItemCallback = new GpxDataItemCallback() {
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
ProcessGpxTask processor = asyncProcessor;
|
||||
return processor == null || processor.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGpxDataItemReady(GpxDataItem item) {
|
||||
populateList(item);
|
||||
if (dbHelper.isRead()) {
|
||||
onListPopulated();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
app = requiredMyApplication();
|
||||
dbHelper = app.getGpxDbHelper();
|
||||
|
||||
progressBar = (ProgressBar) mainView.findViewById(R.id.progress_bar);
|
||||
recyclerView = (RecyclerView) mainView.findViewById(R.id.groups_recycler_view);
|
||||
lookingForTracksText = (TextView) mainView.findViewById(R.id.looking_for_tracks_text);
|
||||
|
||||
asyncProcessor = new ProcessGpxTask();
|
||||
asyncProcessor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
@ -82,22 +113,32 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet
|
|||
dismiss();
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public class ProcessGpxTask extends AsyncTask<Void, GpxDataItem, Void> {
|
||||
|
||||
private OsmandApplication app = getMyApplication();
|
||||
private Map<File, GpxDataItem> processedDataFiles = new HashMap<>();
|
||||
private GPXDatabase db = app.getGpxDatabase();
|
||||
private ProgressBar progressBar = (ProgressBar) mainView.findViewById(R.id.progress_bar);
|
||||
private RecyclerView recyclerView = (RecyclerView) mainView.findViewById(R.id.groups_recycler_view);
|
||||
private TextView lookingForTracksText = (TextView) mainView.findViewById(R.id.looking_for_tracks_text);
|
||||
|
||||
ProcessGpxTask() {
|
||||
List<GpxDataItem> dataItems = db.getItems();
|
||||
for (GpxDataItem item : dataItems) {
|
||||
processedDataFiles.put(item.getFile(), item);
|
||||
private void populateList(GpxDataItem item) {
|
||||
if (item != null && item.getFile() != null) {
|
||||
GPXTrackAnalysis analysis = item.getAnalysis();
|
||||
if (analysis != null && analysis.wptPoints > 0) {
|
||||
int index = gpxList.indexOf(item);
|
||||
if (index != -1) {
|
||||
gpxList.set(index, item);
|
||||
} else {
|
||||
gpxList.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onListPopulated() {
|
||||
asyncProcessor = null;
|
||||
|
||||
adapter.notifyDataSetChanged();
|
||||
progressBar.setVisibility(View.GONE);
|
||||
lookingForTracksText.setVisibility(View.GONE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
setupHeightAndBackground(getView());
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private class ProcessGpxTask extends AsyncTask<Void, GpxDataItem, Void> {
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
|
@ -131,25 +172,8 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet
|
|||
gpxFile.getName() : gpxSubfolder + "/" + gpxFile.getName();
|
||||
processGPXFolder(gpxFile, sub);
|
||||
} else if (gpxFile.isFile() && gpxFile.getName().toLowerCase().endsWith(".gpx")) {
|
||||
GpxDataItem item = processedDataFiles.get(gpxFile);
|
||||
GPXTrackAnalysis itemAnalysis = item != null ? item.getAnalysis() : null;
|
||||
if (item == null
|
||||
|| item.getFileLastModifiedTime() != gpxFile.lastModified()
|
||||
|| itemAnalysis == null
|
||||
|| itemAnalysis.wptCategoryNames == null) {
|
||||
GPXFile f = GPXUtilities.loadGPXFile(gpxFile);
|
||||
GPXTrackAnalysis analysis = f.getAnalysis(gpxFile.lastModified());
|
||||
if (item == null) {
|
||||
item = new GpxDataItem(gpxFile, analysis);
|
||||
db.add(item);
|
||||
} else {
|
||||
db.updateAnalysis(item, analysis);
|
||||
}
|
||||
}
|
||||
processedDataFiles.put(gpxFile, item);
|
||||
if (itemAnalysis != null && itemAnalysis.wptPoints > 0) {
|
||||
gpxList.add(item);
|
||||
}
|
||||
GpxDataItem item = dbHelper.getItem(gpxFile, gpxDataItemCallback);
|
||||
publishProgress(item);
|
||||
}
|
||||
if (isCancelled()) {
|
||||
break;
|
||||
|
@ -157,14 +181,19 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(GpxDataItem... items) {
|
||||
GpxDataItem item = items[0];
|
||||
if (item != null) {
|
||||
populateList(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
asyncProcessor = null;
|
||||
adapter.notifyDataSetChanged();
|
||||
progressBar.setVisibility(View.GONE);
|
||||
lookingForTracksText.setVisibility(View.GONE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
setupHeightAndBackground(getView());
|
||||
if (dbHelper.isRead()) {
|
||||
onListPopulated();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ public class DashTrackFragment extends DashBaseFragment {
|
|||
info.subfolder = "";
|
||||
info.file = f;
|
||||
View v = inflater.inflate(R.layout.dash_gpx_track_item, null, false);
|
||||
AvailableGPXFragment.updateGpxInfoView(v, info, app, true);
|
||||
AvailableGPXFragment.updateGpxInfoView(v, info, app, true, null);
|
||||
|
||||
v.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
@ -259,7 +259,7 @@ public class DashTrackFragment extends DashBaseFragment {
|
|||
AvailableGPXFragment.GpxInfo info = new AvailableGPXFragment.GpxInfo();
|
||||
info.subfolder = "";
|
||||
info.file = f;
|
||||
AvailableGPXFragment.updateGpxInfoView(pView, info, app, true);
|
||||
AvailableGPXFragment.updateGpxInfoView(pView, info, app, true, null);
|
||||
updateShowOnMap(app, f, v, showOnMap);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -55,12 +55,13 @@ import net.osmand.data.PointDescription;
|
|||
import net.osmand.plus.ContextMenuAdapter;
|
||||
import net.osmand.plus.ContextMenuAdapter.ItemClickListener;
|
||||
import net.osmand.plus.ContextMenuItem;
|
||||
import net.osmand.plus.GPXDatabase;
|
||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||
import net.osmand.plus.GpxDbHelper.GpxDataItemCallback;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.OsmAndConstants;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
|
@ -92,7 +93,6 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
|
@ -117,7 +117,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
private Set<Integer> selectedGroups = new LinkedHashSet<>();
|
||||
private ActionMode actionMode;
|
||||
private LoadGpxTask asyncLoader;
|
||||
private ProcessGpxTask asyncProcessor;
|
||||
private GpxIndexesAdapter allGpxAdapter;
|
||||
private static MessageFormat formatMb = new MessageFormat("{0, number,##.#} MB", Locale.US);
|
||||
private ContextMenuAdapter optionsMenuAdapter;
|
||||
|
@ -193,8 +192,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
allGpxAdapter.refreshSelected();
|
||||
allGpxAdapter.notifyDataSetChanged();
|
||||
}
|
||||
asyncProcessor = new ProcessGpxTask();
|
||||
asyncProcessor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
updateCurrentTrack();
|
||||
|
||||
|
@ -210,10 +207,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
if (operationTask != null) {
|
||||
operationTask.cancel(true);
|
||||
}
|
||||
if (asyncProcessor != null) {
|
||||
asyncProcessor.cancel(false);
|
||||
asyncProcessor = null;
|
||||
}
|
||||
if (actionMode != null) {
|
||||
actionMode.finish();
|
||||
}
|
||||
|
@ -410,10 +403,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
public void reloadTracks() {
|
||||
asyncLoader = new LoadGpxTask();
|
||||
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
|
||||
if (asyncProcessor == null) {
|
||||
asyncProcessor = new ProcessGpxTask();
|
||||
asyncProcessor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -830,7 +819,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
} else if (destFolder.mkdirs()) {
|
||||
File dest = new File(destFolder, info.fileName);
|
||||
if (info.file.renameTo(dest)) {
|
||||
app.getGpxDatabase().rename(info.file, dest);
|
||||
app.getGpxDbHelper().rename(info.file, dest);
|
||||
asyncLoader = new LoadGpxTask();
|
||||
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
|
||||
} else {
|
||||
|
@ -853,7 +842,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
Toast.makeText(app, R.string.file_with_name_already_exists, Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
if (info.file.renameTo(dest)) {
|
||||
app.getGpxDatabase().rename(info.file, dest);
|
||||
app.getGpxDbHelper().rename(info.file, dest);
|
||||
asyncLoader = new LoadGpxTask();
|
||||
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
|
||||
} else {
|
||||
|
@ -994,6 +983,37 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
int corruptedColor;
|
||||
private SearchFilter filter;
|
||||
|
||||
private GpxInfoViewCallback updateGpxCallback = new GpxInfoViewCallback() {
|
||||
|
||||
private static final int UPDATE_GPX_ITEM_MSG_ID = OsmAndConstants.UI_HANDLER_LOCATION_SERVICE + 5;
|
||||
private static final long MIN_UPDATE_INTERVAL = 500;
|
||||
|
||||
private long lastUpdateTime;
|
||||
|
||||
private Runnable updateItemsProc = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (updateEnable) {
|
||||
lastUpdateTime = System.currentTimeMillis();
|
||||
allGpxAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return !updateEnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGpxDataItemChanged(GpxDataItem item) {
|
||||
if (System.currentTimeMillis() - lastUpdateTime > MIN_UPDATE_INTERVAL) {
|
||||
updateItemsProc.run();
|
||||
}
|
||||
app.runMessageInUIThreadAndCancelPrevious(UPDATE_GPX_ITEM_MSG_ID, updateItemsProc, MIN_UPDATE_INTERVAL);
|
||||
}
|
||||
};
|
||||
|
||||
public GpxIndexesAdapter(Context ctx) {
|
||||
warningColor = ContextCompat.getColor(ctx, R.color.color_warning);
|
||||
TypedArray ta = ctx.getTheme().obtainStyledAttributes(new int[]{android.R.attr.textColorPrimary});
|
||||
|
@ -1102,7 +1122,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
v = inflater.inflate(R.layout.dash_gpx_track_item, parent, false);
|
||||
}
|
||||
updateGpxInfoView(v, child, app, false);
|
||||
updateGpxInfoView(v, child, app, false, updateGpxCallback);
|
||||
|
||||
ImageView icon = (ImageView) v.findViewById(R.id.icon);
|
||||
ImageButton options = (ImageButton) v.findViewById(R.id.options);
|
||||
|
@ -1409,7 +1429,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
});
|
||||
|
||||
GPXTrackAnalysis analysis;
|
||||
if ((analysis = getGpxTrackAnalysis(gpxInfo, app)) != null) {
|
||||
if ((analysis = getGpxTrackAnalysis(gpxInfo, app, null)) != null) {
|
||||
if (analysis.totalDistance != 0 && !gpxInfo.currentlyRecordingTrack) {
|
||||
item = optionsMenu.getMenu().add(R.string.analyze_on_map).setIcon(iconsCache.getThemedIcon(R.drawable.ic_action_info_dark));
|
||||
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
|
@ -1439,7 +1459,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
LocalIndexesFragment.renameFile(getActivity(), gpxInfo.file, new RenameCallback() {
|
||||
@Override
|
||||
public void renamedTo(File file) {
|
||||
app.getGpxDatabase().rename(gpxInfo.file, file);
|
||||
app.getGpxDbHelper().rename(gpxInfo.file, file);
|
||||
asyncLoader = new LoadGpxTask();
|
||||
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
|
||||
}
|
||||
|
@ -1508,7 +1528,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
if (!isCancelled() && (info.gpx == null || !info.gpx.showCurrentTrack)) {
|
||||
boolean successfull;
|
||||
successfull = Algorithms.removeAllFiles(info.file);
|
||||
app.getGpxDatabase().remove(info.file);
|
||||
app.getGpxDbHelper().remove(info.file);
|
||||
total++;
|
||||
if (successfull) {
|
||||
count++;
|
||||
|
@ -1591,80 +1611,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
}
|
||||
}
|
||||
|
||||
public class ProcessGpxTask extends AsyncTask<Void, GpxDataItem, Void> {
|
||||
|
||||
private Map<File, GpxDataItem> processedDataFiles = new HashMap<>();
|
||||
private GPXDatabase db = app.getGpxDatabase();
|
||||
|
||||
ProcessGpxTask() {
|
||||
List<GpxDataItem> dataItems = db.getItems();
|
||||
for (GpxDataItem item : dataItems) {
|
||||
processedDataFiles.put(item.getFile(), item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
|
||||
File gpxPath = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
|
||||
if (gpxPath.canRead()) {
|
||||
processGPXFolder(gpxPath, "");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private File[] listFilesSorted(File dir) {
|
||||
File[] listFiles = dir.listFiles();
|
||||
if (listFiles == null) {
|
||||
return new File[0];
|
||||
}
|
||||
Arrays.sort(listFiles);
|
||||
return listFiles;
|
||||
}
|
||||
|
||||
private void processGPXFolder(File gpxPath, String gpxSubfolder) {
|
||||
for (File gpxFile : listFilesSorted(gpxPath)) {
|
||||
if (gpxFile.isDirectory()) {
|
||||
String sub = gpxSubfolder.length() == 0 ?
|
||||
gpxFile.getName() : gpxSubfolder + "/" + gpxFile.getName();
|
||||
processGPXFolder(gpxFile, sub);
|
||||
} else if (gpxFile.isFile() && gpxFile.getName().toLowerCase().endsWith(".gpx")) {
|
||||
GpxDataItem item = processedDataFiles.get(gpxFile);
|
||||
GPXTrackAnalysis itemAnalysis = item != null ? item.getAnalysis() : null;
|
||||
if (item == null
|
||||
|| item.getFileLastModifiedTime() != gpxFile.lastModified()
|
||||
|| itemAnalysis == null
|
||||
|| itemAnalysis.wptCategoryNames == null) {
|
||||
GPXFile f = GPXUtilities.loadGPXFile(gpxFile);
|
||||
GPXTrackAnalysis analysis = f.getAnalysis(gpxFile.lastModified());
|
||||
if (item == null) {
|
||||
item = new GpxDataItem(gpxFile, analysis);
|
||||
db.add(item);
|
||||
} else {
|
||||
db.updateAnalysis(item, analysis);
|
||||
}
|
||||
}
|
||||
processedDataFiles.put(gpxFile, item);
|
||||
publishProgress(item);
|
||||
}
|
||||
if (isCancelled()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(GpxDataItem... items) {
|
||||
allGpxAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
asyncProcessor = null;
|
||||
listView.setEmptyView(emptyView);
|
||||
}
|
||||
}
|
||||
|
||||
private class SearchFilter extends Filter {
|
||||
|
||||
@Override
|
||||
|
@ -1819,7 +1765,14 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
}
|
||||
}
|
||||
|
||||
public static void updateGpxInfoView(View v, GpxInfo child, OsmandApplication app, boolean isDashItem) {
|
||||
public interface GpxInfoViewCallback {
|
||||
|
||||
boolean isCancelled();
|
||||
|
||||
void onGpxDataItemChanged(GpxDataItem item);
|
||||
}
|
||||
|
||||
public static void updateGpxInfoView(View v, GpxInfo child, OsmandApplication app, boolean isDashItem, @Nullable GpxInfoViewCallback callback) {
|
||||
TextView viewName = ((TextView) v.findViewById(R.id.name));
|
||||
if (!isDashItem) {
|
||||
v.findViewById(R.id.divider_list).setVisibility(View.VISIBLE);
|
||||
|
@ -1843,7 +1796,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
if (getSelectedGpxFile(child, app) != null) {
|
||||
icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_polygom_dark, R.color.color_distance));
|
||||
}
|
||||
GPXTrackAnalysis analysis = getGpxTrackAnalysis(child, app);
|
||||
GPXTrackAnalysis analysis = getGpxTrackAnalysis(child, app, callback);
|
||||
boolean sectionRead = analysis == null;
|
||||
if (sectionRead) {
|
||||
v.findViewById(R.id.read_section).setVisibility(View.GONE);
|
||||
|
@ -1911,15 +1864,29 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
|||
}
|
||||
|
||||
@Nullable
|
||||
private static GPXTrackAnalysis getGpxTrackAnalysis(GpxInfo gpxInfo, OsmandApplication app) {
|
||||
private static GPXTrackAnalysis getGpxTrackAnalysis(GpxInfo gpxInfo, OsmandApplication app, @Nullable final GpxInfoViewCallback callback) {
|
||||
SelectedGpxFile sgpx = getSelectedGpxFile(gpxInfo, app);
|
||||
GPXTrackAnalysis analysis = null;
|
||||
if (sgpx != null) {
|
||||
analysis = sgpx.getTrackAnalysis();
|
||||
} else if (gpxInfo.currentlyRecordingTrack) {
|
||||
analysis = app.getSavingTrackHelper().getCurrentTrack().getTrackAnalysis();
|
||||
} else {
|
||||
GpxDataItem dataItem = gpxInfo.file == null ? null : app.getGpxDatabase().getItem(gpxInfo.file);
|
||||
} else if (gpxInfo.file != null) {
|
||||
GpxDataItemCallback analyserCallback = null;
|
||||
if (callback != null) {
|
||||
analyserCallback = new GpxDataItemCallback() {
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return callback.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGpxDataItemReady(GpxDataItem item) {
|
||||
callback.onGpxDataItemChanged(item);
|
||||
}
|
||||
};
|
||||
}
|
||||
GpxDataItem dataItem = app.getGpxDbHelper().getItem(gpxInfo.file, analyserCallback);
|
||||
if (dataItem != null) {
|
||||
analysis = dataItem.getAnalysis();
|
||||
}
|
||||
|
|
|
@ -381,12 +381,12 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener {
|
|||
if (clr != 0 && sf.getModifiableGpxFile() != null) {
|
||||
sf.getModifiableGpxFile().setColor(clr);
|
||||
if (getGpxDataItem() != null) {
|
||||
app.getGpxDatabase().updateColor(getGpxDataItem(), clr);
|
||||
app.getGpxDbHelper().updateColor(getGpxDataItem(), clr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (getGpxDataItem() != null) {
|
||||
app.getGpxDatabase().updateColor(getGpxDataItem(), clr);
|
||||
app.getGpxDbHelper().updateColor(getGpxDataItem(), clr);
|
||||
}
|
||||
if (gpx != null && gpx.showCurrentTrack) {
|
||||
app.getSettings().CURRENT_TRACK_COLOR.set(clr);
|
||||
|
@ -846,7 +846,7 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener {
|
|||
}
|
||||
GpxDataItem item = getGpxDataItem();
|
||||
if (item != null) {
|
||||
app.getGpxDatabase().updateSplit(item, splitType, splitInterval);
|
||||
app.getGpxDbHelper().updateSplit(item, splitType, splitInterval);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import android.widget.ImageView;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||
import net.osmand.plus.R;
|
||||
|
@ -28,7 +27,6 @@ public class TracksCard extends BaseCard {
|
|||
|
||||
private List<GPXFile> gpxFiles;
|
||||
private boolean showLimited = true;
|
||||
private List<GpxDataItem> dataItems;
|
||||
|
||||
private static class GpxItem {
|
||||
String title;
|
||||
|
@ -45,7 +43,6 @@ public class TracksCard extends BaseCard {
|
|||
public TracksCard(MapActivity mapActivity, List<GPXFile> gpxFiles) {
|
||||
super(mapActivity);
|
||||
this.gpxFiles = gpxFiles;
|
||||
this.dataItems = app.getGpxDatabase().getItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -54,12 +51,7 @@ public class TracksCard extends BaseCard {
|
|||
}
|
||||
|
||||
private GpxDataItem getDataItem(GPXInfo info) {
|
||||
for (GpxDataItem item : dataItems) {
|
||||
if (item.getFile().getAbsolutePath().endsWith(info.getFileName())) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return app.getGpxDbHelper().getItem(new File(info.getFileName()));
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
|
|
Loading…
Reference in a new issue