AttendanceList fonctionnelle avec lecture des cartes NFC

This commit is contained in:
biloute02 2023-12-30 17:46:08 +01:00
parent 0775eb13da
commit d7bade2287
10 changed files with 135 additions and 62 deletions

View file

@ -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>

View file

@ -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())
}
}

View 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>()
}

View file

@ -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()
}
}

View file

@ -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
}

View file

@ -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)
}
}
}

View file

@ -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")
}
}

View file

@ -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)
}
})

View file

@ -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" />

View file

@ -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
}