diff --git a/app/build.gradle b/app/build.gradle index 80dfa3f..025b795 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,7 +14,6 @@ android { targetSdk 33 versionCode 1 versionName "1.0" - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -33,7 +32,17 @@ android { } } +apply plugin: 'kotlin-kapt' + dependencies { + kapt "androidx.room:room-compiler:2.5.1" + annotationProcessor "androidx.room:room-compiler:2.5.1" + implementation "androidx.room:room-runtime:2.5.1" + implementation "androidx.room:room-ktx:2.5.1" + +// implementation 'androidx.lifecycle:lifecycle-livedata:2.6.1' +// implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1' +// implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.appcompat:appcompat:1.6.1' @@ -47,5 +56,6 @@ dependencies { implementation "androidx.fragment:fragment-ktx:1.5.5" implementation 'org.osmdroid:osmdroid-android:6.1.14' implementation 'com.github.MKergall:osmbonuspack:6.9.0' + implementation 'com.android.support:multidex:1.0.3' } \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/application/RTApplication.kt b/app/src/main/java/uca/baptistearthur/geocaching/application/RTApplication.kt new file mode 100644 index 0000000..d314a10 --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/application/RTApplication.kt @@ -0,0 +1,24 @@ +package uca.baptistearthur.geocaching.application + +import android.app.Application +import uca.baptistearthur.geocaching.data.Database + +class RTApplication: Application() { + +// val db: Database by lazy { +// Database.getInstance(this) +// } + + // + +// lateinit var db: Database +// +// override fun onCreate() { +// super.onCreate() +// +// // Initialiser la propriété db ici +// db = Database.getInstance(this) as Database +// } + + +} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/converters/Converters.kt b/app/src/main/java/uca/baptistearthur/geocaching/converters/Converters.kt new file mode 100644 index 0000000..7cd664f --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/converters/Converters.kt @@ -0,0 +1,32 @@ +package uca.baptistearthur.geocaching.converters + +import androidx.room.TypeConverter +import java.util.Date +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import uca.baptistearthur.geocaching.model.Place + +class Converters { + @TypeConverter + fun toDate(timestamp: Long?): Date? { + return if (timestamp == null) null else Date(timestamp) + } + + @TypeConverter + fun toLong(date: Date?): Long? { + return date?.time + } + + @TypeConverter + fun toString(places: List): String { + return Gson().toJson(places) + } + + @TypeConverter + fun toPlaces(value: String): List { + val listType = object : TypeToken>() {}.type + return Gson().fromJson(value, listType) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/data/Database.kt b/app/src/main/java/uca/baptistearthur/geocaching/data/Database.kt new file mode 100644 index 0000000..60629d7 --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/data/Database.kt @@ -0,0 +1,26 @@ +package uca.baptistearthur.geocaching.data + +import android.content.Context +import androidx.room.Room +import androidx.room.RoomDatabase +import androidx.room.TypeConverters +import uca.baptistearthur.geocaching.converters.Converters +import uca.baptistearthur.geocaching.model.RoadTripEntity + +@androidx.room.Database(entities = arrayOf(RoadTripEntity::class), version=1) +@TypeConverters(Converters::class) +abstract class Database : RoomDatabase(){ + + abstract fun roadTripDAO(): RoadTripDAO + + companion object{ + private var INSTANCE: Database ?= null + + fun getInstance(context: Context) = + INSTANCE ?: synchronized(this){ + val db = Room.databaseBuilder(context, Database::class.java, "roadTripDB").build() + INSTANCE = db + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/data/RoadTripDAO.kt b/app/src/main/java/uca/baptistearthur/geocaching/data/RoadTripDAO.kt new file mode 100644 index 0000000..d11f627 --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/data/RoadTripDAO.kt @@ -0,0 +1,24 @@ +package uca.baptistearthur.geocaching.data + +import androidx.annotation.RequiresPermission.Read +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.Query +import kotlinx.coroutines.flow.Flow +import uca.baptistearthur.geocaching.model.RoadTripEntity + +@androidx.room.Dao +interface RoadTripDAO { + + @Insert + suspend fun insertRoadTrip(r: RoadTripEntity) + + @Delete + suspend fun deleteRoadTrip(r: RoadTripEntity) + + @Query("SELECT * FROM Roadtrip") + fun getAllRoadTrips(): Flow> + + @Query("SELECT * FROM Roadtrip WHERE id = :id") + fun getRoadTripById(id: Int): Flow +} diff --git a/app/src/main/java/uca/baptistearthur/geocaching/data/Stub.kt b/app/src/main/java/uca/baptistearthur/geocaching/data/Stub.kt index 0ddbabe..f6b8e29 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/data/Stub.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/data/Stub.kt @@ -1,28 +1,32 @@ package uca.baptistearthur.geocaching.data import uca.baptistearthur.geocaching.model.Place -import uca.baptistearthur.geocaching.model.RoadTrip +import uca.baptistearthur.geocaching.model.RoadTripEntity import java.util.Date class Stub { - fun load(): MutableList { + fun load(): MutableList { val list = listOf( - RoadTrip( + RoadTripEntity( + 1, "France", Date(), listOf(Place(49.3, 49.3)).toMutableList() ), - RoadTrip( + RoadTripEntity( + 2, "Italie", Date(), listOf(Place(48.866667, 2.333333), Place(48.866667, 2.333333)).toMutableList() ), - RoadTrip( + RoadTripEntity( + 3, "Danemark", Date(), listOf(Place(48.866667, 2.333333), Place(48.866667, 2.333333)).toMutableList() ), - RoadTrip( + RoadTripEntity( + 4, "Islande", Date(), listOf(Place(48.866667, 2.333333), Place(48.866667, 2.333333), Place(48.866667, 2.333333)).toMutableList() diff --git a/app/src/main/java/uca/baptistearthur/geocaching/model/RoadTrip.kt b/app/src/main/java/uca/baptistearthur/geocaching/model/RoadTrip.kt deleted file mode 100644 index 7f8cc10..0000000 --- a/app/src/main/java/uca/baptistearthur/geocaching/model/RoadTrip.kt +++ /dev/null @@ -1,15 +0,0 @@ -package uca.baptistearthur.geocaching.model - -import java.util.Date - -class RoadTrip( - val name: String, - val date: Date, - val places: MutableList -){ - - fun addPlaceToRoadTripList(place: Place) = places.add(place) - fun addPlaceToRoadTripList(latitude: Double, longitude: Double) = places.add(Place(latitude, longitude)) - - -} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/model/RoadTripEntity.kt b/app/src/main/java/uca/baptistearthur/geocaching/model/RoadTripEntity.kt new file mode 100644 index 0000000..5777854 --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/model/RoadTripEntity.kt @@ -0,0 +1,19 @@ +package uca.baptistearthur.geocaching.model + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import java.util.Date + +@Entity(tableName = "Roadtrip") +class RoadTripEntity( + @PrimaryKey(autoGenerate = true) val id: Int, + @ColumnInfo(name="name") val name: String, + @ColumnInfo(name="date") val date: Date, + @ColumnInfo(name="places") val places: MutableList +){ + + fun addPlaceToRoadTripList(place: Place) = places.add(place) + fun addPlaceToRoadTripList(latitude: Double, longitude: Double) = places.add(Place(latitude, longitude)) + +} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/recyclerview/PlacesAdapter.kt b/app/src/main/java/uca/baptistearthur/geocaching/recyclerview/PlacesAdapter.kt index 3e3b60f..fcfbbc3 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/recyclerview/PlacesAdapter.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/recyclerview/PlacesAdapter.kt @@ -6,7 +6,6 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import uca.baptistearthur.geocaching.R import uca.baptistearthur.geocaching.model.Place -import uca.baptistearthur.geocaching.model.RoadTrip class PlacesAdapter (val places: List) : RecyclerView.Adapter(){ diff --git a/app/src/main/java/uca/baptistearthur/geocaching/recyclerview/RoadTripAdapter.kt b/app/src/main/java/uca/baptistearthur/geocaching/recyclerview/RoadTripAdapter.kt index 15a3d96..3ae541e 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/recyclerview/RoadTripAdapter.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/recyclerview/RoadTripAdapter.kt @@ -6,10 +6,10 @@ import android.view.ViewGroup import androidx.navigation.NavController import androidx.recyclerview.widget.RecyclerView import uca.baptistearthur.geocaching.R -import uca.baptistearthur.geocaching.model.RoadTrip +import uca.baptistearthur.geocaching.model.RoadTripEntity -class RoadTripAdapter(val voyages: List, val navController: NavController) : RecyclerView.Adapter(){ +class RoadTripAdapter(val voyages: List, val navController: NavController) : RecyclerView.Adapter(){ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RoadTripViewHolder { return RoadTripViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.cell_one_roadtrip, parent, false), navController) diff --git a/app/src/main/java/uca/baptistearthur/geocaching/services/FragmentService.kt b/app/src/main/java/uca/baptistearthur/geocaching/services/FragmentService.kt index 37359f6..62146c0 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/services/FragmentService.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/services/FragmentService.kt @@ -3,7 +3,6 @@ package uca.baptistearthur.geocaching.services import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import uca.baptistearthur.geocaching.R -import uca.baptistearthur.geocaching.ui.fragment.DetailledRoadTripFragment class FragmentService { diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/activity/MainWindow.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/activity/MainWindow.kt index 73c4971..320821d 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/ui/activity/MainWindow.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/activity/MainWindow.kt @@ -2,22 +2,28 @@ package uca.baptistearthur.geocaching.ui.activity import android.annotation.SuppressLint import android.os.Bundle +import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.navigation.findNavController import androidx.navigation.ui.NavigationUI import androidx.navigation.ui.setupWithNavController import com.google.android.material.bottomnavigation.BottomNavigationView import uca.baptistearthur.geocaching.R -import uca.baptistearthur.geocaching.services.FragmentService +import uca.baptistearthur.geocaching.application.RTApplication import uca.baptistearthur.geocaching.ui.fragment.Map +import uca.baptistearthur.geocaching.viewModels.RoadTripViewModel +import uca.baptistearthur.geocaching.viewModels.RoadTripViewModelFactory class MainWindow: AppCompatActivity() { + +// private val roadTripViewModel: RoadTripViewModel by viewModels { +// RoadTripViewModelFactory((this.application as RTApplication).db.roadTripDAO()) +// } + @SuppressLint("MissingInflatedId") override fun onCreate(savedInstanceState: Bundle?) { - val map = Map() - super.onCreate(savedInstanceState) setContentView(R.layout.main_window) @@ -34,7 +40,6 @@ class MainWindow: AppCompatActivity() { true } - } } \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/DetailledRoadTripFragment.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/DetailledRoadTripFragment.kt deleted file mode 100644 index e10fa9d..0000000 --- a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/DetailledRoadTripFragment.kt +++ /dev/null @@ -1,68 +0,0 @@ -package uca.baptistearthur.geocaching.ui.fragment - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.fragment.app.Fragment -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import uca.baptistearthur.geocaching.R -import uca.baptistearthur.geocaching.model.RoadTrip -import uca.baptistearthur.geocaching.recyclerview.PlacesAdapter -import uca.baptistearthur.geocaching.recyclerview.RoadTripAdapter - -// TODO: Rename parameter arguments, choose names that match -// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER -private const val ARG_PARAM1 = "param1" -private const val ARG_PARAM2 = "param2" - -/** - * A simple [Fragment] subclass. - * Use the [RoadTrip.newInstance] factory method to - * create an instance of this fragment. - */ -class DetailledRoadTripFragment(val roadTrip: RoadTrip): Fragment() { - // TODO: Rename and change types of parameters - private var param1: String? = null - private var param2: String? = null - private var placesRecyclerView : RecyclerView? = null - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - arguments?.let { - param1 = it.getString(ARG_PARAM1) - param2 = it.getString(ARG_PARAM2) - } - } - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - val view = inflater.inflate(R.layout.fragment_detailled_roadtrip, container, false) - - placesRecyclerView = view?.findViewById(R.id.recyclerViewPlacesList) - placesRecyclerView?.adapter = PlacesAdapter(roadTrip.places) - placesRecyclerView?.layoutManager = LinearLayoutManager(context) - - return view - } - - companion object { - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment List. - */ - // TODO: Rename and change types and number of parameters - @JvmStatic - fun newInstance(param1: String, param2: String) = - RoadTripFragment().apply { - arguments = Bundle().apply { - putString(ARG_PARAM1, param1) - putString(ARG_PARAM2, param2) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadTripFragment.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadTripFragment.kt index 75dd307..74b045c 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadTripFragment.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadTripFragment.kt @@ -13,7 +13,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import uca.baptistearthur.geocaching.R import uca.baptistearthur.geocaching.data.Stub -import uca.baptistearthur.geocaching.model.RoadTrip +import uca.baptistearthur.geocaching.model.RoadTripEntity import uca.baptistearthur.geocaching.recyclerview.RoadTripAdapter import java.util.* @@ -24,7 +24,7 @@ private const val ARG_PARAM2 = "param2" /** * A simple [Fragment] subclass. - * Use the [RoadTrip.newInstance] factory method to + * Use the [RoadTripEntity.newInstance] factory method to * create an instance of this fragment. */ class RoadTripFragment : Fragment() { @@ -33,8 +33,6 @@ class RoadTripFragment : Fragment() { private var param2: String? = null private var model = Stub().load() private var roadTripRecyclerView : RecyclerView? = null - private var editTextRoadTripName: EditText? = null - private var buttonAddNewRoadTrip: Button? = null override fun onCreate(savedInstanceState: Bundle?) { @@ -49,36 +47,13 @@ class RoadTripFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflater.inflate(R.layout.fragment_roadtrip, container, false) - - roadTripRecyclerView = view?.findViewById(R.id.recyclerViewRoadTripList) roadTripRecyclerView?.adapter = RoadTripAdapter(model, findNavController()) roadTripRecyclerView?.layoutManager = LinearLayoutManager(context) - editTextRoadTripName = view?.findViewById(R.id.editTextRoadTripName) - buttonAddNewRoadTrip = view?.findViewById(R.id.buttonAddNewRoadTrip) - - buttonAddNewRoadTrip?.setOnClickListener { - addRoadTrip(editTextRoadTripName!!, roadTripRecyclerView!!) - } - return view } - @SuppressLint("NotifyDataSetChanged") - fun addRoadTrip(editText: EditText, recyclerView: RecyclerView) { - val roadTripName = editText.text.toString().trim() - if(roadTripName.isNotEmpty() && roadTripName.length <= 20){ - editText.text?.clear() - val roadTrip = RoadTrip(roadTripName, Date(), mutableListOf()) - model.add(roadTrip) - recyclerView.adapter?.notifyDataSetChanged() - }else{ - editText.error = "Le nom du voyage doit être compris entre 1 et 20 caractères." - } - } - - companion object { /** * Use this factory method to create a new instance of diff --git a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadtripDetail.kt b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadtripDetail.kt index b812524..44cfe88 100644 --- a/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadtripDetail.kt +++ b/app/src/main/java/uca/baptistearthur/geocaching/ui/fragment/RoadtripDetail.kt @@ -19,6 +19,8 @@ import android.location.LocationListener import android.util.Log import android.widget.ProgressBar import androidx.activity.result.contract.ActivityResultContracts +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import org.osmdroid.bonuspack.routing.OSRMRoadManager import org.osmdroid.bonuspack.routing.RoadManager import org.osmdroid.config.IConfigurationProvider @@ -30,19 +32,26 @@ import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay import uca.baptistearthur.geocaching.R +import uca.baptistearthur.geocaching.recyclerview.PlacesAdapter import uca.baptistearthur.geocaching.ui.overlay.AddMarkerOverlay import uca.baptistearthur.geocaching.ui.overlay.RecenterOverlay class RoadtripDetail : Fragment() { - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { + private var placesRecyclerView : RecyclerView? = null + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { Log.d("GeoMap", "MAP ON CREATE VIEW") // Inflate the layout for this fragment val view = inflater.inflate(R.layout.roadtrip_detail, container, false) + +// val roadTrip = // récupérer le roadtrip cliqué +// placesRecyclerView = view?.findViewById(R.id.recyclerViewPlacesList) +// placesRecyclerView?.adapter = PlacesAdapter(roadTrip.places) +// placesRecyclerView?.layoutManager = LinearLayoutManager(context) + return view } + + } \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/viewModels/RoadTripViewModel.kt b/app/src/main/java/uca/baptistearthur/geocaching/viewModels/RoadTripViewModel.kt new file mode 100644 index 0000000..262a4f1 --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/viewModels/RoadTripViewModel.kt @@ -0,0 +1,27 @@ +package uca.baptistearthur.geocaching.viewModels + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.launch +import uca.baptistearthur.geocaching.data.RoadTripDAO +import uca.baptistearthur.geocaching.model.RoadTripEntity + +class RoadTripViewModel(val dao: RoadTripDAO): ViewModel() { + + fun getRoadTripById(id: Int) = dao.getRoadTripById(id) // .asLiveData() // ne marche pas -> impossible d'importer + + fun getAllRoadTrips() = dao.getAllRoadTrips() // .asLiveData() + + fun insertRoadTrip(r: RoadTripEntity){ + viewModelScope.launch { + dao.insertRoadTrip(r) + } + } + + fun deleteRoadTrip(r: RoadTripEntity){ + viewModelScope.launch { + dao.deleteRoadTrip(r) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/uca/baptistearthur/geocaching/viewModels/RoadTripViewModelFactory.kt b/app/src/main/java/uca/baptistearthur/geocaching/viewModels/RoadTripViewModelFactory.kt new file mode 100644 index 0000000..0680471 --- /dev/null +++ b/app/src/main/java/uca/baptistearthur/geocaching/viewModels/RoadTripViewModelFactory.kt @@ -0,0 +1,15 @@ +package uca.baptistearthur.geocaching.viewModels + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import uca.baptistearthur.geocaching.data.RoadTripDAO + +class RoadTripViewModelFactory(private val dao: RoadTripDAO): ViewModelProvider.Factory{ + + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(RoadTripViewModel::class.java)){ + return RoadTripViewModel(dao) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_detailled_roadtrip.xml b/app/src/main/res/layout/fragment_detailled_roadtrip.xml deleted file mode 100644 index 8fb1614..0000000 --- a/app/src/main/res/layout/fragment_detailled_roadtrip.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - -