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) {
|
if (!destinationExists) {
|
||||||
GpxDataItem gpxDataItem = new GpxDataItem(destination, col);
|
GpxDataItem gpxDataItem = new GpxDataItem(destination, col);
|
||||||
gpxDataItem.setApiImported(true);
|
gpxDataItem.setApiImported(true);
|
||||||
app.getGpxDatabase().add(gpxDataItem);
|
app.getGpxDbHelper().add(gpxDataItem);
|
||||||
} else {
|
} else {
|
||||||
GpxDataItem item = app.getGpxDatabase().getItem(destination);
|
GpxDataItem item = app.getGpxDbHelper().getItem(destination);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
app.getGpxDatabase().updateColor(item, col);
|
app.getGpxDbHelper().updateColor(item, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final GpxSelectionHelper helper = app.getSelectedGpxHelper();
|
final GpxSelectionHelper helper = app.getSelectedGpxHelper();
|
||||||
|
@ -1435,7 +1435,7 @@ public class OsmandAidlApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean getImportedGpxV2(List<net.osmand.aidlapi.gpx.AGpxFile> files) {
|
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) {
|
for (GpxDataItem dataItem : gpxDataItems) {
|
||||||
File file = dataItem.getFile();
|
File file = dataItem.getFile();
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
|
@ -1460,7 +1460,7 @@ public class OsmandAidlApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean getImportedGpx(List<AGpxFile> files) {
|
boolean getImportedGpx(List<AGpxFile> files) {
|
||||||
List<GpxDataItem> gpxDataItems = app.getGpxDatabase().getItems();
|
List<GpxDataItem> gpxDataItems = app.getGpxDbHelper().getItems();
|
||||||
for (GpxDataItem dataItem : gpxDataItems) {
|
for (GpxDataItem dataItem : gpxDataItems) {
|
||||||
File file = dataItem.getFile();
|
File file = dataItem.getFile();
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
|
@ -1480,7 +1480,7 @@ public class OsmandAidlApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
String getGpxColor(String gpxFileName) {
|
String getGpxColor(String gpxFileName) {
|
||||||
List<GpxDataItem> gpxDataItems = app.getGpxDatabase().getItems();
|
List<GpxDataItem> gpxDataItems = app.getGpxDbHelper().getItems();
|
||||||
for (GpxDataItem dataItem : gpxDataItems) {
|
for (GpxDataItem dataItem : gpxDataItems) {
|
||||||
File file = dataItem.getFile();
|
File file = dataItem.getFile();
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
|
@ -1499,10 +1499,10 @@ public class OsmandAidlApi {
|
||||||
if (!Algorithms.isEmpty(fileName)) {
|
if (!Algorithms.isEmpty(fileName)) {
|
||||||
final File f = app.getAppPath(IndexConstants.GPX_INDEX_DIR + fileName);
|
final File f = app.getAppPath(IndexConstants.GPX_INDEX_DIR + fileName);
|
||||||
if (f.exists()) {
|
if (f.exists()) {
|
||||||
GpxDataItem item = app.getGpxDatabase().getItem(f);
|
GpxDataItem item = app.getGpxDbHelper().getItem(f);
|
||||||
if (item != null && item.isApiImported()) {
|
if (item != null && item.isApiImported()) {
|
||||||
Algorithms.removeAllFiles(f);
|
Algorithms.removeAllFiles(f);
|
||||||
app.getGpxDatabase().remove(f);
|
app.getGpxDbHelper().remove(f);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -482,7 +482,7 @@ public class AppInitializer implements IProgress {
|
||||||
app.notificationHelper = startupInit(new NotificationHelper(app), NotificationHelper.class);
|
app.notificationHelper = startupInit(new NotificationHelper(app), NotificationHelper.class);
|
||||||
app.liveMonitoringHelper = startupInit(new LiveMonitoringHelper(app), LiveMonitoringHelper.class);
|
app.liveMonitoringHelper = startupInit(new LiveMonitoringHelper(app), LiveMonitoringHelper.class);
|
||||||
app.selectedGpxHelper = startupInit(new GpxSelectionHelper(app, app.savingTrackHelper), GpxSelectionHelper.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.favorites = startupInit(new FavouritesDbHelper(app), FavouritesDbHelper.class);
|
||||||
app.waypointHelper = startupInit(new WaypointHelper(app), WaypointHelper.class);
|
app.waypointHelper = startupInit(new WaypointHelper(app), WaypointHelper.class);
|
||||||
app.aidlApi = startupInit(new OsmandAidlApi(app), OsmandAidlApi.class);
|
app.aidlApi = startupInit(new OsmandAidlApi(app), OsmandAidlApi.class);
|
||||||
|
@ -669,6 +669,7 @@ public class AppInitializer implements IProgress {
|
||||||
notifyEvent(InitEvents.NATIVE_INITIALIZED);
|
notifyEvent(InitEvents.NATIVE_INITIALIZED);
|
||||||
|
|
||||||
app.favorites.loadFavorites();
|
app.favorites.loadFavorites();
|
||||||
|
app.gpxDbHelper.loadGpxItems();
|
||||||
notifyEvent(InitEvents.FAVORITES_INITIALIZED);
|
notifyEvent(InitEvents.FAVORITES_INITIALIZED);
|
||||||
app.poiFilters.reloadAllPoiFilters();
|
app.poiFilters.reloadAllPoiFilters();
|
||||||
app.poiFilters.loadSelectedPoiFilters();
|
app.poiFilters.loadSelectedPoiFilters();
|
||||||
|
|
|
@ -199,13 +199,35 @@ public class GPXDatabase {
|
||||||
public void setShowAsMarkers(boolean showAsMarkers) {
|
public void setShowAsMarkers(boolean showAsMarkers) {
|
||||||
this.showAsMarkers = showAsMarkers;
|
this.showAsMarkers = showAsMarkers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return file != null ? file.hashCode() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GPXDatabase(OsmandApplication app) {
|
@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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GPXDatabase(OsmandApplication app) {
|
||||||
context = 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);
|
SQLiteConnection conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly);
|
||||||
if (conn.getVersion() < DB_VERSION) {
|
if (conn.getVersion() < DB_VERSION) {
|
||||||
if (readonly) {
|
if (readonly) {
|
||||||
|
@ -225,6 +247,7 @@ public class GPXDatabase {
|
||||||
|
|
||||||
private void onCreate(SQLiteConnection db) {
|
private void onCreate(SQLiteConnection db) {
|
||||||
db.execSQL(GPX_TABLE_CREATE);
|
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) {
|
private void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) {
|
||||||
|
@ -401,7 +424,7 @@ public class GPXDatabase {
|
||||||
|
|
||||||
public boolean remove(File file) {
|
public boolean remove(File file) {
|
||||||
SQLiteConnection db = openConnection(false);
|
SQLiteConnection db = openConnection(false);
|
||||||
if (db != null){
|
if (db != null) {
|
||||||
try {
|
try {
|
||||||
String fileName = getFileName(file);
|
String fileName = getFileName(file);
|
||||||
String fileDir = getFileDir(file);
|
String fileDir = getFileDir(file);
|
||||||
|
@ -421,7 +444,7 @@ public class GPXDatabase {
|
||||||
|
|
||||||
public boolean add(GpxDataItem item) {
|
public boolean add(GpxDataItem item) {
|
||||||
SQLiteConnection db = openConnection(false);
|
SQLiteConnection db = openConnection(false);
|
||||||
if (db != null){
|
if (db != null) {
|
||||||
try {
|
try {
|
||||||
insert(item, db);
|
insert(item, db);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -442,7 +465,7 @@ public class GPXDatabase {
|
||||||
"" : itemFile.getParentFile().getName();
|
"" : itemFile.getParentFile().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insert(GpxDataItem item, SQLiteConnection db) {
|
void insert(GpxDataItem item, SQLiteConnection db) {
|
||||||
String fileName = getFileName(item.file);
|
String fileName = getFileName(item.file);
|
||||||
String fileDir = getFileDir(item.file);
|
String fileDir = getFileDir(item.file);
|
||||||
GPXTrackAnalysis a = item.getAnalysis();
|
GPXTrackAnalysis a = item.getAnalysis();
|
||||||
|
@ -482,22 +505,30 @@ public class GPXDatabase {
|
||||||
SQLiteConnection db = openConnection(false);
|
SQLiteConnection db = openConnection(false);
|
||||||
if (db != null) {
|
if (db != null) {
|
||||||
try {
|
try {
|
||||||
String fileName = getFileName(item.file);
|
return updateAnalysis(item, a, db);
|
||||||
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 });
|
|
||||||
} finally {
|
} finally {
|
||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
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) {
|
public boolean clearAnalysis(GpxDataItem item) {
|
||||||
SQLiteConnection db = openConnection(false);
|
SQLiteConnection db = openConnection(false);
|
||||||
if (db != null) {
|
if (db != null) {
|
||||||
|
@ -584,20 +615,24 @@ public class GPXDatabase {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public List<GpxDataItem> getItems() {
|
public List<GpxDataItem> getItems() {
|
||||||
List<GpxDataItem> items = new ArrayList<>();
|
List<GpxDataItem> items = new ArrayList<>();
|
||||||
SQLiteConnection db = openConnection(true);
|
SQLiteConnection db = openConnection(false);
|
||||||
if (db != null) {
|
if (db != null) {
|
||||||
try {
|
try {
|
||||||
SQLiteCursor query = db.rawQuery(GPX_TABLE_SELECT, null);
|
SQLiteCursor query = db.rawQuery(GPX_TABLE_SELECT, null);
|
||||||
if (query != null && query.moveToFirst()) {
|
if (query != null) {
|
||||||
|
try {
|
||||||
|
if (query.moveToFirst()) {
|
||||||
do {
|
do {
|
||||||
items.add(readItem(query));
|
items.add(readItem(query));
|
||||||
} while (query.moveToNext());
|
} while (query.moveToNext());
|
||||||
}
|
}
|
||||||
if (query != null) {
|
} finally {
|
||||||
query.close();
|
query.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
@ -608,23 +643,58 @@ public class GPXDatabase {
|
||||||
@Nullable
|
@Nullable
|
||||||
public GpxDataItem getItem(File file) {
|
public GpxDataItem getItem(File file) {
|
||||||
GpxDataItem result = null;
|
GpxDataItem result = null;
|
||||||
SQLiteConnection db = openConnection(true);
|
SQLiteConnection db = openConnection(false);
|
||||||
if (db != null){
|
if (db != null) {
|
||||||
try {
|
try {
|
||||||
String fileName = getFileName(file);
|
result = getItem(file, db);
|
||||||
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();
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
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,9 +152,8 @@ public class GpxSelectionHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processSplit() {
|
public void processSplit() {
|
||||||
List<GpxDataItem> items = app.getGpxDatabase().getItems();
|
List<GpxDataItem> items = app.getGpxDbHelper().getSplitItems();
|
||||||
for (GpxDataItem dataItem : items) {
|
for (GpxDataItem dataItem : items) {
|
||||||
if (dataItem.getSplitType() != 0) {
|
|
||||||
SelectedGpxFile selectedGpxFile = getSelectedFileByPath(dataItem.getFile().getAbsolutePath());
|
SelectedGpxFile selectedGpxFile = getSelectedFileByPath(dataItem.getFile().getAbsolutePath());
|
||||||
if (selectedGpxFile != null && selectedGpxFile.getGpxFile() != null) {
|
if (selectedGpxFile != null && selectedGpxFile.getGpxFile() != null) {
|
||||||
GPXFile gpxFile = selectedGpxFile.getGpxFile();
|
GPXFile gpxFile = selectedGpxFile.getGpxFile();
|
||||||
|
@ -178,7 +177,6 @@ public class GpxSelectionHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private String getString(int resId, Object... formatArgs) {
|
private String getString(int resId, Object... formatArgs) {
|
||||||
return app.getString(resId, formatArgs);
|
return app.getString(resId, formatArgs);
|
||||||
|
@ -622,7 +620,7 @@ public class GpxSelectionHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SelectedGpxFile selectGpxFile(GPXFile gpx, boolean show, boolean notShowNavigationDialog, boolean syncGroup, boolean selectedByUser, boolean canAddToMarkers) {
|
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()) {
|
if (canAddToMarkers && show && dataItem != null && dataItem.isShowAsMarkers()) {
|
||||||
app.getMapMarkersHelper().addOrEnableGroup(gpx);
|
app.getMapMarkersHelper().addOrEnableGroup(gpx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,9 +370,9 @@ public class MapMarkersHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateGpxShowAsMarkers(File file) {
|
private void updateGpxShowAsMarkers(File file) {
|
||||||
GPXDatabase.GpxDataItem dataItem = ctx.getGpxDatabase().getItem(file);
|
GPXDatabase.GpxDataItem dataItem = ctx.getGpxDbHelper().getItem(file);
|
||||||
if (dataItem != null) {
|
if (dataItem != null) {
|
||||||
ctx.getGpxDatabase().updateShowAsMarkers(dataItem, true);
|
ctx.getGpxDbHelper().updateShowAsMarkers(dataItem, true);
|
||||||
dataItem.setShowAsMarkers(true);
|
dataItem.setShowAsMarkers(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,6 @@ public class OsmandApplication extends MultiDexApplication {
|
||||||
FavouritesDbHelper favorites;
|
FavouritesDbHelper favorites;
|
||||||
CommandPlayer player;
|
CommandPlayer player;
|
||||||
GpxSelectionHelper selectedGpxHelper;
|
GpxSelectionHelper selectedGpxHelper;
|
||||||
GPXDatabase gpxDatabase;
|
|
||||||
SavingTrackHelper savingTrackHelper;
|
SavingTrackHelper savingTrackHelper;
|
||||||
AnalyticsHelper analyticsHelper;
|
AnalyticsHelper analyticsHelper;
|
||||||
NotificationHelper notificationHelper;
|
NotificationHelper notificationHelper;
|
||||||
|
@ -137,6 +136,7 @@ public class OsmandApplication extends MultiDexApplication {
|
||||||
MapViewTrackingUtilities mapViewTrackingUtilities;
|
MapViewTrackingUtilities mapViewTrackingUtilities;
|
||||||
LockHelper lockHelper;
|
LockHelper lockHelper;
|
||||||
SettingsHelper settingsHelper;
|
SettingsHelper settingsHelper;
|
||||||
|
GpxDbHelper gpxDbHelper;
|
||||||
|
|
||||||
private RoutingConfiguration.Builder routingConfig;
|
private RoutingConfiguration.Builder routingConfig;
|
||||||
private Locale preferredLocale = null;
|
private Locale preferredLocale = null;
|
||||||
|
@ -316,8 +316,8 @@ public class OsmandApplication extends MultiDexApplication {
|
||||||
return selectedGpxHelper;
|
return selectedGpxHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GPXDatabase getGpxDatabase() {
|
public GpxDbHelper getGpxDbHelper() {
|
||||||
return gpxDatabase;
|
return gpxDbHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FavouritesDbHelper getFavorites() {
|
public FavouritesDbHelper getFavorites() {
|
||||||
|
|
|
@ -235,7 +235,7 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
|
||||||
GPXFile gpx = data.get(f);
|
GPXFile gpx = data.get(f);
|
||||||
GPXTrackAnalysis analysis = gpx.getAnalysis(fout.lastModified());
|
GPXTrackAnalysis analysis = gpx.getAnalysis(fout.lastModified());
|
||||||
GpxDataItem item = new GpxDataItem(fout, analysis);
|
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) {
|
private void onGPXFileReady(@Nullable GPXFile gpxFile) {
|
||||||
setGpx(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);
|
WindowManager mgr = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
|
||||||
if (gpxFile != null && mgr != null) {
|
if (gpxFile != null && mgr != null) {
|
||||||
|
|
|
@ -73,7 +73,10 @@ import net.osmand.PlatformUtil;
|
||||||
import net.osmand.plus.ContextMenuAdapter;
|
import net.osmand.plus.ContextMenuAdapter;
|
||||||
import net.osmand.plus.ContextMenuItem;
|
import net.osmand.plus.ContextMenuItem;
|
||||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
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.GpxSelectionHelper.SelectedGpxFile;
|
||||||
|
import net.osmand.plus.OsmAndConstants;
|
||||||
import net.osmand.plus.OsmAndFormatter;
|
import net.osmand.plus.OsmAndFormatter;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.OsmandPlugin;
|
import net.osmand.plus.OsmandPlugin;
|
||||||
|
@ -437,6 +440,59 @@ public class GpxUiHelper {
|
||||||
return dlg;
|
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,
|
private static AlertDialog createDialog(final Activity activity,
|
||||||
final boolean showCurrentGpx,
|
final boolean showCurrentGpx,
|
||||||
final boolean multipleChoice,
|
final boolean multipleChoice,
|
||||||
|
@ -451,12 +507,11 @@ public class GpxUiHelper {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(activity, themeRes));
|
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(activity, themeRes));
|
||||||
final int layout = R.layout.gpx_track_item;
|
final int layout = R.layout.gpx_track_item;
|
||||||
final Map<String, String> gpxAppearanceParams = new HashMap<>();
|
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,
|
final ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(activity, layout, R.id.title,
|
||||||
adapter.getItemNames()) {
|
adapter.getItemNames()) {
|
||||||
|
|
||||||
List<GpxDataItem> dataItems = null;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemViewType(int position) {
|
public int getItemViewType(int position) {
|
||||||
return showCurrentGpx && position == 0 ? 1 : 0;
|
return showCurrentGpx && position == 0 ? 1 : 0;
|
||||||
|
@ -468,18 +523,14 @@ public class GpxUiHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private GpxDataItem getDataItem(GPXInfo info) {
|
private GpxDataItem getDataItem(GPXInfo info) {
|
||||||
if (dataItems != null) {
|
return app.getGpxDbHelper().getItem(
|
||||||
for (GpxDataItem item : dataItems) {
|
new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), info.getFileName()),
|
||||||
if (item.getFile().getAbsolutePath().endsWith(info.fileName)) {
|
gpxDataItemCallback);
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
// User super class to create the View
|
||||||
View v = convertView;
|
View v = convertView;
|
||||||
boolean checkLayout = getItemViewType(position) == 0;
|
boolean checkLayout = getItemViewType(position) == 0;
|
||||||
|
@ -487,13 +538,10 @@ public class GpxUiHelper {
|
||||||
v = View.inflate(new ContextThemeWrapper(activity, themeRes), layout, null);
|
v = View.inflate(new ContextThemeWrapper(activity, themeRes), layout, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataItems == null) {
|
|
||||||
dataItems = app.getGpxDatabase().getItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
final ContextMenuItem item = adapter.getItem(position);
|
final ContextMenuItem item = adapter.getItem(position);
|
||||||
GPXInfo info = list.get(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) {
|
if (item.getSelected() == null) {
|
||||||
v.findViewById(R.id.check_item).setVisibility(View.GONE);
|
v.findViewById(R.id.check_item).setVisibility(View.GONE);
|
||||||
|
@ -535,6 +583,7 @@ public class GpxUiHelper {
|
||||||
public void onClick(DialogInterface dialog, int position) {
|
public void onClick(DialogInterface dialog, int position) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
gpxDataItemCallback.setListAdapter(listAdapter);
|
||||||
builder.setAdapter(listAdapter, onClickListener);
|
builder.setAdapter(listAdapter, onClickListener);
|
||||||
if (multipleChoice) {
|
if (multipleChoice) {
|
||||||
if (showAppearanceSetting) {
|
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();
|
dlg.show();
|
||||||
try {
|
try {
|
||||||
dlg.getListView().setFastScrollEnabled(true);
|
dlg.getListView().setFastScrollEnabled(true);
|
||||||
|
|
|
@ -17,8 +17,6 @@ import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.text.SpannableStringBuilder;
|
|
||||||
import android.text.Spanned;
|
|
||||||
import android.text.style.ForegroundColorSpan;
|
import android.text.style.ForegroundColorSpan;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
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.DividerHalfItem;
|
||||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem;
|
import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem;
|
||||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||||
import net.osmand.plus.myplaces.FavoritesActivity;
|
|
||||||
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
||||||
import net.osmand.plus.views.OsmandMapTileView;
|
import net.osmand.plus.views.OsmandMapTileView;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
@ -630,11 +627,11 @@ public class ImportHelper {
|
||||||
File file = new File(gpxFile.path);
|
File file = new File(gpxFile.path);
|
||||||
if (!destinationExists) {
|
if (!destinationExists) {
|
||||||
GPXDatabase.GpxDataItem item = new GPXDatabase.GpxDataItem(file, gpxFile.getColor(0));
|
GPXDatabase.GpxDataItem item = new GPXDatabase.GpxDataItem(file, gpxFile.getColor(0));
|
||||||
app.getGpxDatabase().add(item);
|
app.getGpxDbHelper().add(item);
|
||||||
} else {
|
} else {
|
||||||
GPXDatabase.GpxDataItem item = app.getGpxDatabase().getItem(file);
|
GPXDatabase.GpxDataItem item = app.getGpxDbHelper().getItem(file);
|
||||||
if (item != null) {
|
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.annotation.SuppressLint;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -13,8 +14,9 @@ import net.osmand.GPXUtilities;
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
||||||
import net.osmand.IndexConstants;
|
import net.osmand.IndexConstants;
|
||||||
import net.osmand.plus.GPXDatabase;
|
|
||||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
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.GpxSelectionHelper;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
|
@ -24,18 +26,47 @@ import net.osmand.plus.mapmarkers.adapters.TracksGroupsAdapter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheetDialogFragment {
|
public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheetDialogFragment {
|
||||||
|
|
||||||
|
private OsmandApplication app;
|
||||||
|
private GpxDbHelper dbHelper;
|
||||||
|
|
||||||
private ProcessGpxTask asyncProcessor;
|
private ProcessGpxTask asyncProcessor;
|
||||||
private List<GpxDataItem> gpxList;
|
private List<GpxDataItem> gpxList;
|
||||||
|
|
||||||
|
private ProgressBar progressBar;
|
||||||
|
private RecyclerView recyclerView;
|
||||||
|
private TextView lookingForTracksText;
|
||||||
|
|
||||||
|
private GpxDataItemCallback gpxDataItemCallback = new GpxDataItemCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
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(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, 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 = new ProcessGpxTask();
|
||||||
asyncProcessor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
asyncProcessor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
@ -82,22 +113,32 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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")
|
@SuppressLint("StaticFieldLeak")
|
||||||
public class ProcessGpxTask extends AsyncTask<Void, GpxDataItem, Void> {
|
private 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPreExecute() {
|
protected void onPreExecute() {
|
||||||
|
@ -131,25 +172,8 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet
|
||||||
gpxFile.getName() : gpxSubfolder + "/" + gpxFile.getName();
|
gpxFile.getName() : gpxSubfolder + "/" + gpxFile.getName();
|
||||||
processGPXFolder(gpxFile, sub);
|
processGPXFolder(gpxFile, sub);
|
||||||
} else if (gpxFile.isFile() && gpxFile.getName().toLowerCase().endsWith(".gpx")) {
|
} else if (gpxFile.isFile() && gpxFile.getName().toLowerCase().endsWith(".gpx")) {
|
||||||
GpxDataItem item = processedDataFiles.get(gpxFile);
|
GpxDataItem item = dbHelper.getItem(gpxFile, gpxDataItemCallback);
|
||||||
GPXTrackAnalysis itemAnalysis = item != null ? item.getAnalysis() : null;
|
publishProgress(item);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
break;
|
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
|
@Override
|
||||||
protected void onPostExecute(Void aVoid) {
|
protected void onPostExecute(Void aVoid) {
|
||||||
asyncProcessor = null;
|
if (dbHelper.isRead()) {
|
||||||
adapter.notifyDataSetChanged();
|
onListPopulated();
|
||||||
progressBar.setVisibility(View.GONE);
|
}
|
||||||
lookingForTracksText.setVisibility(View.GONE);
|
|
||||||
recyclerView.setVisibility(View.VISIBLE);
|
|
||||||
setupHeightAndBackground(getView());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,7 +167,7 @@ public class DashTrackFragment extends DashBaseFragment {
|
||||||
info.subfolder = "";
|
info.subfolder = "";
|
||||||
info.file = f;
|
info.file = f;
|
||||||
View v = inflater.inflate(R.layout.dash_gpx_track_item, null, false);
|
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() {
|
v.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -259,7 +259,7 @@ public class DashTrackFragment extends DashBaseFragment {
|
||||||
AvailableGPXFragment.GpxInfo info = new AvailableGPXFragment.GpxInfo();
|
AvailableGPXFragment.GpxInfo info = new AvailableGPXFragment.GpxInfo();
|
||||||
info.subfolder = "";
|
info.subfolder = "";
|
||||||
info.file = f;
|
info.file = f;
|
||||||
AvailableGPXFragment.updateGpxInfoView(pView, info, app, true);
|
AvailableGPXFragment.updateGpxInfoView(pView, info, app, true, null);
|
||||||
updateShowOnMap(app, f, v, showOnMap);
|
updateShowOnMap(app, f, v, showOnMap);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -55,12 +55,13 @@ import net.osmand.data.PointDescription;
|
||||||
import net.osmand.plus.ContextMenuAdapter;
|
import net.osmand.plus.ContextMenuAdapter;
|
||||||
import net.osmand.plus.ContextMenuAdapter.ItemClickListener;
|
import net.osmand.plus.ContextMenuAdapter.ItemClickListener;
|
||||||
import net.osmand.plus.ContextMenuItem;
|
import net.osmand.plus.ContextMenuItem;
|
||||||
import net.osmand.plus.GPXDatabase;
|
|
||||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||||
|
import net.osmand.plus.GpxDbHelper.GpxDataItemCallback;
|
||||||
import net.osmand.plus.GpxSelectionHelper;
|
import net.osmand.plus.GpxSelectionHelper;
|
||||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
||||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||||
|
import net.osmand.plus.OsmAndConstants;
|
||||||
import net.osmand.plus.OsmAndFormatter;
|
import net.osmand.plus.OsmAndFormatter;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.OsmandPlugin;
|
import net.osmand.plus.OsmandPlugin;
|
||||||
|
@ -92,7 +93,6 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
@ -117,7 +117,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
||||||
private Set<Integer> selectedGroups = new LinkedHashSet<>();
|
private Set<Integer> selectedGroups = new LinkedHashSet<>();
|
||||||
private ActionMode actionMode;
|
private ActionMode actionMode;
|
||||||
private LoadGpxTask asyncLoader;
|
private LoadGpxTask asyncLoader;
|
||||||
private ProcessGpxTask asyncProcessor;
|
|
||||||
private GpxIndexesAdapter allGpxAdapter;
|
private GpxIndexesAdapter allGpxAdapter;
|
||||||
private static MessageFormat formatMb = new MessageFormat("{0, number,##.#} MB", Locale.US);
|
private static MessageFormat formatMb = new MessageFormat("{0, number,##.#} MB", Locale.US);
|
||||||
private ContextMenuAdapter optionsMenuAdapter;
|
private ContextMenuAdapter optionsMenuAdapter;
|
||||||
|
@ -193,8 +192,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
||||||
allGpxAdapter.refreshSelected();
|
allGpxAdapter.refreshSelected();
|
||||||
allGpxAdapter.notifyDataSetChanged();
|
allGpxAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
asyncProcessor = new ProcessGpxTask();
|
|
||||||
asyncProcessor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
|
||||||
}
|
}
|
||||||
updateCurrentTrack();
|
updateCurrentTrack();
|
||||||
|
|
||||||
|
@ -210,10 +207,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
||||||
if (operationTask != null) {
|
if (operationTask != null) {
|
||||||
operationTask.cancel(true);
|
operationTask.cancel(true);
|
||||||
}
|
}
|
||||||
if (asyncProcessor != null) {
|
|
||||||
asyncProcessor.cancel(false);
|
|
||||||
asyncProcessor = null;
|
|
||||||
}
|
|
||||||
if (actionMode != null) {
|
if (actionMode != null) {
|
||||||
actionMode.finish();
|
actionMode.finish();
|
||||||
}
|
}
|
||||||
|
@ -410,10 +403,6 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
||||||
public void reloadTracks() {
|
public void reloadTracks() {
|
||||||
asyncLoader = new LoadGpxTask();
|
asyncLoader = new LoadGpxTask();
|
||||||
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
|
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
|
||||||
if (asyncProcessor == null) {
|
|
||||||
asyncProcessor = new ProcessGpxTask();
|
|
||||||
asyncProcessor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -830,7 +819,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
||||||
} else if (destFolder.mkdirs()) {
|
} else if (destFolder.mkdirs()) {
|
||||||
File dest = new File(destFolder, info.fileName);
|
File dest = new File(destFolder, info.fileName);
|
||||||
if (info.file.renameTo(dest)) {
|
if (info.file.renameTo(dest)) {
|
||||||
app.getGpxDatabase().rename(info.file, dest);
|
app.getGpxDbHelper().rename(info.file, dest);
|
||||||
asyncLoader = new LoadGpxTask();
|
asyncLoader = new LoadGpxTask();
|
||||||
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
|
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
|
||||||
} else {
|
} 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();
|
Toast.makeText(app, R.string.file_with_name_already_exists, Toast.LENGTH_LONG).show();
|
||||||
} else {
|
} else {
|
||||||
if (info.file.renameTo(dest)) {
|
if (info.file.renameTo(dest)) {
|
||||||
app.getGpxDatabase().rename(info.file, dest);
|
app.getGpxDbHelper().rename(info.file, dest);
|
||||||
asyncLoader = new LoadGpxTask();
|
asyncLoader = new LoadGpxTask();
|
||||||
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
|
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
|
||||||
} else {
|
} else {
|
||||||
|
@ -994,6 +983,37 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
||||||
int corruptedColor;
|
int corruptedColor;
|
||||||
private SearchFilter filter;
|
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) {
|
public GpxIndexesAdapter(Context ctx) {
|
||||||
warningColor = ContextCompat.getColor(ctx, R.color.color_warning);
|
warningColor = ContextCompat.getColor(ctx, R.color.color_warning);
|
||||||
TypedArray ta = ctx.getTheme().obtainStyledAttributes(new int[]{android.R.attr.textColorPrimary});
|
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();
|
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||||
v = inflater.inflate(R.layout.dash_gpx_track_item, parent, false);
|
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);
|
ImageView icon = (ImageView) v.findViewById(R.id.icon);
|
||||||
ImageButton options = (ImageButton) v.findViewById(R.id.options);
|
ImageButton options = (ImageButton) v.findViewById(R.id.options);
|
||||||
|
@ -1409,7 +1429,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
||||||
});
|
});
|
||||||
|
|
||||||
GPXTrackAnalysis analysis;
|
GPXTrackAnalysis analysis;
|
||||||
if ((analysis = getGpxTrackAnalysis(gpxInfo, app)) != null) {
|
if ((analysis = getGpxTrackAnalysis(gpxInfo, app, null)) != null) {
|
||||||
if (analysis.totalDistance != 0 && !gpxInfo.currentlyRecordingTrack) {
|
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 = optionsMenu.getMenu().add(R.string.analyze_on_map).setIcon(iconsCache.getThemedIcon(R.drawable.ic_action_info_dark));
|
||||||
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
|
@ -1439,7 +1459,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
||||||
LocalIndexesFragment.renameFile(getActivity(), gpxInfo.file, new RenameCallback() {
|
LocalIndexesFragment.renameFile(getActivity(), gpxInfo.file, new RenameCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void renamedTo(File file) {
|
public void renamedTo(File file) {
|
||||||
app.getGpxDatabase().rename(gpxInfo.file, file);
|
app.getGpxDbHelper().rename(gpxInfo.file, file);
|
||||||
asyncLoader = new LoadGpxTask();
|
asyncLoader = new LoadGpxTask();
|
||||||
asyncLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, getActivity());
|
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)) {
|
if (!isCancelled() && (info.gpx == null || !info.gpx.showCurrentTrack)) {
|
||||||
boolean successfull;
|
boolean successfull;
|
||||||
successfull = Algorithms.removeAllFiles(info.file);
|
successfull = Algorithms.removeAllFiles(info.file);
|
||||||
app.getGpxDatabase().remove(info.file);
|
app.getGpxDbHelper().remove(info.file);
|
||||||
total++;
|
total++;
|
||||||
if (successfull) {
|
if (successfull) {
|
||||||
count++;
|
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 {
|
private class SearchFilter extends Filter {
|
||||||
|
|
||||||
@Override
|
@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));
|
TextView viewName = ((TextView) v.findViewById(R.id.name));
|
||||||
if (!isDashItem) {
|
if (!isDashItem) {
|
||||||
v.findViewById(R.id.divider_list).setVisibility(View.VISIBLE);
|
v.findViewById(R.id.divider_list).setVisibility(View.VISIBLE);
|
||||||
|
@ -1843,7 +1796,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
||||||
if (getSelectedGpxFile(child, app) != null) {
|
if (getSelectedGpxFile(child, app) != null) {
|
||||||
icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_polygom_dark, R.color.color_distance));
|
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;
|
boolean sectionRead = analysis == null;
|
||||||
if (sectionRead) {
|
if (sectionRead) {
|
||||||
v.findViewById(R.id.read_section).setVisibility(View.GONE);
|
v.findViewById(R.id.read_section).setVisibility(View.GONE);
|
||||||
|
@ -1911,15 +1864,29 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@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);
|
SelectedGpxFile sgpx = getSelectedGpxFile(gpxInfo, app);
|
||||||
GPXTrackAnalysis analysis = null;
|
GPXTrackAnalysis analysis = null;
|
||||||
if (sgpx != null) {
|
if (sgpx != null) {
|
||||||
analysis = sgpx.getTrackAnalysis();
|
analysis = sgpx.getTrackAnalysis();
|
||||||
} else if (gpxInfo.currentlyRecordingTrack) {
|
} else if (gpxInfo.currentlyRecordingTrack) {
|
||||||
analysis = app.getSavingTrackHelper().getCurrentTrack().getTrackAnalysis();
|
analysis = app.getSavingTrackHelper().getCurrentTrack().getTrackAnalysis();
|
||||||
} else {
|
} else if (gpxInfo.file != null) {
|
||||||
GpxDataItem dataItem = gpxInfo.file == null ? null : app.getGpxDatabase().getItem(gpxInfo.file);
|
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) {
|
if (dataItem != null) {
|
||||||
analysis = dataItem.getAnalysis();
|
analysis = dataItem.getAnalysis();
|
||||||
}
|
}
|
||||||
|
|
|
@ -381,12 +381,12 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener {
|
||||||
if (clr != 0 && sf.getModifiableGpxFile() != null) {
|
if (clr != 0 && sf.getModifiableGpxFile() != null) {
|
||||||
sf.getModifiableGpxFile().setColor(clr);
|
sf.getModifiableGpxFile().setColor(clr);
|
||||||
if (getGpxDataItem() != null) {
|
if (getGpxDataItem() != null) {
|
||||||
app.getGpxDatabase().updateColor(getGpxDataItem(), clr);
|
app.getGpxDbHelper().updateColor(getGpxDataItem(), clr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (getGpxDataItem() != null) {
|
} else if (getGpxDataItem() != null) {
|
||||||
app.getGpxDatabase().updateColor(getGpxDataItem(), clr);
|
app.getGpxDbHelper().updateColor(getGpxDataItem(), clr);
|
||||||
}
|
}
|
||||||
if (gpx != null && gpx.showCurrentTrack) {
|
if (gpx != null && gpx.showCurrentTrack) {
|
||||||
app.getSettings().CURRENT_TRACK_COLOR.set(clr);
|
app.getSettings().CURRENT_TRACK_COLOR.set(clr);
|
||||||
|
@ -846,7 +846,7 @@ public class TrackActivityFragmentAdapter implements TrackBitmapDrawerListener {
|
||||||
}
|
}
|
||||||
GpxDataItem item = getGpxDataItem();
|
GpxDataItem item = getGpxDataItem();
|
||||||
if (item != null) {
|
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.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import net.osmand.AndroidUtils;
|
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
|
@ -28,7 +27,6 @@ public class TracksCard extends BaseCard {
|
||||||
|
|
||||||
private List<GPXFile> gpxFiles;
|
private List<GPXFile> gpxFiles;
|
||||||
private boolean showLimited = true;
|
private boolean showLimited = true;
|
||||||
private List<GpxDataItem> dataItems;
|
|
||||||
|
|
||||||
private static class GpxItem {
|
private static class GpxItem {
|
||||||
String title;
|
String title;
|
||||||
|
@ -45,7 +43,6 @@ public class TracksCard extends BaseCard {
|
||||||
public TracksCard(MapActivity mapActivity, List<GPXFile> gpxFiles) {
|
public TracksCard(MapActivity mapActivity, List<GPXFile> gpxFiles) {
|
||||||
super(mapActivity);
|
super(mapActivity);
|
||||||
this.gpxFiles = gpxFiles;
|
this.gpxFiles = gpxFiles;
|
||||||
this.dataItems = app.getGpxDatabase().getItems();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -54,12 +51,7 @@ public class TracksCard extends BaseCard {
|
||||||
}
|
}
|
||||||
|
|
||||||
private GpxDataItem getDataItem(GPXInfo info) {
|
private GpxDataItem getDataItem(GPXInfo info) {
|
||||||
for (GpxDataItem item : dataItems) {
|
return app.getGpxDbHelper().getItem(new File(info.getFileName()));
|
||||||
if (item.getFile().getAbsolutePath().endsWith(info.getFileName())) {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DefaultLocale")
|
@SuppressLint("DefaultLocale")
|
||||||
|
|
Loading…
Reference in a new issue