diff --git a/README.md b/README.md
index 5a08146..cdb4660 100644
--- a/README.md
+++ b/README.md
@@ -1,109 +1,104 @@
+
# El Faro del Peregrino
-Una aplicación espiritual para acompañar el camino interior y comunitario.
-El Faro del Peregrino es una aplicación diseñada para ofrecer luz, guía y herramientas prácticas a quienes desean profundizar en su vida espiritual. Su propósito es integrar oración, reflexión, comunidad y belleza visual en una experiencia sencilla y significativa.
+Una aplicación para acompañar el camino interior y comunitario, integrando oración, reflexión y comunidad en una experiencia visualmente inspiradora.
---
-## Objetivos del proyecto
-- Crear una app que acompañe el crecimiento espiritual personal.
-- Integrar recursos como oraciones, meditaciones, lecturas y seguimiento del camino interior.
-- Diseñar una interfaz cálida, estética y accesible.
-- Construir una base sólida para futuras funcionalidades como:
- - Comunidad de peregrinos
- - Diario espiritual
- - Ritmos diarios (Laudes, Vísperas, etc.)
- - Notificaciones de oración
- - Contenidos multimedia
+## ✨ Propósito
+
+El Faro del Peregrino nace para ofrecer luz, guía y herramientas prácticas a quienes desean profundizar en su vida espiritual. Busca integrar recursos de oración, reflexión y comunidad en una app sencilla, cálida y significativa.
---
-## Tecnologías utilizadas
-Este proyecto está construido con:
+## 🎯 Objetivos
-- Java / Kotlin (según evolucione el código del módulo app/)
-- Gradle como sistema de construcción
-- Android Studio como entorno de desarrollo
-- Estructura modular preparada para escalar
+- Acompañar el crecimiento espiritual personal y comunitario.
+- Integrar oraciones, meditaciones, lecturas y seguimiento del camino interior.
+- Ofrecer una interfaz estética, accesible y acogedora.
+- Sentar las bases para futuras funcionalidades:
+ - Comunidad de peregrinos
+ - Diario espiritual
+ - Ritmos diarios (Laudes, Vísperas, etc.)
+ - Notificaciones de oración
+ - Contenidos multimedia
---
-## Estructura del repositorio
-`
+## 🛠️ Tecnologías
+
+- **Lenguajes:** Java / Kotlin (según evolución del módulo `app/`)
+- **Build:** Gradle (con wrapper incluido)
+- **IDE:** Android Studio (recomendado Flamingo o superior)
+- **Arquitectura:** Modular y escalable
+
+---
+
+## 📁 Estructura del repositorio
+
+```
el-faro-del-peregrino/
-│
-├── app/
-├── gradle/
-├── build.gradle.kts
-├── settings.gradle.kts
-├── gradle.properties
-└── .idea/
-`
+├── app/ # Código principal de la app
+├── gradle/ # Configuración de Gradle
+├── build.gradle.kts # Build script raíz
+├── settings.gradle.kts # Configuración de módulos
+├── gradle.properties # Propiedades globales
+└── .idea/ # Configuración de Android Studio
+```
---
-## Cómo ejecutar el proyecto
+## 🚀 Cómo ejecutar el proyecto
-1. Requisitos previos
-- Android Studio Flamingo o superior
-- JDK 17+
-- Gradle (incluido en el wrapper)
+1. **Requisitos previos**
+ - Android Studio Flamingo o superior
+ - JDK 17+
+ - Gradle (incluido en el wrapper)
-2. Clonar el repositorio
-`bash
-git clone https://git.tatvil.es/tatiana/el-faro-del-peregrino.git
-cd el-faro-del-peregrino
-`
+2. **Clonar el repositorio**
+ ```bash
+ git clone https://git.tatvil.es/tatiana/el-faro-del-peregrino.git
+ cd el-faro-del-peregrino
+ ```
-3. Abrir en Android Studio
-- Selecciona Open
-- Elige la carpeta del proyecto
-- Android Studio descargará dependencias y sincronizará Gradle automáticamente
+3. **Abrir en Android Studio**
+ - Selecciona *Open*
+ - Elige la carpeta del proyecto
+ - Android Studio descargará dependencias y sincronizará Gradle automáticamente
-4. Ejecutar la app
-- Conecta un dispositivo o usa un emulador
-- Pulsa ▶️ Run
+4. **Ejecutar la app**
+ - Conecta un dispositivo o usa un emulador
+ - Pulsa ▶️ *Run*
---
-🗺️ Roadmap inicial
-Este roadmap está alineado con el estilo profesional que ya usas en GitHub Issues.
+## 🗺️ Roadmap
-Versión 0.1 — Estructura base
-- [ ] Configuración inicial del proyecto
-- [ ] Pantalla de bienvenida
-- [ ] Navegación básica
+**Versión 0.1 — Estructura base**
+- [ ] Configuración inicial del proyecto
+- [ ] Pantalla de bienvenida
+- [ ] Navegación básica
- [ ] Tema visual inicial (colores, tipografías, iconografía)
-Versión 0.2 — Contenidos espirituales
-- [ ] Módulo de oraciones
-- [ ] Lecturas del día
-- [ ] Modo oscuro contemplativo
+**Versión 0.2 — Contenidos espirituales**
+- [ ] Módulo de oraciones
+- [ ] Lecturas del día
+- [ ] Modo oscuro contemplativo
-Versión 0.3 — Herramientas del peregrino
-- [ ] Diario espiritual
-- [ ] Seguimiento del camino
-- [ ] Notificaciones de ritmo diario
+**Versión 0.3 — Herramientas del peregrino**
+- [ ] Diario espiritual
+- [ ] Seguimiento del camino
+- [ ] Notificaciones de ritmo diario
-Versión 1.0 — Comunidad
-- [ ] Perfil del peregrino
-- [ ] Espacios de oración compartida
-- [ ] Mensajes y peticiones
+**Versión 1.0 — Comunidad**
+- [ ] Perfil del peregrino
+- [ ] Espacios de oración compartida
+- [ ] Mensajes y peticiones
---
-🤝 Contribuciones
-Este proyecto está en desarrollo activo.
-Las ideas, mejoras y bugs se gestionan mediante GitHub Issues siguiendo un flujo profesional.
+## 🌅 Inspiración
----
+> “El faro no navega por ti, pero ilumina el camino.”
-📜 Licencia
-Pendiente de definir.
-Recomendación: MIT o Apache 2.0 para proyectos abiertos; licencia privada si será app personal o comercial.
-
----
-
-🕯️ Inspiración
-> “El faro no navega por ti, pero ilumina el camino.”
-Este proyecto nace para ofrecer luz, calma y dirección en medio del viaje interior.
+Este proyecto busca ofrecer luz, calma y dirección en el viaje interior.
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 41dfaac..935c82c 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -46,5 +46,6 @@ dependencies {
implementation("com.google.android.gms:play-services-location:21.3.0")
implementation(libs.volley)
implementation(libs.glide)
+ implementation(libs.mpandroidchart)
annotationProcessor(libs.glide.compiler)
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0621925..a7cc49b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,13 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/es/tatvil/elfarodelperegrino/AlbergueAdapter.java b/app/src/main/java/es/tatvil/elfarodelperegrino/AlbergueAdapter.java
index f72bda3..2f4c861 100644
--- a/app/src/main/java/es/tatvil/elfarodelperegrino/AlbergueAdapter.java
+++ b/app/src/main/java/es/tatvil/elfarodelperegrino/AlbergueAdapter.java
@@ -1,5 +1,6 @@
package es.tatvil.elfarodelperegrino;
+import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -40,6 +41,12 @@ public class AlbergueAdapter extends RecyclerView.Adapter {
+ Intent intent = new Intent(v.getContext(), DetalleServicioActivity.class);
+ intent.putExtra("objeto", albergue);
+ v.getContext().startActivity(intent);
+ });
}
@Override
diff --git a/app/src/main/java/es/tatvil/elfarodelperegrino/DetalleEtapaActivity.java b/app/src/main/java/es/tatvil/elfarodelperegrino/DetalleEtapaActivity.java
index 57ce0d1..f8dea3d 100644
--- a/app/src/main/java/es/tatvil/elfarodelperegrino/DetalleEtapaActivity.java
+++ b/app/src/main/java/es/tatvil/elfarodelperegrino/DetalleEtapaActivity.java
@@ -1,10 +1,13 @@
package es.tatvil.elfarodelperegrino;
+import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
@@ -17,12 +20,20 @@ import com.android.volley.RequestQueue;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.bumptech.glide.Glide;
+import com.github.mikephil.charting.charts.LineChart;
+import com.github.mikephil.charting.data.Entry;
+import com.github.mikephil.charting.data.LineData;
+import com.github.mikephil.charting.data.LineDataSet;
+import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
+import java.util.Locale;
public class DetalleEtapaActivity extends AppCompatActivity {
@@ -39,24 +50,34 @@ public class DetalleEtapaActivity extends AppCompatActivity {
ImageView ivImagen = findViewById(R.id.ivDetalleImagen);
TextView tvTitulo = findViewById(R.id.tvDetalleTitulo);
TextView tvDistancia = findViewById(R.id.tvDetalleDistancia);
+ TextView tvDesnivelPos = findViewById(R.id.tvDetalleDesnivelPos);
+ TextView tvDesnivelNeg = findViewById(R.id.tvDetalleDesnivelNeg);
TextView tvHistoria = findViewById(R.id.tvDetalleHistoria);
TextView tvReflexion = findViewById(R.id.tvDetalleReflexion);
TextView tvClima = findViewById(R.id.tvDetalleClima);
tvTitulo.setText(etapa.getOrigen() + " - " + etapa.getDestino());
- tvDistancia.setText("Distancia: " + etapa.getDistancia() + " km");
+ tvDistancia.setText(etapa.getDistancia() + " km");
+ tvDesnivelPos.setText("+" + etapa.getDesnivelPositivo() + "m");
+ tvDesnivelNeg.setText("-" + etapa.getDesnivelNegativo() + "m");
tvHistoria.setText(etapa.getHitoHistorico());
tvReflexion.setText(etapa.getReflexionEspiritual());
+ configurarGrafico(findViewById(R.id.elevationChart), etapa);
+
Glide.with(this)
.load(etapa.getImagenUrl())
.placeholder(android.R.drawable.ic_menu_gallery)
.into(ivImagen);
- obtenerClima(etapa.getLatitud(), etapa.getLongitud(), tvClima);
+ obtenerClimaYPrevision(etapa.getLatitud(), etapa.getLongitud(), tvClima, findViewById(R.id.layoutForecast));
- findViewById(R.id.btnVerClima).setOnClickListener(v ->
- obtenerClima(etapa.getLatitud(), etapa.getLongitud(), tvClima));
+ // Botón Mapa
+ findViewById(R.id.btnVerMapa).setOnClickListener(v -> {
+ String uri = "geo:" + etapa.getLatitud() + "," + etapa.getLongitud() + "?q=" + etapa.getDestino();
+ android.content.Intent intent = new android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(uri));
+ startActivity(intent);
+ });
// Botón Albergues
findViewById(R.id.btnVerAlbergues).setOnClickListener(v -> {
@@ -76,7 +97,7 @@ public class DetalleEtapaActivity extends AppCompatActivity {
if (cercanas.isEmpty()) {
Toast.makeText(this, "No hay iglesias registradas cerca", Toast.LENGTH_SHORT).show();
} else {
- mostrarDialogoSimple("Iglesias cercanas", cercanas);
+ mostrarDialogoServicios("Iglesias cercanas", cercanas, etapa);
}
});
@@ -92,7 +113,7 @@ public class DetalleEtapaActivity extends AppCompatActivity {
if (cercanos.isEmpty()) {
Toast.makeText(this, "No hay restaurantes registrados cerca", Toast.LENGTH_SHORT).show();
} else {
- mostrarDialogoSimple("Restaurantes cercanos", cercanos);
+ mostrarDialogoServicios("Restaurantes cercanos", cercanos, etapa);
}
});
}
@@ -126,18 +147,17 @@ public class DetalleEtapaActivity extends AppCompatActivity {
.show();
}
- private void mostrarDialogoSimple(String titulo, List> items) {
- StringBuilder sb = new StringBuilder();
- for (Object item : items) {
- if (item instanceof Iglesia) sb.append("• ").append(((Iglesia) item).getNombre()).append("\n");
- if (item instanceof Restaurante) sb.append("• ").append(((Restaurante) item).getNombre()).append("\n");
- }
+ private void mostrarDialogoServicios(String titulo, List> items, Etapa etapa) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ View view = LayoutInflater.from(this).inflate(R.layout.dialog_lista_albergues, null);
+ RecyclerView rv = view.findViewById(R.id.rvDialogo);
+ rv.setLayoutManager(new LinearLayoutManager(this));
+ rv.setAdapter(new SimpleServicioAdapter(items, etapa.getLatitud(), etapa.getLongitud()));
- new AlertDialog.Builder(this)
- .setTitle(titulo)
- .setMessage(sb.toString())
- .setPositiveButton("OK", null)
- .show();
+ builder.setTitle(titulo)
+ .setView(view)
+ .setPositiveButton("Cerrar", null)
+ .show();
}
private double calcularDistancia(double lat1, double lon1, double lat2, double lon2) {
@@ -146,21 +166,100 @@ public class DetalleEtapaActivity extends AppCompatActivity {
return results[0] / 1000; // Retorna km
}
- private void obtenerClima(double lat, double lon, TextView tvClima) {
- String url = "https://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + lon + "&appid=" + API_KEY + "&units=metric&lang=es";
+ private void configurarGrafico(LineChart chart, Etapa etapa) {
+ List entries = new ArrayList<>();
+ List perfil = etapa.getPerfilElevacion();
+ for (int i = 0; i < perfil.size(); i++) {
+ entries.add(new Entry(i, perfil.get(i)));
+ }
+
+ LineDataSet dataSet = new LineDataSet(entries, "Elevación (m)");
+ dataSet.setColor(Color.parseColor("#4CAF50"));
+ dataSet.setCircleColor(Color.parseColor("#4CAF50"));
+ dataSet.setLineWidth(2f);
+ dataSet.setCircleRadius(3f);
+ dataSet.setDrawCircleHole(false);
+ dataSet.setValueTextColor(Color.WHITE);
+ dataSet.setDrawFilled(true);
+ dataSet.setFillDrawable(getResources().getDrawable(R.drawable.ic_launcher_background)); // O un gradiente simple
+ dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
+
+ LineData lineData = new LineData(dataSet);
+ chart.setData(lineData);
+ chart.getDescription().setEnabled(false);
+ chart.getLegend().setTextColor(Color.WHITE);
+ chart.getXAxis().setTextColor(Color.WHITE);
+ chart.getAxisLeft().setTextColor(Color.WHITE);
+ chart.getAxisRight().setEnabled(false);
+ chart.animateX(1500);
+ chart.invalidate();
+ }
+
+ private void obtenerClimaYPrevision(double lat, double lon, TextView tvClima, LinearLayout layoutForecast) {
+ // Clima actual
+ String urlWeather = "https://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + lon + "&appid=" + API_KEY + "&units=metric&lang=es";
+ // Previsión (5 días cada 3 horas)
+ String urlForecast = "https://api.openweathermap.org/data/2.5/forecast?lat=" + lat + "&lon=" + lon + "&appid=" + API_KEY + "&units=metric&lang=es";
+
RequestQueue queue = Volley.newRequestQueue(this);
- JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
+
+ // Request para clima actual
+ JsonObjectRequest requestWeather = new JsonObjectRequest(Request.Method.GET, urlWeather, null,
response -> {
try {
JSONObject main = response.getJSONObject("main");
double temp = main.getDouble("temp");
String desc = response.getJSONArray("weather").getJSONObject(0).getString("description");
- tvClima.setText("Clima actual: " + temp + "°C, " + desc);
+ tvClima.setText("Hoy: " + temp + "°C, " + desc);
} catch (JSONException e) {
- tvClima.setText("Error al procesar clima");
+ tvClima.setText("Error en clima actual");
}
- },
- error -> tvClima.setText("Error al obtener clima"));
- queue.add(request);
+ }, error -> tvClima.setText("Error al conectar con clima"));
+
+ // Request para previsión
+ JsonObjectRequest requestForecast = new JsonObjectRequest(Request.Method.GET, urlForecast, null,
+ response -> {
+ try {
+ JSONArray list = response.getJSONArray("list");
+ layoutForecast.removeAllViews();
+ // Tomamos un punto por día (cada 8 registros son 24h aprox)
+ for (int i = 8; i < list.length() && i <= 24; i += 8) {
+ JSONObject dayObj = list.getJSONObject(i);
+ double temp = dayObj.getJSONObject("main").getDouble("temp");
+ String desc = dayObj.getJSONArray("weather").getJSONObject(0).getString("description");
+ long dt = dayObj.getLong("dt") * 1000;
+ String fecha = new SimpleDateFormat("EEE", new Locale("es", "ES")).format(new Date(dt));
+
+ agregarVistaPrevision(layoutForecast, fecha, temp, desc);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }, error -> {});
+
+ queue.add(requestWeather);
+ queue.add(requestForecast);
+ }
+
+ private void agregarVistaPrevision(LinearLayout layout, String dia, double temp, String desc) {
+ LinearLayout v = new LinearLayout(this);
+ v.setOrientation(LinearLayout.VERTICAL);
+ v.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f));
+ v.setGravity(Gravity.CENTER);
+
+ TextView tvDia = new TextView(this);
+ tvDia.setText(dia.toUpperCase());
+ tvDia.setTextColor(Color.WHITE);
+ tvDia.setTextSize(12);
+
+ TextView tvTemp = new TextView(this);
+ tvTemp.setText((int)temp + "°");
+ tvTemp.setTextColor(Color.parseColor("#FFEB3B"));
+ tvTemp.setTextSize(16);
+ tvTemp.setTypeface(null, android.graphics.Typeface.BOLD);
+
+ layout.addView(v);
+ v.addView(tvDia);
+ v.addView(tvTemp);
}
}
diff --git a/app/src/main/java/es/tatvil/elfarodelperegrino/DetalleServicioActivity.java b/app/src/main/java/es/tatvil/elfarodelperegrino/DetalleServicioActivity.java
new file mode 100644
index 0000000..58b0a1a
--- /dev/null
+++ b/app/src/main/java/es/tatvil/elfarodelperegrino/DetalleServicioActivity.java
@@ -0,0 +1,94 @@
+package es.tatvil.elfarodelperegrino;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+import androidx.appcompat.app.AppCompatActivity;
+import com.google.android.material.button.MaterialButton;
+
+public class DetalleServicioActivity extends AppCompatActivity {
+
+ private String nombre, telefono, tipo, descripcion;
+ private double latitud, longitud;
+ private boolean tieneCocina;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_detalle_servicio);
+
+ // Obtener datos del Intent
+ Object object = getIntent().getSerializableExtra("objeto");
+
+ if (object instanceof Albergue) {
+ Albergue a = (Albergue) object;
+ nombre = a.getNombre();
+ telefono = a.getTelefono();
+ tipo = a.getTipo();
+ descripcion = a.getComentario();
+ latitud = a.getLatitud();
+ longitud = a.getLongitud();
+ tieneCocina = a.isTieneCocina();
+ } else if (object instanceof Restaurante) {
+ Restaurante r = (Restaurante) object;
+ nombre = r.getNombre();
+ telefono = ""; // Por ahora no hay en JSON
+ tipo = getString(R.string.action_food).replace("\n", " ");
+ descripcion = getString(R.string.msg_food_place);
+ latitud = r.getLatitud();
+ longitud = r.getLongitud();
+ } else if (object instanceof Iglesia) {
+ Iglesia i = (Iglesia) object;
+ nombre = i.getNombre();
+ telefono = "";
+ tipo = getString(R.string.msg_interest_place); // Usando un string descriptivo como tipo
+ descripcion = getString(R.string.msg_interest_place);
+ latitud = i.getLatitud();
+ longitud = i.getLongitud();
+ }
+
+ // Vincular vistas
+ TextView tvNombre = findViewById(R.id.tvDetalleNombre);
+ TextView tvTipo = findViewById(R.id.tvDetalleTipo);
+ TextView tvDescripcion = findViewById(R.id.tvDetalleDescripcion);
+ TextView tvCocina = findViewById(R.id.tvDetalleCocina);
+ View layoutExtras = findViewById(R.id.layoutExtras);
+ MaterialButton btnLlamar = findViewById(R.id.btnLlamar);
+ MaterialButton btnComoLlegar = findViewById(R.id.btnComoLlegar);
+
+ tvNombre.setText(nombre);
+ tvTipo.setText(tipo);
+ tvDescripcion.setText(descripcion != null && !descripcion.isEmpty() ? descripcion : getString(R.string.msg_no_description));
+
+ if (tieneCocina) {
+ layoutExtras.setVisibility(View.VISIBLE);
+ tvCocina.setVisibility(View.VISIBLE);
+ }
+
+ if (telefono == null || telefono.isEmpty() || telefono.equals("Sin teléfono")) {
+ btnLlamar.setVisibility(View.GONE);
+ } else {
+ btnLlamar.setOnClickListener(v -> {
+ Intent intent = new Intent(Intent.ACTION_DIAL);
+ intent.setData(Uri.parse("tel:" + telefono));
+ startActivity(intent);
+ });
+ }
+
+ btnComoLlegar.setOnClickListener(v -> {
+ String uri = String.format(java.util.Locale.US, "google.navigation:q=%f,%f&mode=w", latitud, longitud);
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
+ intent.setPackage("com.google.android.apps.maps");
+ if (intent.resolveActivity(getPackageManager()) != null) {
+ startActivity(intent);
+ } else {
+ // Fallback a navegador si no hay Google Maps
+ String webUri = String.format(java.util.Locale.US, "https://www.google.com/maps/dir/?api=1&destination=%f,%f&travelmode=walking", latitud, longitud);
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(webUri)));
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/es/tatvil/elfarodelperegrino/Etapa.java b/app/src/main/java/es/tatvil/elfarodelperegrino/Etapa.java
index 90ed31f..651fa48 100644
--- a/app/src/main/java/es/tatvil/elfarodelperegrino/Etapa.java
+++ b/app/src/main/java/es/tatvil/elfarodelperegrino/Etapa.java
@@ -1,6 +1,8 @@
package es.tatvil.elfarodelperegrino;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
public class Etapa implements Serializable {
private String nombre;
@@ -14,6 +16,9 @@ public class Etapa implements Serializable {
private String hitoHistorico;
private double latitud, longitud;
private String imagenUrl;
+ private int desnivelPositivo;
+ private int desnivelNegativo;
+ private List perfilElevacion;
public Etapa(String nombre, String origen, String destino, String ruta, String camino, double distancia,
int dificultad, String reflexionEspiritual, String hitoHistorico,
@@ -30,11 +35,29 @@ public class Etapa implements Serializable {
this.latitud = latitud;
this.longitud = longitud;
this.imagenUrl = "https://picsum.photos/seed/" + nombre.replace(" ", "") + "/800/400";
+ // Valores por defecto para el ejemplo
+ this.desnivelPositivo = (int) (distancia * 15);
+ this.desnivelNegativo = (int) (distancia * 12);
+ this.perfilElevacion = generarPerfilMock(distancia);
+ }
+
+ private List generarPerfilMock(double dist) {
+ List perfil = new ArrayList<>();
+ int base = 100 + (int)(Math.random() * 200);
+ for (int i = 0; i <= 10; i++) {
+ perfil.add(base + (int)(Math.random() * 150));
+ }
+ return perfil;
}
// Getters
- public String getImagenUrl() { return imagenUrl; }
+ public List getPerfilElevacion() { return perfilElevacion; }
+ public int getDesnivelPositivo() { return desnivelPositivo; }
+ public int getDesnivelNegativo() { return desnivelNegativo; }
+ public void setDesnivelPositivo(int desnivelPositivo) { this.desnivelPositivo = desnivelPositivo; }
+ public void setDesnivelNegativo(int desnivelNegativo) { this.desnivelNegativo = desnivelNegativo; }
public void setImagenUrl(String imagenUrl) { this.imagenUrl = imagenUrl; }
+ public String getImagenUrl() { return imagenUrl; }
public String getNombre() { return nombre; }
public String getOrigen() { return origen; }
public String getDestino() { return destino; }
diff --git a/app/src/main/java/es/tatvil/elfarodelperegrino/EtapasActivity.java b/app/src/main/java/es/tatvil/elfarodelperegrino/EtapasActivity.java
new file mode 100644
index 0000000..9b9fde9
--- /dev/null
+++ b/app/src/main/java/es/tatvil/elfarodelperegrino/EtapasActivity.java
@@ -0,0 +1,115 @@
+package es.tatvil.elfarodelperegrino;
+
+import android.Manifest;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.google.android.gms.location.FusedLocationProviderClient;
+import com.google.android.gms.location.LocationServices;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class EtapasActivity extends AppCompatActivity {
+
+ private FusedLocationProviderClient fusedLocationClient;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ // 1. SIEMPRE debes llamar al super y establecer la vista
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_etapas); // Esto vincula el XML activity_etapas
+
+ // 2. Ahora sí, inicializamos el RecyclerView después de que la vista exista
+ RecyclerView recyclerView = findViewById(R.id.recyclerViewEtapas);
+
+ // 3. Configuración del LayoutManager
+ recyclerView.setLayoutManager(new LinearLayoutManager(this));
+
+ // 4. Configuración del Spinner para seleccionar el camino
+ Spinner spinnerCaminos = findViewById(R.id.spinnerCaminos);
+ String[] opcionesCaminos = {"Norte", "Francés"};
+
+ ArrayAdapter adapterCaminos = new ArrayAdapter<>(this,
+ android.R.layout.simple_spinner_item, opcionesCaminos);
+ adapterCaminos.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinnerCaminos.setAdapter(adapterCaminos);
+
+ // 5. Configuración del Spinner para distancia máxima
+ Spinner spinnerDistancia = findViewById(R.id.spinnerDistancia);
+ String[] opcionesDistancia = {"Sin límite", "15 km", "20 km", "25 km"};
+ ArrayAdapter adapterDistancia = new ArrayAdapter<>(this,
+ android.R.layout.simple_spinner_item, opcionesDistancia);
+ adapterDistancia.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinnerDistancia.setAdapter(adapterDistancia);
+
+ AdapterView.OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ String camino = spinnerCaminos.getSelectedItem().toString();
+ String distStr = spinnerDistancia.getSelectedItem().toString();
+ double maxDist = Double.MAX_VALUE;
+ if (!distStr.equals("Sin límite")) {
+ maxDist = Double.parseDouble(distStr.split(" ")[0]);
+ }
+ actualizarListaEtapas(camino, maxDist, recyclerView);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {}
+ };
+
+ spinnerCaminos.setOnItemSelectedListener(listener);
+ spinnerDistancia.setOnItemSelectedListener(listener);
+
+ fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
+ obtenerUbicacionActual();
+ }
+
+ private void actualizarListaEtapas(String camino, double maxDistancia, RecyclerView recyclerView) {
+ List todas = CaminoData.getEtapasPorCamino(this, camino);
+ List filtradas = new ArrayList<>();
+ for (Etapa e : todas) {
+ if (e.getDistancia() <= maxDistancia) {
+ filtradas.add(e);
+ }
+ }
+ EtapaAdapter adapter = new EtapaAdapter(filtradas);
+ recyclerView.setAdapter(adapter);
+ }
+
+ private void obtenerUbicacionActual() {
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
+ fusedLocationClient.getLastLocation().addOnSuccessListener(this, location -> {
+ if (location != null) {
+ // Futura implementación: resaltar etapa más cercana
+ }
+ });
+ } else {
+ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (requestCode == 1) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ obtenerUbicacionActual();
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/es/tatvil/elfarodelperegrino/MainActivity.java b/app/src/main/java/es/tatvil/elfarodelperegrino/MainActivity.java
index e13c801..4fd8036 100644
--- a/app/src/main/java/es/tatvil/elfarodelperegrino/MainActivity.java
+++ b/app/src/main/java/es/tatvil/elfarodelperegrino/MainActivity.java
@@ -1,174 +1,46 @@
+
package es.tatvil.elfarodelperegrino;
-import android.Manifest;
-import android.content.pm.PackageManager;
+import android.content.Intent;
import android.os.Bundle;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Spinner;
-import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
-import androidx.core.app.ActivityCompat;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.google.android.gms.location.FusedLocationProviderClient;
-import com.google.android.gms.location.LocationServices;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
+import android.view.View;
+import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
- private FusedLocationProviderClient fusedLocationClient;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
- // 1. SIEMPRE debes llamar al super y establecer la vista
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main); // Esto vincula el XML activity_main
+ setContentView(R.layout.activity_main);
- // 2. Ahora sí, inicializamos el RecyclerView después de que la vista exista
- RecyclerView recyclerView = findViewById(R.id.recyclerViewEtapas);
-
- // 3. Configuración del LayoutManager
- recyclerView.setLayoutManager(new LinearLayoutManager(this));
-
- // 4. Configuración del Spinner para seleccionar el camino
- Spinner spinner = findViewById(R.id.spinnerCaminos);
- String[] opcionesCaminos = {"Norte", "Francés"};
-
- ArrayAdapter spinnerAdapter = new ArrayAdapter<>(this,
- android.R.layout.simple_spinner_item, opcionesCaminos);
- spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- spinner.setAdapter(spinnerAdapter);
-
- spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position, long id) {
- String caminoSeleccionado = opcionesCaminos[position];
- actualizarListaEtapas(caminoSeleccionado, recyclerView);
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
- }
+ // --- SECCIÓN RUTA ---
+ findViewById(R.id.btnMap).setOnClickListener(v -> {
+ Intent intent = new Intent(MainActivity.this, EtapasActivity.class);
+ startActivity(intent);
});
- fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
- obtenerUbicacionActual();
+ // --- SECCIÓN SERVICIOS ---
+ findViewById(R.id.btnSleep).setOnClickListener(v -> {
+ Toast.makeText(this, "Funcionalidad de Alojamiento próximamente", Toast.LENGTH_SHORT).show();
+ });
+
+ findViewById(R.id.btnFood).setOnClickListener(v -> {
+ Toast.makeText(this, "Funcionalidad de Restaurantes próximamente", Toast.LENGTH_SHORT).show();
+ });
+
+ // --- SECCIÓN MI CAMINO ---
+ findViewById(R.id.btnDiary).setOnClickListener(v -> {
+ Toast.makeText(this, "Funcionalidad de Diario próximamente", Toast.LENGTH_SHORT).show();
+ });
+
+ findViewById(R.id.btnRegister).setOnClickListener(v -> {
+ Toast.makeText(this, "Funcionalidad de Sellar Credencial próximamente", Toast.LENGTH_SHORT).show();
+ });
+
+ findViewById(R.id.btnTraining).setOnClickListener(v -> {
+ Toast.makeText(this, "Funcionalidad de Entrenamiento próximamente", Toast.LENGTH_SHORT).show();
+ });
}
-
- private void actualizarListaEtapas(String camino, RecyclerView recyclerView) {
- List etapas = CaminoData.getEtapasPorCamino(this, camino);
- EtapaAdapter adapter = new EtapaAdapter(etapas);
- recyclerView.setAdapter(adapter);
- }
-
- private void obtenerUbicacionActual() {
- if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
- fusedLocationClient.getLastLocation().addOnSuccessListener(this, location -> {
- if (location != null) {
- double miLat = location.getLatitude();
- double miLon = location.getLongitude();
- // Aquí se compararía con las etapas
- }
- });
- } else {
- ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
- }
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == 1) {
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- obtenerUbicacionActual();
- }
- }
- }
-
- private List cargarEtapasDesdeJSON() {
- List lista = new ArrayList<>();
- try {
- InputStream is = getResources().openRawResource(R.raw.etapas);
- byte[] buffer = new byte[is.available()];
- is.read(buffer);
- is.close();
- String json = new String(buffer, "UTF-8");
-
- JSONArray jsonArray = new JSONArray(json);
- for (int i = 0; i < jsonArray.length(); i++) {
- JSONObject obj = jsonArray.getJSONObject(i);
- lista.add(new Etapa(
- obj.getString("nombre"),
- obj.optString("origen", ""),
- obj.optString("destino", ""),
- obj.optString("ruta", obj.optString("origen") + " - " + obj.optString("destino")),
- obj.optString("camino", "Norte"),
- obj.getDouble("distancia"),
- obj.optInt("dificultad", 0),
- obj.optString("reflexionEspiritual", obj.optString("reflexion", "")),
- obj.optString("hitoHistorico", obj.optString("historia", "")),
- obj.getDouble("latitud"),
- obj.getDouble("longitud")
- ));
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return lista;
- }
-
- private List leerEtapasDesdeRaw() {
- List lista = new ArrayList<>();
- try {
- // Abrimos el archivo etapas.json que debes crear en res/raw
- InputStream is = getResources().openRawResource(R.raw.etapas);
- int size = is.available();
- byte[] buffer = new byte[size];
- is.read(buffer);
- is.close();
-
- String jsonString = new String(buffer, "UTF-8");
- JSONArray jsonArray = new JSONArray(jsonString);
-
- for (int i = 0; i < jsonArray.length(); i++) {
- JSONObject obj = jsonArray.getJSONObject(i);
- lista.add(new Etapa(
- obj.getString("nombre"),
- obj.optString("origen", ""),
- obj.optString("destino", ""),
- obj.optString("ruta", obj.optString("origen") + " - " + obj.optString("destino")),
- obj.optString("camino", "Norte"),
- obj.getDouble("distancia"),
- obj.optInt("dificultad", 0),
- obj.optString("reflexionEspiritual", obj.optString("reflexion", "")),
- obj.optString("hitoHistorico", obj.optString("historia", "")),
- obj.getDouble("latitud"),
- obj.getDouble("longitud")
- ));
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return lista;
- }
-
- // Método para calcular distancia entre dos puntos (Fórmula de Haversine simplificada)
- public double calcularDistancia(double lat1, double lon1, double lat2, double lon2) {
- double theta = lon1 - lon2;
- double dist = Math.sin(Math.toRadians(lat1)) * Math.sin(Math.toRadians(lat2)) +
- Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
- Math.cos(Math.toRadians(theta));
- dist = Math.acos(dist);
- dist = Math.toDegrees(dist);
- return dist * 60 * 1.1515 * 1.609344; // Retorna Kilómetros
- }
-}
\ No newline at end of file
+}
+
\ No newline at end of file
diff --git a/app/src/main/java/es/tatvil/elfarodelperegrino/MainActivity2.class b/app/src/main/java/es/tatvil/elfarodelperegrino/MainActivity2.class
deleted file mode 100644
index 131d15f..0000000
--- a/app/src/main/java/es/tatvil/elfarodelperegrino/MainActivity2.class
+++ /dev/null
@@ -1,22 +0,0 @@
-public class MainActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- // Aquí conectas los botones
- findViewById(R.id.btnTraining).setOnClickListener(v -> {
- // TODO: abrir pantalla de entrenamiento
- });
-
- findViewById(R.id.btnDiary).setOnClickListener(v -> {
- // TODO: abrir pantalla del diario
- });
-
- // ... y así con los demás
- }
-}
- })
- })
-
\ No newline at end of file
diff --git a/app/src/main/java/es/tatvil/elfarodelperegrino/SimpleServicioAdapter.java b/app/src/main/java/es/tatvil/elfarodelperegrino/SimpleServicioAdapter.java
new file mode 100644
index 0000000..5391b86
--- /dev/null
+++ b/app/src/main/java/es/tatvil/elfarodelperegrino/SimpleServicioAdapter.java
@@ -0,0 +1,85 @@
+package es.tatvil.elfarodelperegrino;
+
+import android.content.Intent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Locale;
+
+public class SimpleServicioAdapter extends RecyclerView.Adapter {
+
+ private List> items;
+ private double refLat, refLon;
+
+ public SimpleServicioAdapter(List> items, double refLat, double refLon) {
+ this.items = items;
+ this.refLat = refLat;
+ this.refLon = refLon;
+ }
+
+ @NonNull
+ @Override
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.item_albergue, parent, false);
+ return new ViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+ Object item = items.get(position);
+ String nombre = "";
+ double lat = 0, lon = 0;
+ String tipo = "";
+
+ if (item instanceof Iglesia) {
+ Iglesia i = (Iglesia) item;
+ nombre = i.getNombre();
+ lat = i.getLatitud();
+ lon = i.getLongitud();
+ tipo = "Iglesia";
+ } else if (item instanceof Restaurante) {
+ Restaurante r = (Restaurante) item;
+ nombre = r.getNombre();
+ lat = r.getLatitud();
+ lon = r.getLongitud();
+ tipo = "Restaurante";
+ }
+
+ holder.tvNombre.setText(nombre);
+ holder.tvTipo.setText(tipo);
+ holder.tvTelefono.setVisibility(View.GONE);
+
+ float[] results = new float[1];
+ android.location.Location.distanceBetween(refLat, refLon, lat, lon, results);
+ float distanciaKm = results[0] / 1000;
+ holder.tvDistancia.setText(String.format(Locale.getDefault(), "A %.1f km", distanciaKm));
+
+ holder.itemView.setOnClickListener(v -> {
+ Intent intent = new Intent(v.getContext(), DetalleServicioActivity.class);
+ intent.putExtra("objeto", (Serializable) item);
+ v.getContext().startActivity(intent);
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return items.size();
+ }
+
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+ TextView tvNombre, tvTipo, tvDistancia, tvTelefono;
+ public ViewHolder(@NonNull View itemView) {
+ super(itemView);
+ tvNombre = itemView.findViewById(R.id.tvAlbergueNombre);
+ tvTipo = itemView.findViewById(R.id.tvAlbergueTipo);
+ tvDistancia = itemView.findViewById(R.id.tvAlbergueDistancia);
+ tvTelefono = itemView.findViewById(R.id.tvAlbergueTelefono);
+ }
+ }
+}
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
index 07d5da9..c3ff9d1 100644
--- a/app/src/main/res/drawable/ic_launcher_background.xml
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -1,170 +1,25 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:pathData="M54,54m-40,0a40,40 0,1 1,80 0a40,40 0,1 1,-80 0">
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml
index 2b068d1..e3242a4 100644
--- a/app/src/main/res/drawable/ic_launcher_foreground.xml
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -4,27 +4,62 @@
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+ android:pathData="M60,30 L93,15 L93,45 Z">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/Activity-main2.xml b/app/src/main/res/layout/Activity-main2.xml
deleted file mode 100644
index d59d819..0000000
--- a/app/src/main/res/layout/Activity-main2.xml
+++ /dev/null
@@ -1,145 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_detalle_etapa.xml b/app/src/main/res/layout/activity_detalle_etapa.xml
index e1469b3..4ec7d9f 100644
--- a/app/src/main/res/layout/activity_detalle_etapa.xml
+++ b/app/src/main/res/layout/activity_detalle_etapa.xml
@@ -28,62 +28,155 @@
android:text="Nombre de la Etapa"
android:layout_marginBottom="16dp"/>
-
+ android:orientation="horizontal"
+ android:layout_marginBottom="16dp"
+ android:baselineAligned="false">
-
+
+
+
+
-
+
+
+
+
-
+
+
+
+
+
-
+ app:cardBackgroundColor="#222222"
+ app:cardCornerRadius="8dp"
+ android:layout_marginBottom="16dp">
+
+
+
+
+
-
+ app:cardBackgroundColor="#222222"
+ app:cardCornerRadius="8dp"
+ android:layout_marginBottom="24dp">
+
+
+
+
+
+
+
+ android:text="Ver en Mapa / GPS"
+ android:backgroundTint="#1976D2"
+ android:layout_marginBottom="24dp"
+ app:icon="@android:drawable/ic_dialog_map"/>
+ style="@style/Widget.MaterialComponents.Button.OutlinedButton"
+ android:layout_marginBottom="24dp"/>
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_detalle_servicio.xml b/app/src/main/res/layout/activity_detalle_servicio.xml
new file mode 100644
index 0000000..b118bd6
--- /dev/null
+++ b/app/src/main/res/layout/activity_detalle_servicio.xml
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_etapas.xml b/app/src/main/res/layout/activity_etapas.xml
new file mode 100644
index 0000000..ee13c5f
--- /dev/null
+++ b/app/src/main/res/layout/activity_etapas.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 3ea5483..2399b8c 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,28 +1,314 @@
-
+ android:background="@color/spiritual_black"
+ android:fillViewport="true">
-
-
-
+ android:layout_height="wrap_content"
+ android:paddingBottom="40dp">
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/raw/restaurantes.json b/app/src/main/res/raw/restaurantes.json
index 331ad10..5a28f0a 100644
--- a/app/src/main/res/raw/restaurantes.json
+++ b/app/src/main/res/raw/restaurantes.json
@@ -3,5 +3,11 @@
"nombre": "Pulperia A Garnacha",
"latitud": 42.91390034545274,
"longitud": -8.011660067243549
+ },
+ {
+ "nombre": "Bar Manuel",
+ "latitud": 42.931718288986296,
+ "longitud":-8.127124619996351
}
+
]
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index fe75fca..2f1f10d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,26 @@
El Faro del Peregrino
+ Buen Camino,\nTatiana
+ TU RUTA
+ SERVICIOS
+ MI CAMINO
+ Mapa interactivo y\nEtapas del Camino
+ Dónde\nDormir
+ Dónde\nComer
+ Mi\nDiario
+ Sellar\nCredencial
+ Preparación
+ Entrenar
+ Sellar
+ 19ºC · Cielo despejado
+ 2 Mayo\nSábado
+ 📍 Las Rozas de Madrid
+ \"El camino me enseñó que el verdadero lujo es el que nos dedicamos a nosotros mismos.\"
+ Categoría
+ Llamar
+ Cómo llegar
+ Sin descripción disponible.
+ 🍳 Dispone de cocina
+ Lugar de interés espiritual y arquitectónico en el Camino.
+ Disfruta de la gastronomía local en este establecimiento.
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 5870e64..f6ad2dc 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -9,6 +9,7 @@ activity = "1.13.0"
constraintlayout = "2.2.1"
volley = "1.2.1"
glide = "4.16.0"
+mpandroidchart = "v3.1.0"
[libraries]
junit = { group = "junit", name = "junit", version.ref = "junit" }
@@ -21,6 +22,7 @@ constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayo
volley = { group = "com.android.volley", name = "volley", version.ref = "volley" }
glide = { group = "com.github.bumptech.glide", name = "glide", version.ref = "glide" }
glide-compiler = { group = "com.github.bumptech.glide", name = "compiler", version.ref = "glide" }
+mpandroidchart = { group = "com.github.PhilJay", name = "MPAndroidChart", version.ref = "mpandroidchart" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index f2a4bab..54a2966 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -19,6 +19,7 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
+ maven { url = uri("https://jitpack.io") }
}
}