AttendanceList fonctionnelle avec lecture des cartes NFC
This commit is contained in:
parent
0775eb13da
commit
d7bade2287
10 changed files with 135 additions and 62 deletions
|
@ -18,13 +18,19 @@
|
|||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".PaltoActivity"
|
||||
android:exported="true" >
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
|
|
|
@ -5,42 +5,46 @@ import android.nfc.Tag
|
|||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.activity.viewModels
|
||||
|
||||
|
||||
class PaltoActivity : AppCompatActivity() {
|
||||
|
||||
private var nfcAdapter: NfcAdapter? = null
|
||||
|
||||
private val paltoViewModel: PaltoViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_palto)
|
||||
|
||||
// get the NFC Adapter
|
||||
this.nfcAdapter = NfcAdapter.getDefaultAdapter(this)
|
||||
nfcAdapter = NfcAdapter.getDefaultAdapter(this)
|
||||
|
||||
// check if NFC is supported
|
||||
if (this.nfcAdapter == null) {
|
||||
if (nfcAdapter == null) {
|
||||
Log.e("NFC", "NFC is not supported")
|
||||
return
|
||||
}
|
||||
|
||||
// check if NFC is disabled
|
||||
if (!(this.nfcAdapter!!.isEnabled)) {
|
||||
if (nfcAdapter?.isEnabled == false) {
|
||||
Log.w("NFC", "NFC is not enabled")
|
||||
}
|
||||
|
||||
// TEST
|
||||
/*
|
||||
setContentView(R.layout.activity_palto)
|
||||
/*
|
||||
val url = URL("https://www.faraphel.fr/palto/api/auth/token/")
|
||||
val connection = url.openConnection()
|
||||
val auth_data = Json.decodeFromString(connection.content)*/
|
||||
val auth_data = Json.decodeFromString(connection.content)
|
||||
*/
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
nfcAdapter!!.enableReaderMode(
|
||||
nfcAdapter?.enableReaderMode(
|
||||
this,
|
||||
this::processTag,
|
||||
paltoViewModel.tagLiveData::postValue,
|
||||
NfcAdapter.FLAG_READER_NFC_A or NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,
|
||||
null
|
||||
)
|
||||
|
@ -50,11 +54,11 @@ class PaltoActivity : AppCompatActivity() {
|
|||
super.onPause()
|
||||
|
||||
// disable the NFC discovery
|
||||
this.nfcAdapter!!.disableReaderMode(this)
|
||||
nfcAdapter?.disableReaderMode(this)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
fun processTag(tag: Tag) {
|
||||
Log.d("NFC", "Tag ID : ${tag.id.toHexString()}")
|
||||
Log.d("NFC", "Tag ID : " + tag.id.toHexString())
|
||||
}
|
||||
}
|
||||
|
|
9
app/src/main/java/com/example/palto/PaltoViewModel.kt
Normal file
9
app/src/main/java/com/example/palto/PaltoViewModel.kt
Normal file
|
@ -0,0 +1,9 @@
|
|||
package com.example.palto
|
||||
|
||||
import android.nfc.Tag
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
class PaltoViewModel: ViewModel() {
|
||||
val tagLiveData = MutableLiveData<Tag>()
|
||||
}
|
|
@ -2,5 +2,22 @@ package com.example.palto.model
|
|||
import java.io.Serializable
|
||||
|
||||
data class Card(
|
||||
val id: String
|
||||
) : Serializable
|
||||
val id: String,
|
||||
val uid: ByteArray,
|
||||
val department: String,
|
||||
val owner: String
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Card
|
||||
|
||||
return uid.contentEquals(other.uid)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return uid.contentHashCode()
|
||||
}
|
||||
|
||||
}
|
|
@ -1,14 +1,13 @@
|
|||
package com.example.palto.ui.attendanceList
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import com.example.palto.model.Card
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.example.palto.databinding.FragmentAttendanceItemBinding
|
||||
import com.example.palto.model.Card
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -30,9 +29,10 @@ class AttendanceListAdapter :
|
|||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
holder.cardId.text = item.id
|
||||
holder.cardId.text = item.uid.toHexString()
|
||||
//holder.contentView.text = item.content
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
package com.example.palto.ui.attendanceList
|
||||
|
||||
import android.nfc.NfcAdapter
|
||||
import android.nfc.Tag
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.navigation.navGraphViewModels
|
||||
import com.example.palto.PaltoViewModel
|
||||
import com.example.palto.R
|
||||
import com.example.palto.databinding.FragmentAttendanceListBinding
|
||||
|
||||
|
@ -17,22 +21,49 @@ import com.example.palto.databinding.FragmentAttendanceListBinding
|
|||
class AttendanceListFragment : Fragment() {
|
||||
|
||||
private val attendanceListViewModel: AttendanceListViewModel by
|
||||
navGraphViewModels(R.id.nav_graph)
|
||||
navGraphViewModels(R.id.nav_graph) { AttendanceListViewModel.Factory }
|
||||
|
||||
private val paltoViewModel: PaltoViewModel by
|
||||
activityViewModels()
|
||||
|
||||
private var _binding: FragmentAttendanceListBinding? = null
|
||||
// This property is only valid between onCreateView and onDestroyView
|
||||
private val binding get() = _binding!!
|
||||
|
||||
/**
|
||||
* Only inflate the view.
|
||||
*/
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val binding = FragmentAttendanceListBinding.inflate(inflater, container, false)
|
||||
|
||||
val adapter = AttendanceListAdapter()
|
||||
binding.list.adapter = adapter
|
||||
|
||||
attendanceListViewModel.cardsLiveData.observe(viewLifecycleOwner) {
|
||||
it -> adapter.submitList(it)
|
||||
}
|
||||
|
||||
_binding = FragmentAttendanceListBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
/**
|
||||
* Logic on the returned view of onCreateView.
|
||||
*/
|
||||
override fun onViewCreated(
|
||||
view: View,
|
||||
savedInstanceState: Bundle?
|
||||
) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// Set the adapter of the view for managing automatically the list of items on the screen.
|
||||
val adapter = AttendanceListAdapter()
|
||||
binding.list.adapter = adapter
|
||||
attendanceListViewModel.cardsLiveData.observe(viewLifecycleOwner) {
|
||||
Log.d("NFC", "A card has been had to the list")
|
||||
adapter.submitList(it)
|
||||
}
|
||||
|
||||
// Set the listener for a new NFC tag.
|
||||
paltoViewModel.tagLiveData.observe(viewLifecycleOwner) {
|
||||
Log.d("NFC", "tag observer has been notified")
|
||||
attendanceListViewModel.insertCard(it)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package com.example.palto.ui.attendanceList
|
||||
|
||||
import android.nfc.Tag
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
@ -7,32 +9,41 @@ import androidx.lifecycle.ViewModelProvider
|
|||
import com.example.palto.data.network.ServerDataSource
|
||||
import com.example.palto.data.repository.AttendanceRepository
|
||||
import com.example.palto.model.Card
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* ViewModel of a session which has a list of attendances.
|
||||
*/
|
||||
class AttendanceListViewModel(
|
||||
private val attendanceRepository: AttendanceRepository
|
||||
) : ViewModel() {
|
||||
|
||||
private val cardsList: MutableList<Card> = mutableListOf()
|
||||
val cardsLiveData: LiveData<List<Card>> = MutableLiveData(cardsList)
|
||||
val cardsLiveData: MutableLiveData<List<Card>> = MutableLiveData(emptyList())
|
||||
|
||||
fun insertCard(cardId: String) {
|
||||
val card = Card(cardId)
|
||||
cardsList.add(card)
|
||||
fun insertCard(tag: Tag) {
|
||||
val card = Card(
|
||||
"0",
|
||||
tag.id,
|
||||
"tmp",
|
||||
"tmp"
|
||||
)
|
||||
cardsLiveData.value = (cardsLiveData.value ?: emptyList()) + card
|
||||
Log.d("NFC", "view model: A card has been had to the list")
|
||||
}
|
||||
|
||||
/**
|
||||
* ViewModel Factory.
|
||||
*/
|
||||
companion object {
|
||||
|
||||
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(
|
||||
modelClass: Class<T>
|
||||
): T {
|
||||
return AttendanceListViewModel(
|
||||
AttendanceRepository(ServerDataSource())
|
||||
) as T
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AttendanceListViewModelFactory : ViewModelProvider.Factory {
|
||||
|
||||
//@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
if (modelClass.isAssignableFrom(AttendanceListViewModel::class.java)) {
|
||||
return AttendanceListViewModel(
|
||||
attendanceRepository = AttendanceRepository(
|
||||
dataSource = ServerDataSource()
|
||||
)
|
||||
) as T
|
||||
}
|
||||
throw IllegalArgumentException("Unknown ViewModel class")
|
||||
}
|
||||
}
|
|
@ -24,8 +24,7 @@ class LoginFragment : Fragment() {
|
|||
|
||||
private var _binding: FragmentLoginBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(
|
||||
|
@ -73,7 +72,7 @@ class LoginFragment : Fragment() {
|
|||
showLoginFailed(it)
|
||||
}
|
||||
loginResult.success?.let {
|
||||
findNavController().navigate(R.id.action_loginFragment_to_attendanceFragment)
|
||||
//findNavController().navigate(R.id.action_loginFragment_to_attendanceFragment)
|
||||
//updateUiWithUser(it)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -3,23 +3,19 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/nav_graph"
|
||||
app:startDestination="@id/loginFragment">
|
||||
app:startDestination="@id/attendanceListFragment">
|
||||
<fragment
|
||||
android:id="@+id/loginFragment"
|
||||
android:name="com.example.palto.ui.login.LoginFragment"
|
||||
android:label="fragment._login"
|
||||
tools:layout="@layout/fragment_login" >
|
||||
<action
|
||||
android:id="@+id/action_loginFragment_to_attendanceFragment"
|
||||
app:destination="@id/attendanceFragment" />
|
||||
</fragment>
|
||||
tools:layout="@layout/fragment_login" />
|
||||
<fragment
|
||||
android:id="@+id/sessionListFragment"
|
||||
android:name="com.example.palto.ui.sessionList.SessionListFragment"
|
||||
android:label="fragment_session_list"
|
||||
tools:layout="@layout/fragment_session_list" />
|
||||
<fragment
|
||||
android:id="@+id/attendanceFragment"
|
||||
android:id="@+id/attendanceListFragment"
|
||||
android:name="com.example.palto.ui.attendanceList.AttendanceListFragment"
|
||||
android:label="fragment_attendance_list"
|
||||
tools:layout="@layout/fragment_attendance_list" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
id("com.android.application") version "8.1.4" apply false
|
||||
id("com.android.application") version "8.2.0" apply false
|
||||
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
|
||||
}
|
Loading…
Reference in a new issue