Add GPX import.
This commit is contained in:
parent
57d9cdb36e
commit
4e17bc3800
|
|
@ -20,6 +20,8 @@
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name=".FilePicker"></activity>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
package fr.chteufleur.mytrackingdog;
|
||||||
|
|
||||||
|
import android.app.ListActivity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import fr.chteufleur.mytrackingdog.R;
|
||||||
|
|
||||||
|
public class FilePicker extends ListActivity {
|
||||||
|
|
||||||
|
public final static String EXTRA_FILE_PATH = "file_path";
|
||||||
|
public final static String EXTRA_SHOW_HIDDEN_FILES = "show_hidden_files";
|
||||||
|
public final static String EXTRA_ACCEPTED_FILE_EXTENSIONS = "accepted_file_extensions";
|
||||||
|
private final static String DEFAULT_INITIAL_DIRECTORY = "/";
|
||||||
|
|
||||||
|
protected File Directory;
|
||||||
|
protected ArrayList<File> Files;
|
||||||
|
protected FilePickerListAdapter Adapter;
|
||||||
|
protected boolean ShowHiddenFiles = false;
|
||||||
|
protected String[] acceptedFileExtensions;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
|
||||||
|
View emptyView = inflator.inflate(R.layout.empty_view, null);
|
||||||
|
((ViewGroup) getListView().getParent()).addView(emptyView);
|
||||||
|
getListView().setEmptyView(emptyView);
|
||||||
|
|
||||||
|
// Set initial directory
|
||||||
|
Directory = new File(DEFAULT_INITIAL_DIRECTORY);
|
||||||
|
|
||||||
|
// Initialize the ArrayList
|
||||||
|
Files = new ArrayList<File>();
|
||||||
|
|
||||||
|
// Set the ListAdapter
|
||||||
|
Adapter = new FilePickerListAdapter(this, Files);
|
||||||
|
setListAdapter(Adapter);
|
||||||
|
|
||||||
|
// Initialize the extensions array to allow any file extensions
|
||||||
|
acceptedFileExtensions = new String[] {};
|
||||||
|
|
||||||
|
// Get intent extras
|
||||||
|
if (getIntent().hasExtra(EXTRA_FILE_PATH)) {
|
||||||
|
Directory = new File(getIntent().getStringExtra(EXTRA_FILE_PATH));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getIntent().hasExtra(EXTRA_SHOW_HIDDEN_FILES)) {
|
||||||
|
ShowHiddenFiles = getIntent().getBooleanExtra(EXTRA_SHOW_HIDDEN_FILES, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getIntent().hasExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS)) {
|
||||||
|
ArrayList<String> collection = getIntent().getStringArrayListExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS);
|
||||||
|
acceptedFileExtensions = collection.toArray(new String[collection.size()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
refreshFilesList();
|
||||||
|
super.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void refreshFilesList() {
|
||||||
|
Files.clear();
|
||||||
|
ExtensionFilenameFilter filter = new ExtensionFilenameFilter(acceptedFileExtensions);
|
||||||
|
|
||||||
|
File[] files = Directory.listFiles(filter);
|
||||||
|
if (files != null && files.length > 0) {
|
||||||
|
for (File f: files) {
|
||||||
|
if (f.isHidden() && !ShowHiddenFiles) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Files.add(f);
|
||||||
|
}
|
||||||
|
Collections.sort(Files, new FileComparator());
|
||||||
|
}
|
||||||
|
Adapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (Directory.getParentFile() != null) {
|
||||||
|
Directory = Directory.getParentFile();
|
||||||
|
refreshFilesList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||||
|
File newFile = (File)l.getItemAtPosition(position);
|
||||||
|
if (newFile.isFile()) {
|
||||||
|
Intent extra = new Intent();
|
||||||
|
extra.putExtra(EXTRA_FILE_PATH, newFile.getAbsolutePath());
|
||||||
|
setResult(RESULT_OK, extra);
|
||||||
|
finish();
|
||||||
|
} else {
|
||||||
|
Directory = newFile;
|
||||||
|
refreshFilesList();
|
||||||
|
}
|
||||||
|
super.onListItemClick(l, v, position, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FilePickerListAdapter extends ArrayAdapter<File> {
|
||||||
|
private List<File> mObjects;
|
||||||
|
|
||||||
|
public FilePickerListAdapter(Context context, List<File> objects) {
|
||||||
|
super(context, R.layout.list_item, android.R.id.text1, objects);
|
||||||
|
mObjects = objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
View row = null;
|
||||||
|
|
||||||
|
if (convertView == null) {
|
||||||
|
LayoutInflater inflater = (LayoutInflater)
|
||||||
|
getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
row = inflater.inflate(R.layout.list_item, parent, false);
|
||||||
|
} else {
|
||||||
|
row = convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
File object = mObjects.get(position);
|
||||||
|
|
||||||
|
ImageView imageView = row.findViewById(R.id.file_picker_image);
|
||||||
|
TextView textView = row.findViewById(R.id.file_picker_text);
|
||||||
|
textView.setSingleLine(true);
|
||||||
|
textView.setText(object.getName());
|
||||||
|
|
||||||
|
if (object.isFile()) {
|
||||||
|
imageView.setImageResource(R.drawable.ic_file);
|
||||||
|
} else {
|
||||||
|
imageView.setImageResource(R.drawable.ic_folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FileComparator implements Comparator<File> {
|
||||||
|
|
||||||
|
public int compare(File f1, File f2) {
|
||||||
|
|
||||||
|
if (f1 == f2) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f1.isDirectory() && f2.isFile()) {
|
||||||
|
// Show directories above files
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f1.isFile() && f2.isDirectory()) {
|
||||||
|
// Show files below directories
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the directories alphabetically
|
||||||
|
return f1.getName().compareToIgnoreCase(f2.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ExtensionFilenameFilter implements FilenameFilter {
|
||||||
|
|
||||||
|
private String[] Extensions;
|
||||||
|
|
||||||
|
public ExtensionFilenameFilter(String[] extensions) {
|
||||||
|
super();
|
||||||
|
Extensions = extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean accept(File dir, String filename) {
|
||||||
|
|
||||||
|
if (new File(dir, filename).isDirectory()) {
|
||||||
|
// Accept all directory names
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Extensions != null && Extensions.length > 0) {
|
||||||
|
for (int i = 0; i < Extensions.length; i++) {
|
||||||
|
if (filename.endsWith(Extensions[i])) {
|
||||||
|
// The filename ends with the extension
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The filename did not match any of the extensions
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// No extensions has been set. Accept all file extensions.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,26 +2,26 @@ package fr.chteufleur.mytrackingdog;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.hardware.GeomagneticField;
|
import android.hardware.GeomagneticField;
|
||||||
import android.location.Location;
|
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.RequiresApi;
|
import android.support.annotation.RequiresApi;
|
||||||
import android.support.design.widget.FloatingActionButton;
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.util.Log;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.osmdroid.api.IMapController;
|
import org.osmdroid.api.IMapController;
|
||||||
|
|
@ -31,7 +31,6 @@ import org.osmdroid.util.GeoPoint;
|
||||||
import org.osmdroid.views.MapView;
|
import org.osmdroid.views.MapView;
|
||||||
import org.osmdroid.views.overlay.Marker;
|
import org.osmdroid.views.overlay.Marker;
|
||||||
import org.osmdroid.views.overlay.Polyline;
|
import org.osmdroid.views.overlay.Polyline;
|
||||||
import org.osmdroid.views.overlay.compass.CompassOverlay;
|
|
||||||
import org.osmdroid.views.overlay.compass.IOrientationConsumer;
|
import org.osmdroid.views.overlay.compass.IOrientationConsumer;
|
||||||
import org.osmdroid.views.overlay.compass.IOrientationProvider;
|
import org.osmdroid.views.overlay.compass.IOrientationProvider;
|
||||||
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
|
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
|
||||||
|
|
@ -39,11 +38,13 @@ import org.osmdroid.views.overlay.infowindow.BasicInfoWindow;
|
||||||
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
|
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
|
||||||
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
|
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import fr.chteufleur.mytrackingdog.models.Gpx;
|
||||||
import fr.chteufleur.mytrackingdog.models.beans.MyLocation;
|
import fr.chteufleur.mytrackingdog.models.beans.MyLocation;
|
||||||
import fr.chteufleur.mytrackingdog.services.ServiceGps;
|
import fr.chteufleur.mytrackingdog.services.ServiceGps;
|
||||||
|
|
||||||
|
|
@ -54,13 +55,11 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
||||||
public static String appName = "";
|
public static String appName = "";
|
||||||
|
|
||||||
private MyLocationNewOverlay mLocationOverlay;
|
private MyLocationNewOverlay mLocationOverlay;
|
||||||
private CompassOverlay mCompassOverlay;
|
|
||||||
private IOrientationProvider compass = null;
|
private IOrientationProvider compass = null;
|
||||||
private ServiceGps serviceGps = null;
|
private ServiceGps serviceGps = null;
|
||||||
|
|
||||||
private Context ctx = null;
|
private Context ctx = null;
|
||||||
private MapView map = null;
|
private MapView map = null;
|
||||||
private ImageButton btFollowMe;
|
|
||||||
|
|
||||||
private int deviceOrientation = 0;
|
private int deviceOrientation = 0;
|
||||||
private boolean zoomed = false;
|
private boolean zoomed = false;
|
||||||
|
|
@ -99,6 +98,9 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
||||||
// Keep screen ON
|
// Keep screen ON
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
map = findViewById(R.id.map);
|
map = findViewById(R.id.map);
|
||||||
map.setTileSource(TileSourceFactory.MAPNIK);
|
map.setTileSource(TileSourceFactory.MAPNIK);
|
||||||
|
|
||||||
|
|
@ -112,11 +114,6 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
||||||
GeoPoint startPoint = new GeoPoint(45.0000, 5.0000);
|
GeoPoint startPoint = new GeoPoint(45.0000, 5.0000);
|
||||||
mapController.setCenter(startPoint);
|
mapController.setCenter(startPoint);
|
||||||
|
|
||||||
// Compass
|
|
||||||
this.mCompassOverlay = new CompassOverlay(ctx, new InternalCompassOrientationProvider(ctx), map);
|
|
||||||
map.getOverlays().add(this.mCompassOverlay);
|
|
||||||
this.mCompassOverlay.enableCompass();
|
|
||||||
|
|
||||||
// Current position on the map
|
// Current position on the map
|
||||||
this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(ctx), map);
|
this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(ctx), map);
|
||||||
map.getOverlays().add(this.mLocationOverlay);
|
map.getOverlays().add(this.mLocationOverlay);
|
||||||
|
|
@ -124,20 +121,6 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
||||||
mLocationOverlay.enableFollowLocation();
|
mLocationOverlay.enableFollowLocation();
|
||||||
mLocationOverlay.setOptionsMenuEnabled(true);
|
mLocationOverlay.setOptionsMenuEnabled(true);
|
||||||
|
|
||||||
// Follow me
|
|
||||||
btFollowMe = findViewById(R.id.ic_follow_me);
|
|
||||||
btFollowMe.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (!mLocationOverlay.isFollowLocationEnabled()) {
|
|
||||||
mLocationOverlay.enableFollowLocation();
|
|
||||||
btFollowMe.setImageResource(R.drawable.osm_ic_follow_me_on);
|
|
||||||
} else {
|
|
||||||
mLocationOverlay.disableFollowLocation();
|
|
||||||
btFollowMe.setImageResource(R.drawable.osm_ic_follow_me);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
start_stop_trace = findViewById(R.id.start_stop_trace);
|
start_stop_trace = findViewById(R.id.start_stop_trace);
|
||||||
start_stop_trace.setOnClickListener(new View.OnClickListener() {
|
start_stop_trace.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
@ -198,6 +181,10 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
||||||
private void addMarker() {
|
private void addMarker() {
|
||||||
MyLocation loc = serviceGps.addPointObject();
|
MyLocation loc = serviceGps.addPointObject();
|
||||||
GeoPoint gp = new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude());
|
GeoPoint gp = new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude());
|
||||||
|
addMarker(gp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMarker(GeoPoint gp) {
|
||||||
Marker marker = new Marker(map);
|
Marker marker = new Marker(map);
|
||||||
marker.setPosition(gp);
|
marker.setPosition(gp);
|
||||||
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
|
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
|
||||||
|
|
@ -262,9 +249,6 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pause() {
|
private void pause() {
|
||||||
if (mCompassOverlay != null) {
|
|
||||||
mCompassOverlay.disableCompass();
|
|
||||||
}
|
|
||||||
if (compass != null) {
|
if (compass != null) {
|
||||||
compass.stopOrientationProvider();
|
compass.stopOrientationProvider();
|
||||||
compass.destroy();
|
compass.destroy();
|
||||||
|
|
@ -308,13 +292,34 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
|
|
||||||
//noinspection SimplifiableIfStatement
|
//noinspection SimplifiableIfStatement
|
||||||
if (id == R.id.action_settings) {
|
if (id == R.id.action_import_gpx) {
|
||||||
|
Intent intent = new Intent(this, FilePicker.class);
|
||||||
|
intent.putExtra(FilePicker.EXTRA_FILE_PATH, Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+appName);
|
||||||
|
startActivityForResult(intent, REQUEST_PICK_FILE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
private static final int REQUEST_PICK_FILE = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (resultCode == RESULT_OK) {
|
||||||
|
switch (requestCode) {
|
||||||
|
case REQUEST_PICK_FILE:
|
||||||
|
if (data.hasExtra(FilePicker.EXTRA_FILE_PATH)) {
|
||||||
|
serviceGps.importGpxTrace(new File(data.getStringExtra(FilePicker.EXTRA_FILE_PATH)));
|
||||||
|
updateDogTrace();
|
||||||
|
updateTrailTrace();
|
||||||
|
for (MyLocation loc: serviceGps.getListGeoPointObjects()) {
|
||||||
|
addMarker(new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -376,40 +381,44 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateDogTrace() {
|
||||||
|
Polyline line = new Polyline(map);
|
||||||
|
line.setTitle(Gpx.DOG_TRACE_NAME);
|
||||||
|
line.setColor(Color.BLUE);
|
||||||
|
line.setPoints(convertListLocation(serviceGps.getListGeoPointDog()));
|
||||||
|
line.setWidth(LINE_WIDTH_BIG);
|
||||||
|
line.setGeodesic(true);
|
||||||
|
line.setInfoWindow(new BasicInfoWindow(R.layout.bonuspack_bubble, map));
|
||||||
|
map.getOverlayManager().add(line);
|
||||||
|
map.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTrailTrace() {
|
||||||
|
Polyline line = new Polyline(map);
|
||||||
|
line.setTitle(Gpx.TRAIL_TRACE_NAME);
|
||||||
|
line.setColor(Color.RED);
|
||||||
|
line.setPoints(convertListLocation(serviceGps.getListGeoPointTraceur()));
|
||||||
|
line.setWidth(LINE_WIDTH_BIG);
|
||||||
|
line.setGeodesic(true);
|
||||||
|
line.setInfoWindow(new BasicInfoWindow(R.layout.bonuspack_bubble, map));
|
||||||
|
map.getOverlayManager().add(line);
|
||||||
|
map.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Observable observable, Object o) {
|
public void update(Observable observable, Object o) {
|
||||||
if (observable == serviceGps) {
|
if (observable == serviceGps) {
|
||||||
if (o instanceof String && o.equals(ServiceGps.NOTIF_NEW_LOCATION)) {
|
if (o instanceof String && o.equals(ServiceGps.NOTIF_NEW_LOCATION)) {
|
||||||
Location loc = serviceGps.getCurrentLocation();
|
MyLocation loc = serviceGps.getCurrentLocation();
|
||||||
if (loc != null) {
|
if (loc != null) {
|
||||||
GeoPoint currentPoint = new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude());
|
GeoPoint currentPoint = new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude());
|
||||||
Polyline line = null;
|
map.getController().setCenter(currentPoint);
|
||||||
if (serviceGps.isTraceurActivated()) {
|
if (serviceGps.isTraceurActivated()) {
|
||||||
map.getController().setCenter(currentPoint);
|
updateTrailTrace();
|
||||||
|
|
||||||
line = new Polyline(map);
|
|
||||||
line.setTitle("Trail");
|
|
||||||
line.setColor(Color.RED);
|
|
||||||
line.setPoints(convertListLocation(serviceGps.getListGeoPointTraceur()));
|
|
||||||
|
|
||||||
} else if (serviceGps.isDogActivated()) {
|
} else if (serviceGps.isDogActivated()) {
|
||||||
map.getController().setCenter(currentPoint);
|
updateDogTrace();
|
||||||
|
|
||||||
line = new Polyline(map);
|
|
||||||
line.setTitle("Dog");
|
|
||||||
line.setColor(Color.BLUE);
|
|
||||||
line.setPoints(convertListLocation(serviceGps.getListGeoPointDog()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line != null) {
|
|
||||||
line.setSubDescription(Polyline.class.getCanonicalName());
|
|
||||||
line.setWidth(LINE_WIDTH_BIG);
|
|
||||||
line.setGeodesic(true);
|
|
||||||
line.setInfoWindow(new BasicInfoWindow(R.layout.bonuspack_bubble, map));
|
|
||||||
map.getOverlayManager().add(line);
|
|
||||||
map.invalidate();
|
|
||||||
}
|
|
||||||
float orientation = serviceGps.getOrientation(deviceOrientation);
|
float orientation = serviceGps.getOrientation(deviceOrientation);
|
||||||
if (orientation >= 0) {
|
if (orientation >= 0) {
|
||||||
map.setMapOrientation(orientation);
|
map.setMapOrientation(orientation);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ import java.io.File;
|
||||||
|
|
||||||
public class Gpx {
|
public class Gpx {
|
||||||
|
|
||||||
|
public static final String DOG_TRACE_NAME = "dog";
|
||||||
|
public static final String TRAIL_TRACE_NAME = "trail";
|
||||||
|
|
||||||
protected final File filePath;
|
protected final File filePath;
|
||||||
|
|
||||||
public Gpx(File filePath) {
|
public Gpx(File filePath) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,219 @@
|
||||||
|
package fr.chteufleur.mytrackingdog.models;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.Xml;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import fr.chteufleur.mytrackingdog.models.beans.MyLocation;
|
||||||
|
import fr.chteufleur.mytrackingdog.models.beans.TraceLocation;
|
||||||
|
import fr.chteufleur.mytrackingdog.models.beans.WayPointLocation;
|
||||||
|
|
||||||
|
public class ImportGpx extends Gpx {
|
||||||
|
|
||||||
|
private static final String TAG = Traces.class.getName();
|
||||||
|
|
||||||
|
private String traceName = "";
|
||||||
|
|
||||||
|
|
||||||
|
public ImportGpx(File filePath) {
|
||||||
|
super(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTraceName() {
|
||||||
|
return this.traceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List parse() throws XmlPullParserException, IOException {
|
||||||
|
InputStream in = new FileInputStream(filePath);
|
||||||
|
try {
|
||||||
|
|
||||||
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
|
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
||||||
|
parser.setInput(in, null);
|
||||||
|
parser.nextTag();
|
||||||
|
return readGpx(parser);
|
||||||
|
} finally {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List readGpx(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||||
|
List entries = new ArrayList();
|
||||||
|
|
||||||
|
parser.require(XmlPullParser.START_TAG, null, "gpx");
|
||||||
|
while (parser.next() != XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String name = parser.getName();
|
||||||
|
if (name.equals("wpt")) {
|
||||||
|
entries.add(readWaypoint(parser));
|
||||||
|
} else if (name.equals("trk")) {
|
||||||
|
entries.addAll(readTrk(parser));
|
||||||
|
} else {
|
||||||
|
skip(parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List readTrk(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||||
|
List entries = new ArrayList();
|
||||||
|
|
||||||
|
parser.require(XmlPullParser.START_TAG, null, "trk");
|
||||||
|
while (parser.next() != XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String name = parser.getName();
|
||||||
|
if (name.equals("trkseg")) {
|
||||||
|
entries = readTrkseq(parser);
|
||||||
|
} else {
|
||||||
|
skip(parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List readTrkseq(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||||
|
List entries = new ArrayList();
|
||||||
|
|
||||||
|
parser.require(XmlPullParser.START_TAG, null, "trkseg");
|
||||||
|
while (parser.next() != XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String name = parser.getName();
|
||||||
|
if (name.equals("trkpt")) {
|
||||||
|
entries.add(readTrkpt(parser));
|
||||||
|
} else if (name.equals("name")) {
|
||||||
|
traceName = readName(parser);
|
||||||
|
} else {
|
||||||
|
skip(parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private MyLocation readTrkpt(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||||
|
parser.require(XmlPullParser.START_TAG, null, "trkpt");
|
||||||
|
|
||||||
|
String latStr = parser.getAttributeValue(null, "lat");
|
||||||
|
String lonStr = parser.getAttributeValue(null, "lon");
|
||||||
|
double lat = Double.parseDouble(latStr);
|
||||||
|
double lon = Double.parseDouble(lonStr);
|
||||||
|
long time = -1;
|
||||||
|
|
||||||
|
while (parser.next() != XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String name = parser.getName();
|
||||||
|
if (name.equals("time")) {
|
||||||
|
time = readTime(parser);
|
||||||
|
} else {
|
||||||
|
skip(parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new TraceLocation(lat, lon, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private MyLocation readWaypoint(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||||
|
parser.require(XmlPullParser.START_TAG, null, "wpt");
|
||||||
|
|
||||||
|
String latStr = parser.getAttributeValue(null, "lat");
|
||||||
|
String lonStr = parser.getAttributeValue(null, "lon");
|
||||||
|
double lat = Double.parseDouble(latStr);
|
||||||
|
double lon = Double.parseDouble(lonStr);
|
||||||
|
long time = -1;
|
||||||
|
|
||||||
|
while (parser.next() != XmlPullParser.END_TAG) {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String name = parser.getName();
|
||||||
|
if (name.equals("time")) {
|
||||||
|
time = readTime(parser);
|
||||||
|
} else {
|
||||||
|
skip(parser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new WayPointLocation(lat, lon, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private long readTime(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||||
|
long ret = 0;
|
||||||
|
parser.require(XmlPullParser.START_TAG, null, "time");
|
||||||
|
String timeStr = readText(parser);
|
||||||
|
|
||||||
|
SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
Pattern pattern = Pattern.compile("([0-9]{4}-[0-9]{2}-[0-9]{2})T([0-9]{2}:[0-9]{2}:[0-9]{2})Z");
|
||||||
|
Matcher matcher = pattern.matcher(timeStr);
|
||||||
|
|
||||||
|
while (matcher.find()) {
|
||||||
|
if (matcher.groupCount() == 2) {
|
||||||
|
try {
|
||||||
|
Date date = formater.parse(matcher.group(1) + " " + matcher.group(2));
|
||||||
|
ret = date.getTime();
|
||||||
|
} catch (ParseException ex) {
|
||||||
|
Log.e(TAG, "Failed to parse time", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parser.require(XmlPullParser.END_TAG, null, "time");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String readName(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||||
|
String ret;
|
||||||
|
parser.require(XmlPullParser.START_TAG, null, "name");
|
||||||
|
ret = readText(parser);
|
||||||
|
parser.require(XmlPullParser.END_TAG, null, "name");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
|
||||||
|
String result = "";
|
||||||
|
if (parser.next() == XmlPullParser.TEXT) {
|
||||||
|
result = parser.getText();
|
||||||
|
parser.nextTag();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||||
|
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
int depth = 1;
|
||||||
|
while (depth != 0) {
|
||||||
|
switch (parser.next()) {
|
||||||
|
case XmlPullParser.END_TAG:
|
||||||
|
depth--;
|
||||||
|
break;
|
||||||
|
case XmlPullParser.START_TAG:
|
||||||
|
depth++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,28 +2,88 @@ package fr.chteufleur.mytrackingdog.models.beans;
|
||||||
|
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
|
|
||||||
public class MyLocation extends Location {
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class MyLocation {
|
||||||
|
|
||||||
|
private final double longitude;
|
||||||
|
private final double latitude;
|
||||||
|
private final long time;
|
||||||
|
|
||||||
|
private final double altitude;
|
||||||
|
private final float speed;
|
||||||
|
private final float bearing;
|
||||||
|
|
||||||
public MyLocation(Location l) {
|
public MyLocation(Location l) {
|
||||||
super(l);
|
if (l == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
this.latitude = l.getLatitude();
|
||||||
|
this.longitude = l.getLongitude();
|
||||||
|
this.time = l.getTime();
|
||||||
|
this.altitude = l.getAltitude();
|
||||||
|
this.speed = l.getSpeed();
|
||||||
|
this.bearing = l.getBearing();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MyLocation(double lat, double lon, long time) {
|
||||||
|
this.latitude = lat;
|
||||||
|
this.longitude = lon;
|
||||||
|
this.time = time;
|
||||||
|
this.altitude = 0;
|
||||||
|
this.speed = 0;
|
||||||
|
this.bearing = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public double getLatitude() {
|
||||||
|
return this.latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLongitude() {
|
||||||
|
return this.longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTime() {
|
||||||
|
return this.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDate() {
|
||||||
|
Date date = new Date(this.time);
|
||||||
|
SimpleDateFormat formaterDate = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
SimpleDateFormat formaterTime = new SimpleDateFormat("HH:mm:ss");
|
||||||
|
return formaterDate.format(date)+"T"+formaterTime.format(date)+"Z";
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getAltitude() {
|
||||||
|
return this.altitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getSpeed() {
|
||||||
|
return this.speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getBearing() {
|
||||||
|
return this.bearing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String toWayPoint() {
|
public String toWayPoint() {
|
||||||
String ret = "<wpt lat=\""+getLatitude()+"\" lon=\""+getLongitude()+"\">";
|
String ret = "<wpt lat=\""+getLatitude()+"\" lon=\""+getLongitude()+"\">";
|
||||||
ret += "<time>"+getTime()+"</time>";
|
ret += "<time>"+getDate()+"</time>";
|
||||||
ret += "</wpt>";
|
ret += "</wpt>";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toTracePoint() {
|
public String toTracePoint() {
|
||||||
String ret = "<trkpt lat=\""+getLatitude()+"\" lon=\""+getLongitude()+"\">";
|
String ret = "<trkpt lat=\""+getLatitude()+"\" lon=\""+getLongitude()+"\">";
|
||||||
ret += "<time>"+getTime()+"</time>";
|
ret += "<time>"+getDate()+"</time>";
|
||||||
ret += "</trkpt>";
|
ret += "</trkpt>";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("lat=%,4f ; lon=%,4f ; time=%d", getLatitude(), getLongitude(), getTime());
|
return String.format("lat=%,4f ; lon=%,4f ; time=%s", getLatitude(), getLongitude(), getDate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package fr.chteufleur.mytrackingdog.models.beans;
|
||||||
|
|
||||||
|
import android.location.Location;
|
||||||
|
|
||||||
|
public class TraceLocation extends MyLocation {
|
||||||
|
public TraceLocation(Location l) {
|
||||||
|
super(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TraceLocation(double lat, double lon, long time) {
|
||||||
|
super(lat, lon, time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package fr.chteufleur.mytrackingdog.models.beans;
|
||||||
|
|
||||||
|
import android.location.Location;
|
||||||
|
|
||||||
|
|
||||||
|
public class WayPointLocation extends MyLocation {
|
||||||
|
public WayPointLocation(Location l) {
|
||||||
|
super(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WayPointLocation(double lat, double lon, long time) {
|
||||||
|
super(lat, lon, time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,15 +7,22 @@ import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
|
|
||||||
import fr.chteufleur.mytrackingdog.models.ExportGpx;
|
import fr.chteufleur.mytrackingdog.models.ExportGpx;
|
||||||
|
import fr.chteufleur.mytrackingdog.models.Gpx;
|
||||||
|
import fr.chteufleur.mytrackingdog.models.ImportGpx;
|
||||||
import fr.chteufleur.mytrackingdog.models.Traces;
|
import fr.chteufleur.mytrackingdog.models.Traces;
|
||||||
import fr.chteufleur.mytrackingdog.models.beans.MyLocation;
|
import fr.chteufleur.mytrackingdog.models.beans.MyLocation;
|
||||||
|
import fr.chteufleur.mytrackingdog.models.beans.TraceLocation;
|
||||||
|
import fr.chteufleur.mytrackingdog.models.beans.WayPointLocation;
|
||||||
|
|
||||||
public class ServiceGps extends Observable implements IServiceGps, LocationListener {
|
public class ServiceGps extends Observable implements IServiceGps, LocationListener {
|
||||||
|
|
||||||
|
|
@ -142,19 +149,41 @@ public class ServiceGps extends Observable implements IServiceGps, LocationListe
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean exportDogTraceToGpx() {
|
public boolean exportDogTraceToGpx() {
|
||||||
File file = new File(getFileName("dog"));
|
File file = new File(getFileName(Gpx.DOG_TRACE_NAME));
|
||||||
ExportGpx exportGpx = new ExportGpx(file, "dog");
|
ExportGpx exportGpx = new ExportGpx(file, Gpx.DOG_TRACE_NAME);
|
||||||
exportGpx.setTrace(traces.getListPointDog());
|
exportGpx.setTrace(traces.getListPointDog());
|
||||||
return exportGpx.export();
|
return exportGpx.export();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean exportTrailTraceToGpx() {
|
public boolean exportTrailTraceToGpx() {
|
||||||
SimpleDateFormat formater = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
|
File file = new File(getFileName(Gpx.TRAIL_TRACE_NAME));
|
||||||
String date = formater.format(new Date());
|
ExportGpx exportGpx = new ExportGpx(file, Gpx.TRAIL_TRACE_NAME);
|
||||||
File file = new File(getFileName("trail"));
|
|
||||||
ExportGpx exportGpx = new ExportGpx(file, "trail");
|
|
||||||
exportGpx.setObjects(traces.getListPointObjects());
|
exportGpx.setObjects(traces.getListPointObjects());
|
||||||
exportGpx.setTrace(traces.getListPointTraceur());
|
exportGpx.setTrace(traces.getListPointTraceur());
|
||||||
return exportGpx.export();
|
return exportGpx.export();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void importGpxTrace(File file) {
|
||||||
|
ImportGpx importGpx = new ImportGpx(file);
|
||||||
|
try {
|
||||||
|
List list = importGpx.parse();
|
||||||
|
String traceName = importGpx.getTraceName();
|
||||||
|
for (int i=0; i<list.size(); i++) {
|
||||||
|
Object o = list.get(i);
|
||||||
|
if (o instanceof WayPointLocation) {
|
||||||
|
traces.addPointObject((WayPointLocation) o);
|
||||||
|
} else if (o instanceof TraceLocation) {
|
||||||
|
if (traceName.equals(Gpx.DOG_TRACE_NAME)) {
|
||||||
|
traces.addPointDog((TraceLocation) o);
|
||||||
|
} else if (traceName.equals(Gpx.TRAIL_TRACE_NAME)) {
|
||||||
|
traces.addPointTraceur((TraceLocation) o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TextView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="No files or directories"
|
||||||
|
android:background="@android:drawable/toast_frame"
|
||||||
|
android:textSize="28sp"
|
||||||
|
android:gravity="center_vertical|center_horizontal" />
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/file_picker_image"
|
||||||
|
android:layout_width="40dip"
|
||||||
|
android:layout_height="40dip"
|
||||||
|
android:layout_marginTop="5dip"
|
||||||
|
android:layout_marginBottom="5dip"
|
||||||
|
android:layout_marginLeft="5dip"
|
||||||
|
android:src="@drawable/direction_arrow"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/file_picker_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_gravity="left|center_vertical"
|
||||||
|
android:textSize="28sp"
|
||||||
|
android:layout_marginLeft="10dip"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="Filename" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
|
@ -6,21 +7,25 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
|
|
||||||
|
<android.support.design.widget.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:theme="@style/AppTheme.AppBarOverlay">
|
||||||
|
|
||||||
|
<android.support.v7.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:background="?attr/colorPrimary"
|
||||||
|
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
||||||
|
|
||||||
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
<org.osmdroid.views.MapView android:id="@+id/map"
|
<org.osmdroid.views.MapView android:id="@+id/map"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent" />
|
android:layout_height="fill_parent" />
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/ic_follow_me"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="top|end"
|
|
||||||
android:layout_marginTop="11dp"
|
|
||||||
android:background="#00ffffff"
|
|
||||||
android:contentDescription="@string/bt_follow_me_description"
|
|
||||||
android:cropToPadding="true"
|
|
||||||
android:src="@drawable/osm_ic_follow_me_on" />
|
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/start_stop_trace"
|
android:id="@+id/start_stop_trace"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context="fr.chteufleur.mytrackingdog.MainActivity">
|
tools:context="fr.chteufleur.mytrackingdog.MainActivity">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_import_gpx"
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
android:title="@string/action_settings"
|
android:title="@string/action_import_gpx"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">MyTrackingDog</string>
|
<string name="app_name">MyTrackingDog</string>
|
||||||
<string name="action_settings">Settings</string>
|
<string name="action_import_gpx">Import GPX</string>
|
||||||
<string name="bt_follow_me_description">Follow me</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue