From f1354254442aac8c34fd3eed0c6d3352af75108f Mon Sep 17 00:00:00 2001 From: Mathieu Sanchez Date: Thu, 16 Apr 2020 14:32:46 +0200 Subject: [PATCH] Changing attestation data to ArrayList Adding PdfViewerActivity Adding providePdfUtils in Injector --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 3 +- .../attestationsCovid19/MainActivity.kt | 5 +- .../attestationsCovid19/PdfViewerActivity.kt | 24 +++++++ .../data/db/dao/AttestationDao.kt | 6 +- .../data/db/entity/Attestation.kt | 10 +-- .../ui/attestations/AttestationsFragment.kt | 15 ++++ .../ui/attestations/AttestationsViewModel.kt | 17 ++++- .../utilities/InjectorUtils.kt | 7 ++ .../attestationsCovid19/utilities/PdfUtils.kt | 72 +++++++++++++++++-- .../utilities/QRCodeUtils.kt | 10 +-- .../main/res/drawable/custom_rectangle.xml | 13 ++++ .../main/res/layout/activity_pdf_viewer.xml | 20 ++++++ app/src/main/res/layout/attestation_item.xml | 34 +++++++++ .../main/res/layout/fragment_attestations.xml | 26 +++++-- app/src/main/res/values/strings.xml | 5 ++ 16 files changed, 240 insertions(+), 28 deletions(-) create mode 100644 app/src/main/java/fr/sanchezm/attestationsCovid19/PdfViewerActivity.kt create mode 100644 app/src/main/res/drawable/custom_rectangle.xml create mode 100644 app/src/main/res/layout/activity_pdf_viewer.xml create mode 100644 app/src/main/res/layout/attestation_item.xml diff --git a/app/build.gradle b/app/build.gradle index 2ab8985..9da2caf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,6 +67,7 @@ dependencies { // PDF implementation 'com.tom_roush:pdfbox-android:1.8.10.1' + implementation 'com.github.barteksc:android-pdf-viewer:3.2.0-beta.1' // Gson implementation 'com.google.code.gson:gson:2.8.6' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3ff6c1a..f847135 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,12 +6,13 @@ + diff --git a/app/src/main/java/fr/sanchezm/attestationsCovid19/MainActivity.kt b/app/src/main/java/fr/sanchezm/attestationsCovid19/MainActivity.kt index 523697b..51364ae 100644 --- a/app/src/main/java/fr/sanchezm/attestationsCovid19/MainActivity.kt +++ b/app/src/main/java/fr/sanchezm/attestationsCovid19/MainActivity.kt @@ -6,7 +6,7 @@ import androidx.navigation.findNavController import androidx.navigation.ui.setupWithNavController import com.google.android.material.bottomnavigation.BottomNavigationView import com.tom_roush.pdfbox.util.PDFBoxResourceLoader -import fr.sanchezm.attestationsCovid19.utilities.PdfUtils +import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils class MainActivity : AppCompatActivity() { @@ -19,12 +19,11 @@ class MainActivity : AppCompatActivity() { val navController = findNavController(R.id.nav_host_fragment) PDFBoxResourceLoader.init(applicationContext) - PdfUtils.getInstance(assets, getMyFilesDir()) + InjectorUtils.providePdfUtils(applicationContext) actionBar?.hide() navView.setupWithNavController(navController) navView.setBackgroundColor(resources.getColor(R.color.itemBackground, theme)) } - private fun getMyFilesDir(): String = filesDir.path } \ No newline at end of file diff --git a/app/src/main/java/fr/sanchezm/attestationsCovid19/PdfViewerActivity.kt b/app/src/main/java/fr/sanchezm/attestationsCovid19/PdfViewerActivity.kt new file mode 100644 index 0000000..0f91858 --- /dev/null +++ b/app/src/main/java/fr/sanchezm/attestationsCovid19/PdfViewerActivity.kt @@ -0,0 +1,24 @@ +package fr.sanchezm.attestationsCovid19 + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.github.barteksc.pdfviewer.PDFView +import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils +import java.io.File + +class PdfViewerActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_pdf_viewer) + val createAt = intent.getLongExtra("createAt", 0) + val pdfUtils = InjectorUtils.providePdfUtils(applicationContext) + + findViewById(R.id.pdfView).also { + it.fromFile(File(pdfUtils.getPath(createAt))) + .enableAnnotationRendering(true) + .spacing(20) + .load() + } + } +} diff --git a/app/src/main/java/fr/sanchezm/attestationsCovid19/data/db/dao/AttestationDao.kt b/app/src/main/java/fr/sanchezm/attestationsCovid19/data/db/dao/AttestationDao.kt index eef5377..fd937fb 100644 --- a/app/src/main/java/fr/sanchezm/attestationsCovid19/data/db/dao/AttestationDao.kt +++ b/app/src/main/java/fr/sanchezm/attestationsCovid19/data/db/dao/AttestationDao.kt @@ -9,14 +9,14 @@ import java.io.File class AttestationDao(private val path: String) { - private var _attestations = MutableLiveData>() + private var _attestations = MutableLiveData>() private var fileName = "attestation.db" private val type = object : TypeToken>() {}.type - fun getAttestations() : LiveData> = + fun getAttestations() : LiveData> = _attestations - fun getAttestation(id: Int) : Attestation? = + fun getAttestation(id: Int): Attestation? = _attestations.value?.elementAt(id) fun addAttestation(attestation: Attestation) { diff --git a/app/src/main/java/fr/sanchezm/attestationsCovid19/data/db/entity/Attestation.kt b/app/src/main/java/fr/sanchezm/attestationsCovid19/data/db/entity/Attestation.kt index e9d0380..2af8b61 100644 --- a/app/src/main/java/fr/sanchezm/attestationsCovid19/data/db/entity/Attestation.kt +++ b/app/src/main/java/fr/sanchezm/attestationsCovid19/data/db/entity/Attestation.kt @@ -3,6 +3,8 @@ package fr.sanchezm.attestationsCovid19.data.db.entity import java.text.SimpleDateFormat import java.util.* +const val PATTERN = "dd/MM/yyyy 'a' HH:mm" + //@Entity(tableName = "attestation") data class Attestation( val profile: Profile, @@ -11,8 +13,6 @@ data class Attestation( var createAt: Long, val reasons: List ) { - private val pattern = "dd/MM/yyyy 'a' HH:mm" - override fun toString(): String { val motifs = StringBuilder() @@ -20,9 +20,9 @@ data class Attestation( return "Cree le: ${getDate(createAt)}; $profile; Sortie: $exitDate a $exitHour; Motifs: $motifs" } - private fun getDate(dateTime: Long): String { - return SimpleDateFormat(pattern, Locale.FRANCE).format(Date(dateTime)) - } + fun getCreatedAtFormatedDate(): String = getDate(createAt) + + private fun getDate(dateTime: Long): String = SimpleDateFormat(PATTERN, Locale.FRANCE).format(Date(dateTime)) private fun getMotifText(i: Int): String { return when (i) { diff --git a/app/src/main/java/fr/sanchezm/attestationsCovid19/ui/attestations/AttestationsFragment.kt b/app/src/main/java/fr/sanchezm/attestationsCovid19/ui/attestations/AttestationsFragment.kt index 1c4336c..e1f1e11 100644 --- a/app/src/main/java/fr/sanchezm/attestationsCovid19/ui/attestations/AttestationsFragment.kt +++ b/app/src/main/java/fr/sanchezm/attestationsCovid19/ui/attestations/AttestationsFragment.kt @@ -1,12 +1,15 @@ package fr.sanchezm.attestationsCovid19.ui.attestations +import android.content.Intent import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment +import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider +import fr.sanchezm.attestationsCovid19.PdfViewerActivity import fr.sanchezm.attestationsCovid19.R import fr.sanchezm.attestationsCovid19.databinding.FragmentAttestationsBinding import fr.sanchezm.attestationsCovid19.utilities.InjectorUtils @@ -31,9 +34,21 @@ class AttestationsFragment : Fragment() { this.viewModel = attestationsViewModel } + bindMessage() return binding.root } + private fun bindMessage() { + attestationsViewModel.startActivity.observe(viewLifecycleOwner, Observer { + it.getContentIfNotHandled()?.let { createAtPdf -> + val intent = Intent(context, PdfViewerActivity::class.java).apply { + putExtra("createAt", createAtPdf) + } + startActivity(intent) + } + }) + } + private fun initializeUi() { val factory = context?.let { InjectorUtils.provideAttestationViewModel(it) } attestationsViewModel = factory?.let { diff --git a/app/src/main/java/fr/sanchezm/attestationsCovid19/ui/attestations/AttestationsViewModel.kt b/app/src/main/java/fr/sanchezm/attestationsCovid19/ui/attestations/AttestationsViewModel.kt index a491517..1d56f32 100644 --- a/app/src/main/java/fr/sanchezm/attestationsCovid19/ui/attestations/AttestationsViewModel.kt +++ b/app/src/main/java/fr/sanchezm/attestationsCovid19/ui/attestations/AttestationsViewModel.kt @@ -1,17 +1,30 @@ package fr.sanchezm.attestationsCovid19.ui.attestations +import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository +import fr.sanchezm.attestationsCovid19.utilities.Event class AttestationsViewModel(private val attestationRepository: AttestationRepository) : ViewModel() { - val attestationName = MutableLiveData() + private var attestationCreateAt: Long + private val _startActivity = MutableLiveData>() + private val _attestationName = MutableLiveData() + + val startActivity: LiveData> = + _startActivity + + val attestationName: LiveData = + _attestationName fun onClick() { + _startActivity.value = Event(attestationCreateAt) } init { - attestationRepository.getAttestation(0) + val attestation = attestationRepository.getAttestations().value?.last() + attestationCreateAt = attestation?.createAt!! + _attestationName.value = "${attestation.profile.firstName} ${attestation.profile.lastName}" } } \ No newline at end of file diff --git a/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/InjectorUtils.kt b/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/InjectorUtils.kt index f825417..0eb0aa9 100644 --- a/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/InjectorUtils.kt +++ b/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/InjectorUtils.kt @@ -1,6 +1,7 @@ package fr.sanchezm.attestationsCovid19.utilities import android.content.Context +import android.os.Environment import fr.sanchezm.attestationsCovid19.data.db.MyDatabase import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository import fr.sanchezm.attestationsCovid19.data.repository.ProfileRepository @@ -25,4 +26,10 @@ object InjectorUtils { return AttestationsViewModelFactory(attestationRepository) } + fun providePdfUtils(context: Context): PdfUtils { + return PdfUtils.getInstance(context.assets, getMyFilesDir(context)) + } + + private fun getMyFilesDir(context: Context): String = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.path!! + } \ No newline at end of file diff --git a/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/PdfUtils.kt b/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/PdfUtils.kt index c9159e3..6b22691 100644 --- a/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/PdfUtils.kt +++ b/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/PdfUtils.kt @@ -3,6 +3,11 @@ package fr.sanchezm.attestationsCovid19.utilities import android.content.res.AssetManager import android.util.Log import com.tom_roush.pdfbox.pdmodel.PDDocument +import com.tom_roush.pdfbox.pdmodel.PDPage +import com.tom_roush.pdfbox.pdmodel.PDPageContentStream +import com.tom_roush.pdfbox.pdmodel.common.PDRectangle +import com.tom_roush.pdfbox.pdmodel.font.PDType1Font +import com.tom_roush.pdfbox.pdmodel.graphics.image.LosslessFactory import com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm import com.tom_roush.pdfbox.pdmodel.interactive.form.PDCheckbox import com.tom_roush.pdfbox.pdmodel.interactive.form.PDTextField @@ -20,6 +25,7 @@ class PdfUtils private constructor( private val folderPath = "attestations" private val checkboxListNames = ArrayList() + private val font = PDType1Font.HELVETICA fun fillForm(attestation: Attestation) { checkFolder() @@ -33,17 +39,75 @@ class PdfUtils private constructor( setFieldsData(acroForm, attestation) setCheckboxFields(acroForm, attestation) attestation.createAt = Date().time + addPageWithQrCode(document, attestation) - val savePath = "$path/$folderPath/${attestation.createAt}.pdf" - - Log.v("PdfUtils", "Save File to $savePath") - document.save(savePath) + Log.v("PdfUtils", "Save File to ${getPath(attestation.createAt)}") + document.save(getPath(attestation.createAt)) document.close() } catch (e: IOException) { e.printStackTrace() } } + fun getPath(createAt: Long): String = "$path/$folderPath/$createAt.pdf" + + private fun addPageWithQrCode(document: PDDocument, attestation: Attestation) { + val size = 360 + val margin = 40f + +// Add QRCode on the first page + val page1: PDPage = document.pages.first() + Log.v("PdfUtils", "Width: ${page1.mediaBox.width}; Height: ${page1.mediaBox.height}") + addQrCode( + document, + page1, + attestation, + size / 3, + page1.mediaBox.upperRightX - margin - size / 3 - 30, + 141f, + true + ) + + // Add QRCode on a new page + val page2 = PDPage(PDRectangle.A4) + + document.addPage(page2) + addQrCode(document, page2, attestation, size, margin, page2.mediaBox.height - (size + margin)) + + } + + private fun addQrCode( + document: PDDocument, + page: PDPage, + attestation: Attestation, + size: Int, + x: Float, + y: Float, + addText: Boolean = false + ) { + + val contentStream = PDPageContentStream(document, page, true, false) + val alphaXimage = + LosslessFactory.createFromImage(document, QRCodeUtils.getQrCode(attestation, size)) + + contentStream.drawImage(alphaXimage, x, y) + if (addText) { + contentStream.beginText() + contentStream.setFont(font, 7f) + contentStream.newLineAtOffset(page.mediaBox.upperRightX - size - 20, 145f) + contentStream.showText("Date de création:") + contentStream.endText() + + contentStream.beginText() + contentStream.setFont(font, 7f) + contentStream.newLineAtOffset(page.mediaBox.upperRightX - size - 27, 138f) + contentStream.showText(attestation.getCreatedAtFormatedDate()) + contentStream.endText() + } + contentStream.close() + + } + private fun setFieldsData(acroForm: PDAcroForm, attestation: Attestation) { val profile = attestation.profile diff --git a/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/QRCodeUtils.kt b/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/QRCodeUtils.kt index fab1679..cc60289 100644 --- a/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/QRCodeUtils.kt +++ b/app/src/main/java/fr/sanchezm/attestationsCovid19/utilities/QRCodeUtils.kt @@ -9,9 +9,11 @@ import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation class QRCodeUtils { - fun getQrCode(attestation: Attestation): Bitmap = - BarcodeEncoder().createBitmap(getMultiFormatWriter(attestation)) + companion object { + fun getQrCode(attestation: Attestation, size: Int): Bitmap = + BarcodeEncoder().createBitmap(getMultiFormatWriter(attestation, size)) - private fun getMultiFormatWriter(attestation: Attestation) = - MultiFormatWriter().encode(attestation.toString(), BarcodeFormat.QR_CODE, 150, 150) + private fun getMultiFormatWriter(attestation: Attestation, size: Int) = + MultiFormatWriter().encode(attestation.toString(), BarcodeFormat.QR_CODE, size, size) + } } \ No newline at end of file diff --git a/app/src/main/res/drawable/custom_rectangle.xml b/app/src/main/res/drawable/custom_rectangle.xml new file mode 100644 index 0000000..20f7a82 --- /dev/null +++ b/app/src/main/res/drawable/custom_rectangle.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_pdf_viewer.xml b/app/src/main/res/layout/activity_pdf_viewer.xml new file mode 100644 index 0000000..4a38e64 --- /dev/null +++ b/app/src/main/res/layout/activity_pdf_viewer.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/attestation_item.xml b/app/src/main/res/layout/attestation_item.xml new file mode 100644 index 0000000..d5eb6fc --- /dev/null +++ b/app/src/main/res/layout/attestation_item.xml @@ -0,0 +1,34 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_attestations.xml b/app/src/main/res/layout/fragment_attestations.xml index b7f0507..ea657fc 100644 --- a/app/src/main/res/layout/fragment_attestations.xml +++ b/app/src/main/res/layout/fragment_attestations.xml @@ -1,7 +1,9 @@ + xmlns:tools="http://schemas.android.com/tools" + android:paddingHorizontal="30dp" + android:paddingVertical="20dp"> - + + \ 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 0c14c75..99a2422 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -40,4 +40,9 @@ "Développer avec ❤️ par Mathieu Sanchez" Version : + + + Personne : + Date de sortie : + Raison(s) :