From e74c307566075dc9527908a37bbcc11d9be4a9ef Mon Sep 17 00:00:00 2001 From: Seil0 Date: Sun, 18 Aug 2019 22:09:33 +0200 Subject: [PATCH] cleand up the nfc part, added foreground-dispatch * cleaned up the strings.xml files * fixed license dialog --- app/build.gradle | 3 +- .../mosad/seil0/projectlaogai/MainActivity.kt | 75 ++++++--------- .../projectlaogai/controller/NFCMensaCard.kt | 93 +++++++++++++++++++ .../controller/PreferencesController.kt | 1 + .../fragments/SettingsFragment.kt | 5 + app/src/main/res/layout/nav_header_main.xml | 2 +- app/src/main/res/raw/notices.xml | 4 +- app/src/main/res/values-de-rDE/strings.xml | 42 ++++++--- app/src/main/res/values/strings.xml | 22 +++-- 9 files changed, 178 insertions(+), 69 deletions(-) create mode 100644 app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt diff --git a/app/build.gradle b/app/build.gradle index ebfb9cf..8928012 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,7 +13,7 @@ android { minSdkVersion 23 targetSdkVersion 28 versionCode 14 - versionName "0.4.94" + versionName "0.4.95" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" resValue "string", "build_time", buildTime() setProperty("archivesBaseName", "projectlaogai-$versionName") @@ -24,6 +24,7 @@ android { minifyEnabled false shrinkResources false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + versionNameSuffix "-release" } debug { versionNameSuffix "-debug" diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt index c151b8d..cc1f96f 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt @@ -22,12 +22,12 @@ package org.mosad.seil0.projectlaogai +import android.app.PendingIntent import android.content.Intent +import android.content.IntentFilter import android.graphics.Color -import android.nfc.NdefMessage import android.nfc.NfcAdapter -import android.nfc.Tag -import android.nfc.tech.IsoDep +import android.nfc.tech.NfcA import android.os.Bundle import android.view.Menu import android.view.MenuItem @@ -37,20 +37,16 @@ import androidx.core.view.GravityCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentTransaction import com.afollestad.aesthetic.Aesthetic -import com.afollestad.materialdialogs.MaterialDialog -import com.codebutler.farebot.card.desfire.DesfireProtocol import com.google.android.material.navigation.NavigationView import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.app_bar_main.* import org.mosad.seil0.projectlaogai.controller.CacheController +import org.mosad.seil0.projectlaogai.controller.NFCMensaCard import org.mosad.seil0.projectlaogai.controller.PreferencesController import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cColorAccent import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cColorPrimary import org.mosad.seil0.projectlaogai.fragments.* import kotlin.system.measureTimeMillis -import com.codebutler.farebot.Utils.selectAppFile -import com.codebutler.farebot.card.desfire.DesfireFileSettings -import java.lang.Exception // TODO save the current fragment to show it when the app is restarted @@ -58,6 +54,11 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte private var activeFragment: Fragment = HomeFragment() // the currently active fragment, home at the start + private lateinit var adapter: NfcAdapter + private lateinit var pendingIntent: PendingIntent + private lateinit var intentFiltersArray: Array + private lateinit var techListsArray: Array> + override fun onCreate(savedInstanceState: Bundle?) { Aesthetic.attach(this) super.onCreate(savedInstanceState) @@ -67,6 +68,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte // load mensa, timetable and color load() initAesthetic() + initForegroundDispatch() //init home fragment val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction() @@ -81,65 +83,37 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte nav_view.setNavigationItemSelectedListener(this) - // TODO nfc stuff, needs to move to it's own function - if (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action) { - val appId = 0x5F8415 - val fileId = 1 - - val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG) - - val isoDep = IsoDep.get(tag) - isoDep.connect() - - val card = DesfireProtocol(isoDep) - val settings = selectAppFile(card, appId, fileId) - - if (settings is DesfireFileSettings.ValueDesfireFileSettings) { - val data = try { - card.readValue(fileId) - } catch (ex: Exception) { 0 } - - MaterialDialog(this) - .title(text = "Mensa balance") - .message(text = "current: ${data / 1000}.${(data % 1000) / 10}€\n" + - "latest: ${settings.value / 1000}.${(settings.value % 1000) / 10}€") - .show() - } - } + // if we get an NFC read intent while the app is closed call readBalance + if (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action) + NFCMensaCard.readBalance(intent, this) } override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) - if (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action) { - intent.getParcelableArrayExtra(NfcAdapter.EXTRA_TAG)?.also { rawMessages -> - val messages: List = rawMessages.map { it as NdefMessage } - // Process the messages array. - - MaterialDialog(this) - .title(text = "nfc tag detected (onNewIntent)") - .message(text = messages[0].toString()) - .show() - - } - } + if (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action) + NFCMensaCard.readBalance(intent, this) } override fun onResume() { super.onResume() Aesthetic.resume(this) + adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray) + } override fun onPause() { super.onPause() Aesthetic.pause(this) + adapter.disableForegroundDispatch(this) } override fun onBackPressed() { if (drawer_layout.isDrawerOpen(GravityCompat.START)) { drawer_layout.closeDrawer(GravityCompat.START) } else { + // TODO only call on double tap super.onBackPressed() } } @@ -214,4 +188,15 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte } } + private fun initForegroundDispatch() { + intentFiltersArray = arrayOf(IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED).apply { addDataType("*/*") }) + techListsArray = arrayOf(arrayOf(NfcA::class.java.name)) + adapter = NfcAdapter.getDefaultAdapter(this) + pendingIntent = PendingIntent.getActivity( + this, 0, + Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0 + ) + + } + } diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt new file mode 100644 index 0000000..fffb014 --- /dev/null +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt @@ -0,0 +1,93 @@ +/** + * ProjectLaogai + * + * Copyright 2019 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +package org.mosad.seil0.projectlaogai.controller + +import android.content.Context +import android.content.Intent +import android.nfc.NfcAdapter +import android.nfc.Tag +import android.nfc.tech.IsoDep +import com.afollestad.materialdialogs.MaterialDialog +import com.codebutler.farebot.Utils +import com.codebutler.farebot.card.desfire.DesfireFileSettings +import com.codebutler.farebot.card.desfire.DesfireProtocol +import org.mosad.seil0.projectlaogai.R +import java.lang.Exception + +class NFCMensaCard { + + companion object { + private const val appId = 0x5F8415 + private const val fileId = 1 + + /** + * read the current balance and last payment from the mensa card + * @param intent a nfc intent + * @param context the context to show the dialog in + */ + fun readBalance(intent: Intent, context: Context) { + val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG) + val isoDep = IsoDep.get(tag) + isoDep.connect() + + val card = DesfireProtocol(isoDep) + val settings = Utils.selectAppFile(card, appId, fileId) + + if (settings is DesfireFileSettings.ValueDesfireFileSettings) { + val data = try { + card.readValue(fileId) + } catch (ex: Exception) { 0 } + + MaterialDialog(context) + .title(R.string.mensa_credit) + .message(text = lookAtMe(context, data, settings.value)) + .show() + } + } + + /** + * generate the values for current balance and last payment + * if the easter egg is active use schmeckles as currency + * 0.0000075 = 1.11 / 148 / 1000 (dollar / shm / card multiplier) + * @param context the context to access resources + * @param currentRaw the raw card value of the current balance + * @param lastRaw the raw card value of the last payment + * @return the message containing all values + */ + private fun lookAtMe(context: Context, currentRaw: Int, lastRaw: Int): String { + val current = if (!PreferencesController.oGiants) { + String.format("%.2f €", (currentRaw.toFloat() / 1000)) + } else { + String.format("%.4f shm", (currentRaw.toFloat() * 0.0000075)) + } + + val last = if (!PreferencesController.oGiants) { + String.format("%.2f €", (lastRaw.toFloat() / 1000)) + } else { + String.format("%.4f shm", (lastRaw.toFloat() * 0.0000075)) + } + + return context.resources.getString(R.string.mensa_current, current) + context.resources.getString(R.string.mensa_last, last) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt index 4901306..d6a43fa 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt @@ -42,6 +42,7 @@ class PreferencesController { var cColorAccent: Int = Color.parseColor("#3F51B5") var cCourse = Course("https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=DA64F6FE-9DDB-429E-A677-05D0D40CB636&week=0", "AI3") var cShowBuffet = true + var oGiants = false // the save function fun save(context: Context) { diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt index a244a3a..73c9dd1 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt @@ -124,6 +124,11 @@ class SettingsFragment : Fragment() { // open a new dialog } + linLayoutUser.setOnLongClickListener { + PreferencesController.oGiants = true // enable easter egg + return@setOnLongClickListener true + } + linLayoutCourse.setOnClickListener { selectCourse(context!!) txtView_Course.text = cCourse.courseName // update txtView diff --git a/app/src/main/res/layout/nav_header_main.xml b/app/src/main/res/layout/nav_header_main.xml index 087f997..67d4683 100644 --- a/app/src/main/res/layout/nav_header_main.xml +++ b/app/src/main/res/layout/nav_header_main.xml @@ -19,7 +19,7 @@ android:layout_height="wrap_content" android:paddingTop="@dimen/nav_header_vertical_spacing" app:srcCompat="@mipmap/ic_laogai_icon" - android:contentDescription="@string/nav_header_desc" + android:contentDescription="@string/app_name" android:id="@+id/imageView"/> farebot part for desfire cards https://github.com/codebutler/farebot - - GNU General Public License v3.0 + Copyright 2011-2012, 2014, 2016 Eric Butler + GNU General Public License 3.0 Android Support Libraries diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index e17ba93..64a267b 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -1,36 +1,50 @@ + Navigationsleiste schließen + Navigationsleiste öffnen + + Home Mensa Stundenplan Moodle Einstellungen + + Essen Heute, %1$s Morgen, %1$s keine Essensausgabe Diese Woche keine weitere Essensausgabe heute keine Vorlesung! - Fehler - Stundenplan konnte nicht geladen werden! + + Info Benutzer Tippen, um den Kurs zu ändern - Hauptfarbe - Die Primärfarbe, Standard ist Schwarz. - Akzentfarbe - Die Akzentfarbe, Standard ist indigo - auswählen - schließen Über - lade Stundenplan … - Navigationsleiste schließen - Navigationsleiste öffnen - Buffet immer anzeigen - Wähle deinen Studiengang aus + Lizenzen Design Hell Dunkel Schwarz - Lizenzen + Hauptfarbe + Die Primärfarbe, Standard ist Schwarz. + Akzentfarbe + Die Akzentfarbe, Standard ist indigo + Buffet immer anzeigen + + + Wähle deinen Studiengang + lade Stundenplan … + auswählen + schließen + Mensa-Guthaben + aktuell: %1$s\n + letzte Abbuchung: %1$s + + + Fehler + Stundenplan konnte nicht geladen werden! + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1cfebc4..57efb0b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4,31 +4,31 @@ Close navigation drawer Project Laogai seil0@mosad.xyz - Project Laogai + Home Mensa Timetable Moodle Settings + Meal Today, %1$s Tomorrow, %1$s the Mensa is closed No more Food this week + "No lecture today!" + Info User Tap to change course - Select your course - loading timetable … About "This software is made by @Seil0 and is published under the terms and conditions of GPL 3. For further information visit \ngit.mosad.xyz/Seil0/ProjectLaogai \n\n© 2018-2019 seil0@mosad.xyz " hso App by @Seil0 Version %1$s (%2$s) Licenses - Theme Light Dark @@ -38,18 +38,28 @@ Accent color The accent color, default is indigo. Always show buffet + + + Select your course + loading timetable … select close + Mensa credit + current: %1$s\n + last: %1$s - SampleUser@stud.hs-offenburg.de + + + spinefield@stud.hs-offenburg.de SampleCourse 3 Montag, 30.02 0.00 – 23.59 - "No lecture today!" + Error Could not load timetable!" + org.mosad.seil0.projectlaogai.course org.mosad.seil0.projectlaogai.courseTTLink org.mosad.seil0.projectlaogai.colorPrimary