From 2fb0506db9d62ef3ab8e60380853a8496c9b1cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20D=C3=BCzg=C3=B6ren?= Date: Tue, 30 Jul 2019 11:18:01 +0200 Subject: [PATCH] "Last updated" time is now compared to a string embedded in the HTML instead of the "Last-Updated" header field to prevent duplicate notifications when the food menu refreshes --- .../denizd/substitutionplan/ColourAdapter.kt | 3 +- .../denizd/substitutionplan/DataFetcher.kt | 183 +++++++++--------- .../substitutionplan/NotificationService.kt | 24 +-- .../substitutionplan/SettingsFragment.kt | 6 +- 4 files changed, 110 insertions(+), 106 deletions(-) diff --git a/app/src/main/java/com/denizd/substitutionplan/ColourAdapter.kt b/app/src/main/java/com/denizd/substitutionplan/ColourAdapter.kt index e735ba5..bc956b3 100644 --- a/app/src/main/java/com/denizd/substitutionplan/ColourAdapter.kt +++ b/app/src/main/java/com/denizd/substitutionplan/ColourAdapter.kt @@ -33,7 +33,6 @@ class ColourAdapter(private var mColours: List, onClickListener: OnClick override fun onBindViewHolder(holder: ColourViewHolder, position: Int) { val currentItem = mColours[position] - val prefs = PreferenceManager.getDefaultSharedPreferences(holder.image.context) holder.title.text = currentItem.title holder.titleNoLang.text = currentItem.titleNoLang @@ -54,6 +53,6 @@ class ColourAdapter(private var mColours: List, onClickListener: OnClick } public interface OnClickListener { - fun onClick(position: Int, title: String, titleNolang: String) + fun onClick(position: Int, title: String, titleNoLang: String) } } \ No newline at end of file diff --git a/app/src/main/java/com/denizd/substitutionplan/DataFetcher.kt b/app/src/main/java/com/denizd/substitutionplan/DataFetcher.kt index 27f45b4..5694ce4 100644 --- a/app/src/main/java/com/denizd/substitutionplan/DataFetcher.kt +++ b/app/src/main/java/com/denizd/substitutionplan/DataFetcher.kt @@ -49,12 +49,9 @@ class DataFetcher(isplan: Boolean, ismenu: Boolean, isjobservice: Boolean, conte private val edit = prefs.edit() private lateinit var pullToRefresh: SwipeRefreshLayout private lateinit var progressBar: ProgressBar - private val oldDateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz" - private val newDateFormat = "yyyy-MM-dd, HH:mm:ss" - private var sdf = SimpleDateFormat(oldDateFormat) - private lateinit var d: Date private val fadeOut = AnimationUtils.loadAnimation(mContext, R.anim.fade_out) private val handler = Handler(Looper.getMainLooper()) + var currentTime = "" override fun doInBackground(vararg params: Void?): Void? { try { @@ -142,111 +139,120 @@ class DataFetcher(isplan: Boolean, ismenu: Boolean, isjobservice: Boolean, conte if (plan) { val substViewModel = SubstViewModel(mApplication) val doc = Jsoup.connect("https://djd4rkn355.github.io/subst_test").get() - val connection = URL("https://djd4rkn355.github.io/subst").openConnection() - edit.putString("time", connection.getHeaderField("Last-Modified")).apply() - d = sdf.parse(connection.getHeaderField("Last-Modified")) - val rows = doc.select("tr") - val paragraphs = doc.select("p") + currentTime = doc.select("h1").text() + if (currentTime != prefs.getString("time", "")) { + val rows = doc.select("tr") + val paragraphs = doc.select("p") - val groupS = ArrayList() - val dateS = ArrayList() - val timeS = ArrayList() - val courseS = ArrayList() - val roomS = ArrayList() - val additionalS = ArrayList() + val groupS = ArrayList() + val dateS = ArrayList() + val timeS = ArrayList() + val courseS = ArrayList() + val roomS = ArrayList() + val additionalS = ArrayList() - mView?.let { - progressBar.max = rows.size - } - - for (i in 0 until paragraphs.size) { - if (i == 0) { - informational = paragraphs[i].text() - } else { - informational += "\n\n" + paragraphs[i].text() + mView?.let { + progressBar.max = rows.size } - } - edit.putString("informational", informational).apply() - substViewModel.deleteAllSubst() - - for (i in 0 until rows.size) { - val row = rows[i] - val cols = row.select("th") as Elements - - groupS.add(cols[0].text()) - dateS.add(cols[1].text()) - timeS.add(cols[2].text()) - courseS.add(cols[3].text()) - roomS.add(cols[4].text()) - additionalS.add(cols[5].text()) - if (!jobservice) { - mView?.let { - progressBar.incrementProgressBy(1) + for (i in 0 until paragraphs.size) { + if (i == 0) { + informational = paragraphs[i].text() + } else { + informational += "\n\n" + paragraphs[i].text() } } + edit.putString("informational", informational).apply() - val drawable = MiscData.getIcon(courseS[i]) - val subst = Subst(drawable, groupS[i], dateS[i], timeS[i], courseS[i], - roomS[i], additionalS[i], priority) - priority-- - substViewModel.insertSubst(subst) + substViewModel.deleteAllSubst() - if (jobservice) { - if ((prefs.getString("courses", "") ?: "").isEmpty() && (prefs.getString("classes", "") ?: "").isNotEmpty()) { - if (groupS[i].isNotEmpty() && groupS[i] != "") { - if ((prefs.getString("classes", "") ?: "").contains(groupS[i]) || groupS[i].contains((prefs.getString("classes", "") ?: "").toString())) { - if (notifText.isNotEmpty()) { - notifText += ", " - } - notifText += courseS[i] + ": " + additionalS[i] - } + for (i in 0 until rows.size) { + val row = rows[i] + val cols = row.select("th") as Elements + + groupS.add(cols[0].text()) + dateS.add(cols[1].text()) + timeS.add(cols[2].text()) + courseS.add(cols[3].text()) + roomS.add(cols[4].text()) + additionalS.add(cols[5].text()) + if (!jobservice) { + mView?.let { + progressBar.incrementProgressBy(1) } - } else if ((prefs.getString("classes", "") ?: "").isNotEmpty() && (prefs.getString("courses", "") ?: "").isNotEmpty()) { - if (groupS[i] != "" && courseS[i] != "") { - if ((prefs.getString("courses", "") ?: "").contains(courseS[i])) { - if ((prefs.getString("classes", "") ?: "").contains(groupS[i]) || groupS[i].contains((prefs.getString("classes", "") ?: "").toString())) { + } + + val drawable = MiscData.getIcon(courseS[i]) + val subst = Subst(drawable, groupS[i], dateS[i], timeS[i], courseS[i], + roomS[i], additionalS[i], priority) + priority-- + substViewModel.insertSubst(subst) + + if (jobservice && prefs.getBoolean("notif", true)) { + if ((prefs.getString("courses", "") + ?: "").isEmpty() && (prefs.getString("classes", "") + ?: "").isNotEmpty()) { + if (groupS[i].isNotEmpty() && groupS[i] != "") { + if ((prefs.getString("classes", "") + ?: "").contains(groupS[i]) || groupS[i].contains((prefs.getString("classes", "") + ?: "").toString())) { if (notifText.isNotEmpty()) { notifText += ", " } notifText += courseS[i] + ": " + additionalS[i] } } + } else if ((prefs.getString("classes", "") + ?: "").isNotEmpty() && (prefs.getString("courses", "") + ?: "").isNotEmpty()) { + if (groupS[i] != "" && courseS[i] != "") { + if ((prefs.getString("courses", "") ?: "").contains(courseS[i])) { + if ((prefs.getString("classes", "") + ?: "").contains(groupS[i]) || groupS[i].contains((prefs.getString("classes", "") + ?: "").toString())) { + if (notifText.isNotEmpty()) { + notifText += ", " + } + notifText += courseS[i] + ": " + additionalS[i] + } + } + } } } + edit.putString("time", currentTime).apply() } - } - if (jobservice) { - val openApp = Intent(mContext, Main::class.java) - openApp.flags = Intent.FLAG_ACTIVITY_NEW_TASK - openApp.flags += Intent.FLAG_ACTIVITY_CLEAR_TASK - val openAppPending = PendingIntent.getActivity(mContext, 0, openApp, 0) + if (jobservice && prefs.getBoolean("notif", true)) { + val openApp = Intent(mContext, Main::class.java) + openApp.flags = Intent.FLAG_ACTIVITY_NEW_TASK + openApp.flags += Intent.FLAG_ACTIVITY_CLEAR_TASK + val openAppPending = PendingIntent.getActivity(mContext, 0, openApp, 0) - val notificationLayout = RemoteViews(mContext.packageName, R.layout.notification) - notificationLayout.setTextViewText(R.id.notification_title, mContext.getString(R.string.subst)) - notificationLayout.setTextViewText(R.id.notification_textview, notifText) + val notificationLayout = RemoteViews(mContext.packageName, R.layout.notification) + notificationLayout.setTextViewText(R.id.notification_title, mContext.getString(R.string.subst)) + notificationLayout.setTextViewText(R.id.notification_textview, notifText) - if (notifText.isNotEmpty()) { - val manager = mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - val channelId = "general" - val channelName = mContext.getString(R.string.general) + if (notifText.isNotEmpty()) { + val manager = mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val channelId = "general" + val channelName = mContext.getString(R.string.general) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT) - channel.enableLights(true) - channel.lightColor = Color.BLUE - manager.createNotificationChannel(channel) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT) + channel.enableLights(true) + channel.lightColor = Color.BLUE + manager.createNotificationChannel(channel) + } + + val notification = NotificationCompat.Builder(mContext, channelId) + .setStyle(NotificationCompat.DecoratedCustomViewStyle()) + .setCustomContentView(notificationLayout) + .setSmallIcon(R.drawable.ic_avh) + .setContentIntent(openAppPending) + .setAutoCancel(true) + .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) + .build() + manager.notify(1, notification) } - - val notification = NotificationCompat.Builder(mContext, channelId) - .setStyle(NotificationCompat.DecoratedCustomViewStyle()) - .setCustomContentView(notificationLayout) - .setSmallIcon(R.drawable.ic_avh) - .setContentIntent(openAppPending) - .setAutoCancel(true) - .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) - .build() - manager.notify(1, notification) } } } @@ -263,9 +269,8 @@ class DataFetcher(isplan: Boolean, ismenu: Boolean, isjobservice: Boolean, conte pullToRefresh.isRefreshing = false if (plan) { val snackBarView = v.findViewById(R.id.coordination) - sdf.applyPattern(newDateFormat) val sb = StringBuilder() - val lastUpdated = sb.append(mContext.getText(R.string.lastupdatedK)).append(sdf.format(d)).toString() + val lastUpdated = sb.append(mContext.getText(R.string.lastupdatedK)).append(currentTime) Snackbar.make(snackBarView, lastUpdated, Snackbar.LENGTH_LONG).show() } } diff --git a/app/src/main/java/com/denizd/substitutionplan/NotificationService.kt b/app/src/main/java/com/denizd/substitutionplan/NotificationService.kt index 7a1cde4..a8bac9a 100644 --- a/app/src/main/java/com/denizd/substitutionplan/NotificationService.kt +++ b/app/src/main/java/com/denizd/substitutionplan/NotificationService.kt @@ -5,6 +5,7 @@ import android.app.job.JobService import android.content.Context import android.net.ConnectivityManager import android.preference.PreferenceManager +import org.jsoup.Jsoup import java.net.URL class NotificationService : JobService() { @@ -29,21 +30,20 @@ class NotificationService : JobService() { val networkStatus = connectivityManager.activeNetworkInfo Thread(Runnable { - if (jobCancelled || networkStatus == null) { + if (!prefs.getBoolean("notif", false)) { return@Runnable - } - if (prefs.getBoolean("notif", false)) { - edit.putInt("notificationTestNumberDev", prefs.getInt("notificationTestNumberDev", 0) + 1).apply() - try { - val url = URL("https://djd4rkn355.github.io/subst.html") - val connection = url.openConnection() - if (connection.getHeaderField("Last-Modified") != prefs.getString("time", "")) { + } else { + if (jobCancelled || networkStatus == null) { + return@Runnable + } + if (prefs.getBoolean("notif", false)) { + edit.putInt("notificationTestNumberDev", prefs.getInt("notificationTestNumberDev", 0) + 1).apply() + try { DataFetcher(true, true, true, context, application, null).execute() - edit.putString("time", connection.getHeaderField("Last-Modified")).apply() - } - } catch (ignored: Exception) {} + } catch (ignored: Exception) {} + } + jobFinished(params, false) } - jobFinished(params, false) }).start() } } \ No newline at end of file diff --git a/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt b/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt index e3b23db..00cc349 100644 --- a/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt +++ b/app/src/main/java/com/denizd/substitutionplan/SettingsFragment.kt @@ -350,7 +350,7 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen dialogView.findViewById(R.id.dialogtext).text = getString(R.string.fortest) dialogButton.setOnClickListener { when (dialogEditText.text.toString()) { - "@DIAGNOSTICS" -> { + "_DIAGNOSTICS" -> { val alertDialogDev = AlertDialog.Builder(mContext, R.style.AlertDialog) val devDialogView = LayoutInflater.from(mContext).inflate(R.layout.diagnostics_dialog, null) val devDialogText = devDialogView.findViewById(R.id.dialogtext) @@ -382,11 +382,11 @@ class SettingsFragment : Fragment(R.layout.content_settings), View.OnClickListen Toast.makeText(mContext, R.string.noyoutube, Toast.LENGTH_LONG).show() } } - "@NOTIFICATION" -> { + "_NOTIFICATION" -> { edit.putString("time", "").apply() Toast.makeText(mContext, "Notification time cleared", Toast.LENGTH_LONG).show() } // TODO add option to clear database - "@FIRSTTIME" -> { + "_FIRSTTIME" -> { edit.putBoolean("firstTime", true).apply() Toast.makeText(mContext, "First time flag cleared", Toast.LENGTH_LONG).show() }