Vereinfache Code mit extensions methods und verbessere Logging

master
Niko Diamadis 4 years ago
parent f9ed1af9f9
commit 42784fc4f8
Signed by: niko
GPG Key ID: BE53B0B17B1B142E

@ -1,8 +1,6 @@
package com.cyb3rko.techniklogger
import android.Manifest
import android.annotation.SuppressLint
import android.content.SharedPreferences
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
@ -17,13 +15,10 @@ class MainActivity : AppCompatActivity() {
private var _binding: ActivityMainBinding? = null
private lateinit var navController: NavController
private lateinit var sharedPref: SharedPreferences
private lateinit var sharedPrefEditor: SharedPreferences.Editor
// This property is only valid between onCreateView and onDestroyView.
private val binding get() = _binding!!
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// This property is only valid between onCreateView and onDestroyView.
@ -39,12 +34,8 @@ class MainActivity : AppCompatActivity() {
)
setupActionBarWithNavController(navController, appBarConfiguration)
sharedPref = getSharedPreferences("Safe", 0)
sharedPrefEditor = sharedPref.edit()
sharedPrefEditor.apply()
if (sharedPref.getString("name", "") == "") {
showNameDialog(this, sharedPref, sharedPrefEditor, false)
if (Safe.getKey(applicationContext, NAME) == "") {
showNameDialog(this, false)
} else {
if (!BuildConfig.DEBUG) {
Updater.updateCheck(this@MainActivity)

@ -0,0 +1,44 @@
package com.cyb3rko.techniklogger
import android.content.Context
import android.content.Context.MODE_PRIVATE
internal object Safe {
private const val SHARED_PREFERENCE = "Safe"
internal fun storeBoolean(
context: Context,
label: String,
content: Boolean
) {
context.getSharedPreferences(SHARED_PREFERENCE, MODE_PRIVATE)
.edit()
.putBoolean(label, content)
.apply()
}
internal fun storeKey(
context: Context,
label: String,
content: String?
) {
context.getSharedPreferences(SHARED_PREFERENCE, MODE_PRIVATE)
.edit()
.putString(label, content)
.apply()
}
internal fun getBoolean(context: Context, label: String): Boolean {
return context.getSharedPreferences(SHARED_PREFERENCE, MODE_PRIVATE)
.getBoolean(label, false)
}
internal fun getKey(
context: Context,
label: String,
defaultValue: String = ""
): String {
return context.getSharedPreferences(SHARED_PREFERENCE, MODE_PRIVATE)
.getString(label, defaultValue)!!
}
}

@ -2,32 +2,110 @@ package com.cyb3rko.techniklogger
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.util.Log
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import es.dmoral.toasty.Toasty
internal const val COLUMN_TECHNIKER_ADMIN = "admin"
internal const val COLUMN_TECHNIKER_NAME = "name"
internal const val ADMIN = "admin"
internal const val CURRENT_YEAR = "current_year"
internal const val CURRENT_YEAR_NAME = "current_year_name"
internal const val LOG_APP_ID = "Technik-Logger"
internal const val NAME = "name"
internal const val TECHNIKER_ID = "technikerId"
internal const val SHARED_PREFERENCE = "Safe"
//// Extension functions
// For Context class
internal fun Context.showSuccessToast(message: String, length: Int = Toasty.LENGTH_SHORT) {
Toasty.success(this, message, length).show()
}
internal fun Context.showWarningToast(message: String, length: Int = Toasty.LENGTH_LONG) {
Toasty.warning(this, message, length).show()
}
internal fun Context.showErrorToast(message: String, length: Int = Toasty.LENGTH_LONG) {
Toasty.error(this, message, length).show()
}
// For Activity class
internal fun Activity.hideKeyboard() {
hideKeyboardWithActivity(this)
}
// For Fragment class
internal fun Fragment.showSuccessToast(message: String, length: Int = Toasty.LENGTH_SHORT) {
this.requireContext().showSuccessToast(message, length)
}
internal fun Fragment.showWarningToast(message: String, length: Int = Toasty.LENGTH_LONG) {
this.requireContext().showWarningToast(message, length)
}
internal fun Fragment.showErrorToast(message: String, length: Int = Toasty.LENGTH_LONG) {
this.requireContext().showErrorToast(message, length)
}
internal fun Fragment.hideKeyboard() {
hideKeyboardWithActivity(this.requireActivity())
}
// For View class
internal fun View.hide() {
this.visibility = View.INVISIBLE
}
internal fun View.show() {
this.visibility = View.VISIBLE
}
// For Float class
internal fun Float.toPrettyString(): String {
val string = this.toString()
return if (!string.endsWith(".0")) {
string
} else {
string.dropLast(2)
}
}
//// Other functions
internal fun logD(message: String) = Log.d(LOG_APP_ID, message)
internal fun logE(message: String) = Log.e(LOG_APP_ID, message)
private fun hideKeyboardWithActivity(activity: Activity) {
val imm = activity.getSystemService(
AppCompatActivity.INPUT_METHOD_SERVICE
) as InputMethodManager
var view = activity.currentFocus
if (view == null) {
view = View(activity)
}
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
@SuppressLint("CheckResult")
internal fun showNameDialog(
activity: MainActivity,
sharedPref: SharedPreferences,
sharedPrefEditor: SharedPreferences.Editor,
cancelable: Boolean
) {
val currentName = sharedPref.getString(COLUMN_TECHNIKER_NAME, "")
val currentName = Safe.getKey(activity, NAME)
@SuppressLint("InflateParams")
val inputField = activity.layoutInflater
@ -48,7 +126,7 @@ internal fun showNameDialog(
.create().apply {
setOnShowListener {
getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
closeKeyboard(activity)
activity.hideKeyboard()
val inputName = inputTextField.text.toString()
try {
if (!inputName[0].isUpperCase()) {
@ -58,7 +136,7 @@ internal fun showNameDialog(
}
if (inputName != currentName) {
sharedPrefEditor.putString("name", inputName.trim()).commit()
Safe.storeKey(activity, NAME, inputName.trim())
activity.finish()
activity.startActivity(Intent(activity, MainActivity::class.java))
} else {
@ -69,23 +147,3 @@ internal fun showNameDialog(
show()
}
}
private fun closeKeyboard(activity: Activity) {
val imm = activity.getSystemService(
AppCompatActivity.INPUT_METHOD_SERVICE
) as InputMethodManager
var view = activity.currentFocus
if (view == null) {
view = View(activity)
}
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
internal fun Float.toPrettyString(): String {
val string = this.toString()
return if (!string.endsWith(".0")) {
string
} else {
string.dropLast(2)
}
}

@ -3,13 +3,11 @@ package com.cyb3rko.techniklogger.fragments
import android.animation.Animator
import android.app.ActivityManager
import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.Html
import android.util.Log
import android.view.*
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
@ -32,8 +30,6 @@ class ListingFragment : Fragment() {
private var adminMode: Boolean? = null
private lateinit var missionAdapter: MissionAdapter
private var isFABOpen = false
private lateinit var sharedPref: SharedPreferences
private lateinit var sharedPrefEditor: SharedPreferences.Editor
// This property is only valid between onCreateView and onDestroyView.
private val binding get() = _binding!!
@ -44,9 +40,7 @@ class ListingFragment : Fragment() {
val root = binding.root
myContext = requireContext()
sharedPref = myContext.getSharedPreferences("Safe", 0)
sharedPrefEditor = sharedPref.edit()
if (sharedPref.getString(CURRENT_YEAR, "") == "") {
if (Safe.getKey(myContext, CURRENT_YEAR) == "") {
findNavController().navigate(R.id.navigation_years)
}
@ -100,7 +94,7 @@ class ListingFragment : Fragment() {
myContext,
missionAdapter.currentList,
binding,
sharedPref.getString("current_year_name", "")!!
Safe.getKey(myContext, CURRENT_YEAR_NAME)
)
}
@ -113,10 +107,10 @@ class ListingFragment : Fragment() {
closeFABMenu()
}
if (adminMode == null && sharedPref.getString("name", "") != "") {
if (adminMode == null && Safe.getKey(myContext, NAME) != "") {
updateAdminStatus()
} else if (adminMode != null && adminMode!!) {
binding.fabContainer.visibility = View.VISIBLE
binding.fabContainer.show()
}
return root
@ -125,7 +119,7 @@ class ListingFragment : Fragment() {
override fun onStart() {
super.onStart()
updateActionBarNumber()
val actionBarTitle = "Einsätze ${sharedPref.getString(CURRENT_YEAR_NAME, "")}"
val actionBarTitle = "Einsätze ${Safe.getKey(myContext, CURRENT_YEAR_NAME)}"
(requireActivity() as MainActivity).setActionBarTitle(actionBarTitle)
}
@ -145,7 +139,7 @@ class ListingFragment : Fragment() {
}
private fun loadEntries() {
ParseController.fetchMissions(sharedPref.getString(CURRENT_YEAR, "")!!) { missions, e ->
ParseController.fetchMissions(Safe.getKey(myContext, CURRENT_YEAR)) { missions, e ->
if (e == null) {
showAnimation(false)
binding.swipeRefreshLayout.isRefreshing = false
@ -164,11 +158,11 @@ class ListingFragment : Fragment() {
if (missionAdapter.currentList.isEmpty()) {
showAnimation(true, false)
}
Toasty.error(myContext, "Abruf fehlgeschlagen", Toasty.LENGTH_SHORT).show()
Log.e("TechnikLogger.EinsSuche", e.message.toString())
showErrorToast("Abruf fehlgeschlagen")
logE("Abruf der Einsätze fehlgeschlagen")
e.printStackTrace()
} else {
Log.d("TechnikLogger.EinsSuche", "Empty cache, fetching data immediately.")
logD("Leerer Cache, rufe Daten direkt ab.")
}
}
}
@ -177,25 +171,26 @@ class ListingFragment : Fragment() {
}
private fun updateAdminStatus() {
ParseController.fetchAdminStatus(sharedPref.getString("name", "")) { objectId, admin, e ->
ParseController.fetchAdminStatus(Safe.getKey(myContext, NAME)) { objectId, admin, e ->
if (e == null) {
if (admin!!) {
adminMode = true
sharedPrefEditor.putBoolean("admin", adminMode!!)
binding.fabContainer.visibility = View.VISIBLE
Safe.storeBoolean(myContext, ADMIN, adminMode!!)
binding.fabContainer.show()
} else {
adminMode = false
sharedPrefEditor.putBoolean("admin", adminMode!!)
binding.fabContainer.visibility = View.INVISIBLE
Safe.storeBoolean(myContext, ADMIN, adminMode!!)
binding.fabContainer.hide()
}
sharedPrefEditor.putString("technikerId", objectId).apply()
Safe.storeKey(myContext, TECHNIKER_ID, objectId)
} else {
binding.fabContainer.visibility = View.INVISIBLE
binding.fabContainer.hide()
adminMode = false
sharedPrefEditor.putString("technikerId", "")
sharedPrefEditor.putBoolean("admin", adminMode!!).apply()
Toasty.error(myContext, "Adminstatus unbekannt", Toasty.LENGTH_SHORT).show()
Log.e("TechnikLogger.TechSuche", e.message.toString())
Safe.storeKey(myContext, TECHNIKER_ID, "")
Safe.storeBoolean(myContext, ADMIN, adminMode!!)
showErrorToast("Adminstatus unbekannt", Toasty.LENGTH_SHORT)
logE("Adminstatus unbekannt")
e.printStackTrace()
}
}
}
@ -216,10 +211,10 @@ class ListingFragment : Fragment() {
private fun showFABMenu() {
isFABOpen = true
binding.fabLayout1.visibility = View.VISIBLE
binding.fabLayout2.visibility = View.VISIBLE
binding.fabLayout3.visibility = View.VISIBLE
binding.fabBgLayout.visibility = View.VISIBLE
binding.fabLayout1.show()
binding.fabLayout2.show()
binding.fabLayout3.show()
binding.fabBgLayout.show()
binding.fab.animate().rotationBy(180f)
binding.fabLayout1.animate().translationY(-resources.getDimension(R.dimen.first_fab))
binding.fabLayout2.animate().translationY(-resources.getDimension(R.dimen.second_fab))
@ -228,7 +223,7 @@ class ListingFragment : Fragment() {
private fun closeFABMenu() {
isFABOpen = false
binding.fabBgLayout.visibility = View.GONE
binding.fabBgLayout.hide()
binding.fab.animate().rotation(0f)
binding.fabLayout1.animate().translationY(0f)
binding.fabLayout2.animate().translationY(0f)
@ -238,9 +233,9 @@ class ListingFragment : Fragment() {
override fun onAnimationEnd(animation: Animator) {
if (!isFABOpen) {
binding.fabLayout1.visibility = View.GONE
binding.fabLayout2.visibility = View.GONE
binding.fabLayout3.visibility = View.GONE
binding.fabLayout1.hide()
binding.fabLayout2.hide()
binding.fabLayout3.hide()
}
}
@ -260,7 +255,7 @@ class ListingFragment : Fragment() {
// as you specify a parent activity in AndroidManifest.xml.
when (item.itemId) {
R.id.action_year -> findNavController().navigate(R.id.navigation_years)
R.id.action_rename -> showNameDialog(requireActivity() as MainActivity, sharedPref, sharedPrefEditor, true)
R.id.action_rename -> showNameDialog(requireActivity() as MainActivity, true)
R.id.action_info -> {
var info = "App-Version: ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})"
info += "\nBuild-Typ: ${BuildConfig.BUILD_TYPE}"

@ -2,7 +2,6 @@ package com.cyb3rko.techniklogger.fragments
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -17,9 +16,11 @@ import com.cyb3rko.techniklogger.R
import com.cyb3rko.techniklogger.data.objects.Member
import com.cyb3rko.techniklogger.data.ParseController
import com.cyb3rko.techniklogger.databinding.FragmentManageMembersBinding
import com.cyb3rko.techniklogger.logE
import com.cyb3rko.techniklogger.showErrorToast
import com.cyb3rko.techniklogger.showSuccessToast
import com.google.android.material.switchmaterial.SwitchMaterial
import com.google.android.material.textfield.TextInputEditText
import es.dmoral.toasty.Toasty
class ManageMembersFragment : Fragment() {
private var _binding: FragmentManageMembersBinding? = null
@ -54,12 +55,13 @@ class ManageMembersFragment : Fragment() {
setName(newName)
saveInBackground {
if (it == null) {
Toasty.success(myContext, "Hinzugefügt").show()
showSuccessToast("Hinzugefügt")
showAnimation(true)
loadMembers()
} else {
Toasty.error(myContext, "Fehler bei Speicherung").show()
Log.e("TechnikLogger.Techniker", it.message.toString())
showErrorToast("Fehler beim Hinzufügen")
logE("Fehler beim Hinzufügen des Technikers")
it.printStackTrace()
}
}
}
@ -119,14 +121,15 @@ class ManageMembersFragment : Fragment() {
setName(newName)
saveInBackground {
if (it == null) {
Toasty.success(myContext, "Gespeichert").show()
showSuccessToast("Gespeichert")
if (nameChanged) {
showAnimation(true)
loadMembers()
}
} else {
Toasty.error(myContext, "Fehler bei Speicherung").show()
Log.e("TechnikLogger.Techniker", it.message.toString())
showErrorToast("Fehler bei der Speicherung")
logE("Fehler bei der Speicherung des neuen Technikers")
it.printStackTrace()
}
}
}
@ -142,12 +145,13 @@ class ManageMembersFragment : Fragment() {
retire()
saveInBackground {
if (it == null) {
Toasty.success(myContext, "Gespeichert").show()
showSuccessToast("Techniker entlassen")
showAnimation(true)
loadMembers()
} else {
Toasty.error(myContext, "Fehler bei Speicherung").show()
Log.e("TechnikLogger.Techniker", it.message.toString())
showErrorToast("Fehler bei der Entlassung")
logE("Fehler bei der Entlassung des Technikers")
it.printStackTrace()
}
}
}
@ -159,8 +163,9 @@ class ManageMembersFragment : Fragment() {
}
} else {
showAnimation(true, false)
Toasty.error(myContext, "Abruf fehlgeschlagen", Toasty.LENGTH_SHORT).show()
Log.e("TechnikLogger.TechVerw", e.message.toString())
showErrorToast("Abruf fehlgeschlagen")
logE("Abruf der Techniker fehlgeschlagen")
e.printStackTrace()
}
}
}

@ -2,10 +2,8 @@ package com.cyb3rko.techniklogger.fragments
import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.text.Html
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -27,12 +25,10 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.TimeFormat
import com.parse.ParseObject
import es.dmoral.toasty.Toasty
import java.sql.Time
import java.text.SimpleDateFormat
import java.util.*
@SuppressLint("SetTextI18n")
class MissionFragment : Fragment() {
private var _binding: FragmentMissionBinding? = null
private lateinit var myContext: Context
@ -45,7 +41,6 @@ class MissionFragment : Fragment() {
private var time = ""
private lateinit var participationAdapter: ParticipationAdapter
private var adminMode = false
private lateinit var sharedPref: SharedPreferences
private val binding get() = _binding!!
@ -58,26 +53,25 @@ class MissionFragment : Fragment() {
val root = binding.root
myContext = requireContext()
sharedPref = myContext.getSharedPreferences(SHARED_PREFERENCE, 0)
adminMode = sharedPref.getBoolean(COLUMN_TECHNIKER_ADMIN, false)
adminMode = Safe.getBoolean(myContext, ADMIN)
objectId = args.objectId
loadData()
binding.addButton.setOnClickListener {
val name = sharedPref.getString(NAME, "invalid")!!
val name = Safe.getKey(myContext, NAME, "invalid")
if (!adminMode) selfAdd(name) else bothAdd(name)
}
emptyCheck()
if (adminMode || sharedPref.getString(TECHNIKER_ID, "")!!.isNotBlank()) {
binding.addButton.visibility = View.VISIBLE
if (adminMode || Safe.getKey(myContext, TECHNIKER_ID).isNotBlank()) {
binding.addButton.show()
}
if (adminMode) {
binding.resetButton.visibility = View.VISIBLE
binding.resetButton.show()
binding.resetButton.setOnClickListener {
MaterialAlertDialogBuilder(myContext)
.setTitle("Techniker entfernen")
@ -91,8 +85,9 @@ class MissionFragment : Fragment() {
showDivider(false)
updateTechnikerCount(0)
} else {
Toasty.error(myContext, "Fehler bei Techniker-Abfrage", Toasty.LENGTH_SHORT).show()
Log.e("TechnikLogger.TechSuche", e.message.toString())
showErrorToast("Abfrage der Techniker fehlgeschlagen")
logE("Abfrage der Techniker fehlgeschlagen")
e.printStackTrace()
}
}
}
@ -139,10 +134,11 @@ class MissionFragment : Fragment() {
} else {
if (e.message != null) {
if (e.message != "results not cached") {
Toasty.error(myContext, "Fehler bei Einsatz-Suche").show()
Log.e("TechnikLogger.EinsSuche", e.message.toString())
showErrorToast("Abfrage fehlgeschlagen")
logE("Abfrage der Einsatz-Informationen fehlgeschlagen")
e.printStackTrace()
} else {
Log.d("TechnikLogger.EinsSuche", "Empty cache, fetching data immediately.")
logD("Leerer Cache, rufe Daten direkt ab.")
}
}
}
@ -151,8 +147,8 @@ class MissionFragment : Fragment() {
}
private fun loadParticipations() {
ParseController.fetchParticipations(objectId, true) { participations, e2 ->
if (e2 == null) {
ParseController.fetchParticipations(objectId, true) { participations, e ->
if (e == null) {
if (participations.isNotEmpty()) {
participations.forEach {
if (it.duration == 0f) it.setDuration(duration)
@ -165,8 +161,9 @@ class MissionFragment : Fragment() {
showDivider()
}
} else {
Toasty.error(myContext, "Fehler bei Teilnehmer-Abfrage").show()
Log.e("TechnikLogger.TechSuche", e2.message.toString())
showErrorToast("Abfrage der Techniker fehlgeschlagen")
logE("Abfrage der Techniker fehlgeschlagen")
e.printStackTrace()
}
}
}
@ -178,7 +175,7 @@ class MissionFragment : Fragment() {
return
}
participationAdapter = ParticipationAdapter(duration) {
if (adminMode || it.name == sharedPref.getString(NAME, "")) {
if (adminMode || it.name == Safe.getKey(myContext, NAME)) {
val uhrzeit = if (it.time == "0") {
time
} else {
@ -223,9 +220,9 @@ class MissionFragment : Fragment() {
val testHour = testTime.split(":")[0]
val testMinutes = testTime.split(":")[1]
if (testHour > hour) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
showWarningToast("Zeitpunkt nicht im Zeitraum des Einsatzes")
} else if (testHour == hour && testMinutes > minute) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
showWarningToast("Zeitpunkt nicht im Zeitraum des Einsatzes")
} else {
tempTime += "${hour}:${minute} - "
activity?.let { it1 -> picker2.show(it1.supportFragmentManager, picker2.tag) }
@ -243,10 +240,10 @@ class MissionFragment : Fragment() {
val testHour = testTime.split(":")[0]
val testMinutes = testTime.split(":")[1]
if (testHour < hour) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
showWarningToast("Zeitpunkt nicht im Zeitraum des Einsatzes")
return@addOnPositiveButtonClickListener
} else if (testHour == hour && testMinutes < minute) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
showWarningToast("Zeitpunkt nicht im Zeitraum des Einsatzes")
return@addOnPositiveButtonClickListener
}
tempTime += "${hour}:${minute}"
@ -259,11 +256,12 @@ class MissionFragment : Fragment() {
setTime(it.time)
saveInBackground {
if (it == null) {
Toasty.success(myContext, "Arbeitszeit geändert").show()
showSuccessToast("Arbeitszeit geändert")
loadParticipations()
} else {
Toasty.error(myContext, "Fehler bei Speicherung").show()
Log.e("TechnikLogger.TechEdit", it.message.toString())
showErrorToast("Ändern der Arbeitszeit fehlgeschlagen")
logE("Ändern der Arbeitszeit fehlgeschlagen")
it.printStackTrace()
}
}
}
@ -315,16 +313,17 @@ class MissionFragment : Fragment() {
private fun selfAdd(name: String, skip: Boolean = false) {
if (!memberExists(name)) {
val ownMemberId = Safe.getKey(myContext, TECHNIKER_ID)
if (!skip) {
MaterialAlertDialogBuilder(myContext)
.setMessage("Möchtest du dich als involvierter Techniker eintragen?")
.setPositiveButton("Ja") { _, _ ->
addTechniker(listOf(sharedPref.getString(TECHNIKER_ID, "")!!))
addTechniker(listOf(ownMemberId))
}
.setNegativeButton("Abbrechen", null)
.show()
} else {
addTechniker(listOf(sharedPref.getString(TECHNIKER_ID, "")!!))
addTechniker(listOf(ownMemberId))
}
} else {
MaterialAlertDialogBuilder(myContext)
@ -383,8 +382,9 @@ class MissionFragment : Fragment() {
}
.show()
} else {
Toasty.error(myContext, "Fehler bei Techniker-Suche").show()
Log.e("TechnikLogger.TechSuche", e.message.toString())
showErrorToast("Abfrage der Techniker fehlgeschlagen")
logE("Abfrage der Techniker fehlgeschlagen")
e.printStackTrace()
}
}
}
@ -405,12 +405,14 @@ class MissionFragment : Fragment() {
if (it == null) {
loadData()
} else {
Toasty.error(myContext, "Fehler bei Techniker-Suche").show()
Log.e("TechnikLogger.TechSuche", it.message.toString())
showErrorToast("Speichern fehlgeschlagen")
logE("Speichern des Technikers fehlgeschlagen")
it.printStackTrace()
}
}
}
@SuppressLint("SetTextI18n")
private fun updateTechnikerCount(counter: Int) {
binding.technikerView.text = "Techniker: $counter"
}
@ -421,7 +423,7 @@ class MissionFragment : Fragment() {
private fun emptyCheck() {
if (isRecyclerViewInitialized() && participationAdapter.currentList.isEmpty()) {
binding.divider.visibility = View.GONE
binding.divider.hide()
}
}
}

@ -5,7 +5,6 @@ import android.content.Context
import android.os.Bundle
import android.text.Html
import android.text.SpannableStringBuilder
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -14,7 +13,6 @@ import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.cyb3rko.techniklogger.*
import com.cyb3rko.techniklogger.CURRENT_YEAR
import com.cyb3rko.techniklogger.SHARED_PREFERENCE
import com.cyb3rko.techniklogger.data.objects.Mission
import com.cyb3rko.techniklogger.data.ParseController
import com.cyb3rko.techniklogger.databinding.FragmentMissionPusherBinding
@ -23,7 +21,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.TimeFormat
import com.parse.ParseObject
import es.dmoral.toasty.Toasty
import java.sql.Time
import java.text.SimpleDateFormat
import java.util.*
@ -122,7 +119,7 @@ class MissionPusherFragment : Fragment() {
}
if (childKey != "") {
binding.deleteButton.visibility = View.VISIBLE
binding.deleteButton.show()
binding.deleteButton.setOnClickListener {
MaterialAlertDialogBuilder(myContext)
.setTitle("Einsatz entfernen")
@ -135,14 +132,16 @@ class MissionPusherFragment : Fragment() {
if (it == null) {
findNavController().navigate(R.id.navigation_listing)
} else {
Toasty.error(myContext, "Fehler bei Einsatz-Löschung").show()
Log.e("TechnikLogger.Einsätze", it.message.toString())
showErrorToast("Löschen des Einsatzes fehlgeschlagen")
logE("Löschen des Einsatzes fehlgeschlagen")
it.printStackTrace()
}
}
}
} else {
Toasty.error(myContext, "Fehler bei Teilnehmer-Löschung").show()
Log.e("TechnikLogger.Einsätze", e.message.toString())
showErrorToast("Löschen der Techniker fehlgeschlagen")
logE("Löschen der Techniker fehlgeschlagen")
e.printStackTrace()
}
}
}
@ -163,21 +162,18 @@ class MissionPusherFragment : Fragment() {
if (time != "") dateTime += ",$time"
mission.setDate(dateTime)
mission.setDuration(duration)
val sharedPref = context?.getSharedPreferences(
SHARED_PREFERENCE,
Context.MODE_PRIVATE
)
mission.setYear(sharedPref?.getString(CURRENT_YEAR, "")!!)
mission.setYear(Safe.getKey(myContext, CURRENT_YEAR))
mission.saveInBackground {
if (it == null) {
findNavController().navigate(R.id.navigation_listing)
} else {
Toasty.error(myContext, "Fehler bei Einsatz-Speicherung").show()
Log.e("TechnikLogger.Einsätze", it.message.toString())
showErrorToast("Speichern des Einsatzes fehlgeschlagen")
logE("Speichern des Einsatzes fehlgeschlagen")
it.printStackTrace()
}
}
} else {
Toasty.error(myContext, "Fülle zuerst alle Felder aus").show()
showWarningToast("Fülle zuerst alle Felder aus")
}
}

@ -1,9 +1,7 @@
package com.cyb3rko.techniklogger.fragments
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -13,7 +11,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.cyb3rko.techniklogger.*
import com.cyb3rko.techniklogger.CURRENT_YEAR
import com.cyb3rko.techniklogger.CURRENT_YEAR_NAME
import com.cyb3rko.techniklogger.SHARED_PREFERENCE
import com.cyb3rko.techniklogger.data.ParseController
import com.cyb3rko.techniklogger.data.objects.Year
import com.cyb3rko.techniklogger.databinding.FragmentYearsBinding
@ -29,8 +26,6 @@ class YearsFragment : Fragment() {
private var adminMode: Boolean? = null
private lateinit var yearAdapter: YearAdapter
private var data: List<Year> = mutableListOf()
private lateinit var sharedPref: SharedPreferences
private lateinit var sharedPrefEditor: SharedPreferences.Editor
// This property is only valid between onCreateView and onDestroyView.
private val binding get() = _binding!!
@ -49,14 +44,11 @@ class YearsFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
sharedPref = myContext.getSharedPreferences(SHARED_PREFERENCE, Context.MODE_PRIVATE)
sharedPrefEditor = sharedPref.edit()
binding.loadingAnimation.playAnimation()
yearAdapter = YearAdapter { year ->
sharedPrefEditor.putString(CURRENT_YEAR, year.objectId)
sharedPrefEditor.putString(CURRENT_YEAR_NAME, year.name).commit()
Safe.storeKey(myContext, CURRENT_YEAR, year.objectId)
Safe.storeKey(myContext, CURRENT_YEAR_NAME, year.name)
findNavController().navigate(R.id.navigation_listing)
}
binding.recyclerView.apply {
@ -91,10 +83,10 @@ class YearsFragment : Fragment() {
.show()
}
if (adminMode == null && sharedPref.getString("name", "") != "") {
if (adminMode == null && Safe.getKey(myContext, NAME) != "") {
updateAdminStatus()
} else if (adminMode != null && adminMode!!) {
binding.fab.visibility = View.VISIBLE
binding.fab.show()
}
}
@ -113,11 +105,11 @@ class YearsFragment : Fragment() {
if (data.isEmpty()) {
showAnimation(true, false)
}
Toasty.error(myContext, "Abruf fehlgeschlagen", Toasty.LENGTH_SHORT).show()
Log.e("TechnikLogger.JahrSuche", e.message.toString())
showErrorToast("Abruf fehlgeschlagen")
logE("Abruf der Schuljahre fehlgeschlagen")
e.printStackTrace()
} else {
Log.d("TechnikLogger.EinsSuche", "Empty cache, fetching data immediately.")
logD("Leerer Cache, rufe Daten direkt ab.")
}
}
}
@ -125,25 +117,26 @@ class YearsFragment : Fragment() {
}
private fun updateAdminStatus() {
ParseController.fetchAdminStatus(sharedPref.getString("name", "")) { objectId, admin, e ->
ParseController.fetchAdminStatus(Safe.getKey(myContext, NAME)) { objectId, admin, e ->
if (e == null) {
if (admin!!) {
adminMode = true
sharedPrefEditor.putBoolean("admin", adminMode!!)
binding.fab.visibility = View.VISIBLE
Safe.storeBoolean(myContext, ADMIN, adminMode!!)
binding.fab.show()
} else {
adminMode = false
sharedPrefEditor.putBoolean("admin", adminMode!!)
binding.fab.visibility = View.INVISIBLE
Safe.storeBoolean(myContext, ADMIN, adminMode!!)
binding.fab.hide()
}
sharedPrefEditor.putString("technikerId", objectId).apply()
Safe.storeKey(myContext, TECHNIKER_ID, objectId)
} else {
binding.fab.visibility = View.INVISIBLE
binding.fab.hide()
adminMode = false
sharedPrefEditor.putString("technikerId", "")
sharedPrefEditor.putBoolean("admin", adminMode!!).apply()
Toasty.error(myContext, "Adminstatus unbekannt", Toasty.LENGTH_SHORT).show()
Log.e("TechnikLogger.TechSuche", e.message.toString())
Safe.storeKey(myContext, TECHNIKER_ID, "")
Safe.storeBoolean(myContext, ADMIN, adminMode!!)
showErrorToast("Adminstatus unbekannt", Toasty.LENGTH_SHORT)
logE("Adminstatus unbekannt")
e.printStackTrace()
}
}
}

@ -4,20 +4,22 @@ import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.util.Base64
import android.util.Log
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.androidnetworking.AndroidNetworking
import com.androidnetworking.error.ANError
import com.androidnetworking.interfaces.StringRequestListener
import com.cyb3rko.techniklogger.BuildConfig
import com.cyb3rko.techniklogger.MainActivity
import com.cyb3rko.techniklogger.*
import com.cyb3rko.techniklogger.logD
import com.cyb3rko.techniklogger.logE
import com.cyb3rko.techniklogger.showErrorToast
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import es.dmoral.toasty.Toasty
import java.nio.charset.StandardCharsets
internal object Updater {
internal fun updateCheck(activity: MainActivity) {
logD("Frage App-Update an")
AndroidNetworking.initialize(activity)
AndroidNetworking.get("https://git.aldiserver.de/api/v1/repos/niko/technik-logger-app/contents/app/build.gradle")
.addHeaders("Authorization", "token d70a26aa455b25e60885ba5ff31cce231d454f82")
@ -38,22 +40,26 @@ internal object Updater {
val newestVersion = parts2[0]
if (BuildConfig.VERSION_CODE != neuesterVersionCode) {
Log.d("Technik-Logger Updater", "Update verfügbar: $newestVersion")
logD("App-Update verfügbar: $newestVersion")
showDownloadDialog(activity, newestVersion)
ActivityCompat.requestPermissions(
activity, arrayOf(Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE), 1
)
} else {
Log.d(activity.toString(), "App auf dem neuesten Stand")
logD("Kein App-Update verfügbar, App ist auf dem neuesten Stand")
}
} catch (e: Exception) {
Toasty.error(activity, "Update-Check fehlgeschlagen", Toasty.LENGTH_LONG).show()
activity.showErrorToast("Update-Check fehlgeschlagen", Toasty.LENGTH_SHORT)
logE("Update-Check fehlgeschlagen")
e.printStackTrace()
}
}
override fun onError(anError: ANError?) {
Log.d(activity.toString(), "Update-Abfrage fehlgeschlagen: ${anError!!.errorBody.trimIndent()}")
activity.showErrorToast("Update-Check fehlgeschlagen", Toasty.LENGTH_SHORT)
logE("Update-Check fehlgeschlagen")
anError?.printStackTrace()
}
})
}
@ -73,7 +79,7 @@ internal object Updater {
val link = "https://cdn.cyb3rko.de/Apps/Technik-Logger/Technik-Logger%20v$newestVersion.apk"
DownloadApk(context).startDownloadingApk(link, "Technik-Logger $newestVersion")
} else {
Toasty.error(context, "Fehlende Berechtigung, erteile diese beim nächsten App-Start", Toasty.LENGTH_LONG).show()
context.showErrorToast("Fehlende Berechtigung, erteile diese beim nächsten App-Start")
}
}
}

Loading…
Cancel
Save