diff --git a/app/proguard/app.pro b/app/proguard/app.pro index 443cc2b1..65817554 100644 --- a/app/proguard/app.pro +++ b/app/proguard/app.pro @@ -25,10 +25,10 @@ -keep class pl.szczodrzynski.edziennik.data.db.entity.Event { *; } -keep class pl.szczodrzynski.edziennik.data.db.full.EventFull { *; } -keep class pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel { *; } --keepclassmembers class pl.szczodrzynski.edziennik.widgets.WidgetConfig { public *; } --keepnames class pl.szczodrzynski.edziennik.WidgetTimetable --keepnames class pl.szczodrzynski.edziennik.notifications.WidgetNotifications --keepnames class pl.szczodrzynski.edziennik.luckynumber.WidgetLuckyNumber +-keepclassmembers class pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig { public *; } +-keepnames class pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider +-keepnames class pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider +-keepnames class pl.szczodrzynski.edziennik.widgets.luckynumber.WidgetLuckyNumber -keep class .R -keep class **.R$* { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1d99e178..fa7b2065 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,17 @@ xmlns:tools="http://schemas.android.com/tools" package="pl.szczodrzynski.edziennik"> + + + + + + + + + + + - - + - - - - - - - - - - - - + - - - - - - - - - - - - + + + + + + - - - + + + @@ -163,8 +95,10 @@ android:name="android.appwidget.provider" android:resource="@xml/widget_notifications_info" /> - + + @@ -174,8 +108,58 @@ android:name="android.appwidget.provider" android:resource="@xml/widget_lucky_number_info" /> - + + + + + + + + + + + + + + @@ -188,54 +172,53 @@ - - - - - + - - - + - + + + + - - - - - - - - - - - - diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt b/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt index 92010b02..3cd469c4 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt @@ -6,6 +6,7 @@ import android.content.Context import android.content.pm.PackageManager import android.content.res.ColorStateList import android.content.res.Resources +import android.database.Cursor import android.graphics.PorterDuff import android.graphics.PorterDuffColorFilter import android.graphics.Typeface @@ -26,6 +27,9 @@ import android.widget.CompoundButton import android.widget.TextView import androidx.annotation.* import androidx.core.app.ActivityCompat +import androidx.core.database.getIntOrNull +import androidx.core.database.getLongOrNull +import androidx.core.database.getStringOrNull import androidx.core.util.forEach import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LiveData @@ -938,3 +942,7 @@ fun Context.getNotificationTitle(type: Int): String { else -> R.string.notification_type_general }) } + +fun Cursor?.getString(columnName: String) = this?.getStringOrNull(getColumnIndex(columnName)) +fun Cursor?.getInt(columnName: String) = this?.getIntOrNull(getColumnIndex(columnName)) +fun Cursor?.getLong(columnName: String) = this?.getLongOrNull(getColumnIndex(columnName)) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt b/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt index 9977fe10..d8d523d5 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt @@ -4,6 +4,7 @@ package pl.szczodrzynski.edziennik.config +import com.google.gson.JsonObject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -74,6 +75,11 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig { get() { mRunSync = mRunSync ?: values.get("runSync", false); return mRunSync ?: false } set(value) { set("runSync", value); mRunSync = value } + private var mWidgetConfigs: JsonObject? = null + var widgetConfigs: JsonObject + get() { mWidgetConfigs = mWidgetConfigs ?: values.get("widgetConfigs", JsonObject()); return mWidgetConfigs ?: JsonObject() } + set(value) { set("widgetConfigs", value); mWidgetConfigs = value } + private var rawEntries: List = db.configDao().getAllNow() private val profileConfigs: HashMap = hashMapOf() init { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt index 774a121f..992d6f23 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt @@ -10,38 +10,14 @@ import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.data.api.* import pl.szczodrzynski.edziennik.data.api.interfaces.EndpointCallback import pl.szczodrzynski.edziennik.data.db.AppDb -import pl.szczodrzynski.edziennik.data.db.entity.Announcement -import pl.szczodrzynski.edziennik.data.db.entity.EndpointTimer -import pl.szczodrzynski.edziennik.data.db.entity.Attendance -import pl.szczodrzynski.edziennik.data.db.entity.AttendanceType -import pl.szczodrzynski.edziennik.data.db.entity.Classroom -import pl.szczodrzynski.edziennik.data.db.entity.Event -import pl.szczodrzynski.edziennik.data.db.entity.EventType -import pl.szczodrzynski.edziennik.data.db.entity.Grade -import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory -import pl.szczodrzynski.edziennik.data.db.entity.LessonRange -import pl.szczodrzynski.edziennik.data.db.entity.LoginStore -import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber -import pl.szczodrzynski.edziennik.data.db.entity.Message -import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient -import pl.szczodrzynski.edziennik.data.db.entity.Metadata -import pl.szczodrzynski.edziennik.data.db.entity.Notice -import pl.szczodrzynski.edziennik.data.db.entity.NoticeType -import pl.szczodrzynski.edziennik.data.db.entity.Notification -import pl.szczodrzynski.edziennik.data.db.entity.Profile -import pl.szczodrzynski.edziennik.data.db.entity.Subject -import pl.szczodrzynski.edziennik.data.db.entity.Teacher -import pl.szczodrzynski.edziennik.data.db.entity.TeacherAbsence -import pl.szczodrzynski.edziennik.data.db.entity.TeacherAbsenceType -import pl.szczodrzynski.edziennik.data.db.entity.Team -import pl.szczodrzynski.edziennik.data.db.entity.Lesson -import pl.szczodrzynski.edziennik.data.db.entity.LibrusLesson +import pl.szczodrzynski.edziennik.data.db.entity.* import pl.szczodrzynski.edziennik.singleOrNull import pl.szczodrzynski.edziennik.toSparseArray import pl.szczodrzynski.edziennik.utils.Utils.d import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.values import java.io.InterruptedIOException +import java.net.ConnectException import java.net.SocketTimeoutException import java.net.UnknownHostException import javax.net.ssl.SSLException @@ -390,7 +366,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt apiError.errorCode = when (apiError.throwable) { is UnknownHostException -> ERROR_REQUEST_FAILURE_HOSTNAME_NOT_FOUND is SSLException -> ERROR_REQUEST_FAILURE_SSL_ERROR - is InterruptedIOException -> ERROR_REQUEST_FAILURE_NO_INTERNET + is InterruptedIOException, is ConnectException -> ERROR_REQUEST_FAILURE_NO_INTERNET is SocketTimeoutException -> ERROR_REQUEST_FAILURE_TIMEOUT else -> if (apiError.errorCode == ERROR_REQUEST_FAILURE) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/NotificationDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/NotificationDao.kt index 549b2327..a8ae22b9 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/NotificationDao.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/NotificationDao.kt @@ -4,6 +4,7 @@ package pl.szczodrzynski.edziennik.data.db.dao +import android.database.Cursor import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert @@ -36,4 +37,7 @@ interface NotificationDao { @Query("UPDATE notifications SET posted = 1 WHERE posted = 0") fun setAllPosted() + + @Query("SELECT * FROM notifications ORDER BY addedDate DESC") + fun getAllCursor(): Cursor } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt b/app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt index 2b5f38c9..c6a4cfec 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/receivers/SzkolnyReceiver.kt @@ -13,6 +13,10 @@ import pl.szczodrzynski.edziennik.data.api.events.requests.TaskCancelRequest import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask class SzkolnyReceiver : BroadcastReceiver() { + companion object { + const val ACTION = "pl.szczodrzynski.edziennik.SZKOLNY_MAIN" + } + override fun onReceive(context: Context?, intent: Intent?) { context ?: return when (intent?.extras?.getString("task", null)) { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/receivers/UserPresentReceiver.java b/app/src/main/java/pl/szczodrzynski/edziennik/receivers/UserPresentReceiver.java index 3884c4f0..82a31f11 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/receivers/UserPresentReceiver.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/receivers/UserPresentReceiver.java @@ -6,7 +6,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import pl.szczodrzynski.edziennik.WidgetTimetable; +import pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider; public class UserPresentReceiver extends BroadcastReceiver { @Override @@ -14,12 +14,12 @@ public class UserPresentReceiver extends BroadcastReceiver { if (intent.getAction() != null) { if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) { //Toast.makeText(context, "User is present", Toast.LENGTH_SHORT).show(); - Intent widgetIntent = new Intent(context, WidgetTimetable.class); + Intent widgetIntent = new Intent(context, WidgetTimetableProvider.class); widgetIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); // Use an array and EXTRA_APPWIDGET_IDS instead of AppWidgetManager.EXTRA_APPWIDGET_ID, // since it seems the onUpdate() is only fired on that: int[] ids = AppWidgetManager.getInstance(context) - .getAppWidgetIds(new ComponentName(context, WidgetTimetable.class)); + .getAppWidgetIds(new ComponentName(context, WidgetTimetableProvider.class)); widgetIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids); context.sendBroadcast(widgetIntent); } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/LessonDialogActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/LessonDialogActivity.kt similarity index 97% rename from app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/LessonDialogActivity.kt rename to app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/LessonDialogActivity.kt index fd118390..891e44ea 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/LessonDialogActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/LessonDialogActivity.kt @@ -2,7 +2,7 @@ * Copyright (c) Kuba Szczodrzyński 2019-11-14. */ -package pl.szczodrzynski.edziennik.widgets.timetable +package pl.szczodrzynski.edziennik.ui.widgets import android.content.Intent import android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/WidgetConfig.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/WidgetConfig.java similarity index 82% rename from app/src/main/java/pl/szczodrzynski/edziennik/widgets/WidgetConfig.java rename to app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/WidgetConfig.java index 7fea2fc4..9d3ba5ce 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/WidgetConfig.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/WidgetConfig.java @@ -1,4 +1,8 @@ -package pl.szczodrzynski.edziennik.widgets; +/* + * Copyright (c) Kuba Szczodrzyński 2020-1-6. + */ + +package pl.szczodrzynski.edziennik.ui.widgets; public class WidgetConfig { public int profileId = -1; diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/WidgetConfigActivity.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/WidgetConfigActivity.java similarity index 93% rename from app/src/main/java/pl/szczodrzynski/edziennik/widgets/WidgetConfigActivity.java rename to app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/WidgetConfigActivity.java index b2484b92..06014abf 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/WidgetConfigActivity.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/WidgetConfigActivity.java @@ -1,4 +1,8 @@ -package pl.szczodrzynski.edziennik.widgets; +/* + * Copyright (c) Kuba Szczodrzyński 2020-1-6. + */ + +package pl.szczodrzynski.edziennik.ui.widgets; import android.app.Activity; import android.app.WallpaperManager; @@ -15,16 +19,17 @@ import android.widget.SeekBar; import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.simplelist.MaterialSimpleListAdapter; import com.afollestad.materialdialogs.simplelist.MaterialSimpleListItem; +import com.google.gson.JsonObject; import java.util.List; import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.R; -import pl.szczodrzynski.edziennik.WidgetTimetable; import pl.szczodrzynski.edziennik.data.db.entity.Profile; import pl.szczodrzynski.edziennik.databinding.DialogWidgetConfigBinding; +import pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider; +import pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider; import pl.szczodrzynski.edziennik.widgets.luckynumber.WidgetLuckyNumber; -import pl.szczodrzynski.edziennik.widgets.notifications.WidgetNotifications; import static pl.szczodrzynski.edziennik.ExtensionsKt.filterOutArchived; @@ -130,17 +135,19 @@ public class WidgetConfigActivity extends Activity { .positiveText(R.string.ok) .negativeText(R.string.cancel) .onPositive(((dialog1, which) -> { - app.appConfig.widgetTimetableConfigs.put(mAppWidgetId, new WidgetConfig(profileId, bigStyle, darkTheme, opacity)); - app.saveConfig("widgetTimetableConfigs"); + WidgetConfig config = new WidgetConfig(profileId, bigStyle, darkTheme, opacity); + JsonObject configs = app.config.getWidgetConfigs(); + configs.add(Integer.toString(mAppWidgetId), app.gson.toJsonTree(config)); + app.config.setWidgetConfigs(configs); Intent refreshIntent; switch (widgetType) { default: case WIDGET_TIMETABLE: - refreshIntent = new Intent(app.getContext(), WidgetTimetable.class); + refreshIntent = new Intent(app.getContext(), WidgetTimetableProvider.class); break; case WIDGET_NOTIFICATIONS: - refreshIntent = new Intent(app.getContext(), WidgetNotifications.class); + refreshIntent = new Intent(app.getContext(), WidgetNotificationsProvider.class); break; case WIDGET_LUCKY_NUMBER: refreshIntent = new Intent(app.getContext(), WidgetLuckyNumber.class); diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsFactory.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsFactory.kt new file mode 100644 index 00000000..2386a438 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsFactory.kt @@ -0,0 +1,77 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2020-1-6. + */ + +package pl.szczodrzynski.edziennik.ui.widgets.notifications + +import android.content.Intent +import android.database.Cursor +import android.os.Binder +import android.widget.AdapterView +import android.widget.RemoteViews +import android.widget.RemoteViewsService +import com.google.gson.JsonParser +import pl.szczodrzynski.edziennik.* +import pl.szczodrzynski.edziennik.data.db.entity.Notification +import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig +import pl.szczodrzynski.edziennik.utils.models.Date + +class WidgetNotificationsFactory(val app: App, val config: WidgetConfig) : RemoteViewsService.RemoteViewsFactory { + companion object { + private const val TAG = "WidgetNotificationsFactory" + } + private var cursor: Cursor? = null + + override fun onDataSetChanged() { + cursor?.close() + Binder.clearCallingIdentity().let { + cursor = app.db.notificationDao().getAllCursor() + Binder.restoreCallingIdentity(it) + } + } + + override fun getViewAt(position: Int): RemoteViews? { + if (position == AdapterView.INVALID_POSITION || cursor?.moveToPosition(position) != true) + return null + + val views: RemoteViews = if (config.bigStyle) { + RemoteViews(app.packageName, if (config.darkTheme) R.layout.row_widget_notifications_dark_big_item else R.layout.row_widget_notifications_big_item) + } else { + RemoteViews(app.packageName, if (config.darkTheme) R.layout.row_widget_notifications_dark_item else R.layout.row_widget_notifications_item) + } + + val notification = cursor?.run { + Notification( + getInt("id") ?: 0, + getString("title") ?: "", + getString("text") ?: "", + getInt("type") ?: 0, + getInt("profileId"), + getString("profileName"), + getInt("posted") == 1, + getInt("viewId"), + getString("extras")?.let { JsonParser().parse(it).asJsonObject }, + getLong("addedDate") ?: System.currentTimeMillis() + ) + } ?: return views + + views.apply { + setTextViewText(R.id.widgetNotificationsTitle, + app.getString(R.string.widget_notifications_title_format, notification.title, app.getNotificationTitle(notification.type))) + setTextViewText(R.id.widgetNotificationsText, notification.text) + setTextViewText(R.id.widgetNotificationsDate, Date.fromMillis(notification.addedDate).formattedString) + setOnClickFillInIntent(R.id.widgetNotificationsRoot, Intent().also { notification.fillIntent(it) }) + } + + return views + } + + override fun getItemId(position: Int): Long = if (cursor?.moveToPosition(position) == true) + cursor?.getLong("id") ?: position.toLong() else position.toLong() + override fun getCount() = cursor?.count ?: 0 + override fun onCreate() {} + override fun getLoadingView() = null + override fun hasStableIds() = true + override fun getViewTypeCount() = 1 + override fun onDestroy() = cursor?.close() ?: Unit +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsProvider.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsProvider.kt new file mode 100644 index 00000000..77d2a902 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsProvider.kt @@ -0,0 +1,91 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2020-1-6. + */ + +package pl.szczodrzynski.edziennik.ui.widgets.notifications + +import android.app.PendingIntent +import android.appwidget.AppWidgetManager +import android.appwidget.AppWidgetProvider +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.net.Uri +import android.view.View +import android.widget.RemoteViews +import com.mikepenz.iconics.IconicsDrawable +import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial +import com.mikepenz.iconics.utils.colorInt +import com.mikepenz.iconics.utils.sizeDp +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.MainActivity +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.getJsonObject +import pl.szczodrzynski.edziennik.receivers.SzkolnyReceiver +import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig + +class WidgetNotificationsProvider : AppWidgetProvider() { + companion object { + private const val TAG = "WidgetNotificationsProvider" + } + + override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { + val app = context.applicationContext as App + val widgetConfigs = app.config.widgetConfigs + for (appWidgetId in appWidgetIds) { + val config = widgetConfigs.getJsonObject(appWidgetId.toString())?.let { app.gson.fromJson(it, WidgetConfig::class.java) } ?: continue + + val iconSize = if (config.bigStyle) 24 else 16 + + val views: RemoteViews = if (config.bigStyle) { + RemoteViews(app.packageName, if (config.darkTheme) R.layout.widget_notifications_dark_big else R.layout.widget_notifications_big) + } else { + RemoteViews(app.packageName, if (config.darkTheme) R.layout.widget_notifications_dark else R.layout.widget_notifications) + } + + val syncIntent = Intent(SzkolnyReceiver.ACTION) + syncIntent.putExtra("task", "SyncRequest") + val syncPendingIntent = PendingIntent.getBroadcast(context, 0, syncIntent, 0) + views.setOnClickPendingIntent(R.id.widgetNotificationsSync, syncPendingIntent) + + views.setImageViewBitmap( + R.id.widgetNotificationsSync, + IconicsDrawable(context, CommunityMaterial.Icon.cmd_download_outline) + .colorInt(Color.WHITE) + .sizeDp(iconSize) + .toBitmap() + ) + + views.setViewVisibility(R.id.widgetNotificationsLoading, View.GONE) + + val listIntent = Intent(context, WidgetNotificationsService::class.java) + listIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) + listIntent.putExtra("config", app.gson.toJson(config)) + listIntent.data = Uri.parse(listIntent.toUri(Intent.URI_INTENT_SCHEME)) + views.setRemoteAdapter(R.id.widgetNotificationsListView, listIntent) + + val itemIntent = Intent(context, MainActivity::class.java) + itemIntent.action = Intent.ACTION_MAIN + val itemPendingIntent = PendingIntent.getActivity(context, 0, itemIntent, 0) + views.setPendingIntentTemplate(R.id.widgetNotificationsListView, itemPendingIntent) + + val headerIntent = Intent(context, MainActivity::class.java) + headerIntent.action = Intent.ACTION_MAIN + headerIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_NOTIFICATIONS) + val headerPendingIntent = PendingIntent.getActivity(context, 0, headerIntent, 0) + views.setOnClickPendingIntent(R.id.widgetNotificationsHeader, headerPendingIntent) + + appWidgetManager.updateAppWidget(appWidgetId, views) + appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widgetNotificationsListView) + } + } + + override fun onDeleted(context: Context, appWidgetIds: IntArray) { + val app = context.applicationContext as App + val widgetConfigs = app.config.widgetConfigs + appWidgetIds.forEach { + widgetConfigs.remove(it.toString()) + } + app.config.widgetConfigs = widgetConfigs + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsService.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsService.kt new file mode 100644 index 00000000..fa837e08 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsService.kt @@ -0,0 +1,18 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2020-1-6. + */ + +package pl.szczodrzynski.edziennik.ui.widgets.notifications + +import android.content.Intent +import android.widget.RemoteViewsService +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig + +class WidgetNotificationsService : RemoteViewsService() { + override fun onGetViewFactory(intent: Intent): RemoteViewsFactory { + val app = application as App + val config = intent.getStringExtra("config")?.let { app.gson.fromJson(it, WidgetConfig::class.java) } + return WidgetNotificationsFactory(app, config ?: WidgetConfig(-1)) + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/WidgetTimetableListProvider.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableFactory.java similarity index 96% rename from app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/WidgetTimetableListProvider.java rename to app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableFactory.java index 81bfd599..47e0aea3 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/WidgetTimetableListProvider.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableFactory.java @@ -1,4 +1,8 @@ -package pl.szczodrzynski.edziennik.widgets.timetable; +/* + * Copyright (c) Kuba Szczodrzyński 2020-1-6. + */ + +package pl.szczodrzynski.edziennik.ui.widgets.timetable; import android.appwidget.AppWidgetManager; import android.content.ComponentName; @@ -28,14 +32,13 @@ import com.mikepenz.iconics.typeface.library.community.material.CommunityMateria import java.util.List; import pl.szczodrzynski.edziennik.R; -import pl.szczodrzynski.edziennik.WidgetTimetable; import pl.szczodrzynski.edziennik.utils.models.Date; import pl.szczodrzynski.edziennik.utils.models.ItemWidgetTimetableModel; import pl.szczodrzynski.edziennik.utils.models.Time; import static android.util.TypedValue.COMPLEX_UNIT_SP; -public class WidgetTimetableListProvider implements RemoteViewsService.RemoteViewsFactory { +public class WidgetTimetableFactory implements RemoteViewsService.RemoteViewsFactory { private static final String TAG = "WidgetTimetableProvider"; private Context context; @@ -44,7 +47,7 @@ public class WidgetTimetableListProvider implements RemoteViewsService.RemoteVie private static boolean triedToReload = false; //For obtaining the activity's context and intent - public WidgetTimetableListProvider(Context context, Intent intent) { + public WidgetTimetableFactory(Context context, Intent intent) { this.context = context; this.appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0); // executed only ONCE @@ -65,7 +68,7 @@ public class WidgetTimetableListProvider implements RemoteViewsService.RemoteVie public void onDataSetChanged() { // executed EVERY TIME Log.d(TAG, "onDataSetChanged for appWidgetId: "+appWidgetId); - lessons = WidgetTimetable.Companion.getTimetables() == null ? null : WidgetTimetable.Companion.getTimetables().get(appWidgetId); + lessons = WidgetTimetableProvider.Companion.getTimetables() == null ? null : WidgetTimetableProvider.Companion.getTimetables().get(appWidgetId); } @Override @@ -306,11 +309,11 @@ public class WidgetTimetableListProvider implements RemoteViewsService.RemoteVie // try to reload the widget // only once triedToReload = true; - Intent intent = new Intent(context, WidgetTimetable.class); + Intent intent = new Intent(context, WidgetTimetableProvider.class); intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); // Use an array and EXTRA_APPWIDGET_IDS instead of AppWidgetManager.EXTRA_APPWIDGET_ID, // since it seems the onUpdate() is only fired on that: - int[] ids = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, WidgetTimetable.class)); + int[] ids = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, WidgetTimetableProvider.class)); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids); context.sendBroadcast(intent); } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableProvider.kt similarity index 85% rename from app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.kt rename to app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableProvider.kt index fc1a407b..6d7e712d 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableProvider.kt @@ -1,4 +1,8 @@ -package pl.szczodrzynski.edziennik +/* + * Copyright (c) Kuba Szczodrzyński 2020-1-6. + */ + +package pl.szczodrzynski.edziennik.ui.widgets.timetable import android.app.PendingIntent import android.appwidget.AppWidgetManager @@ -21,20 +25,50 @@ import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.sizeDp +import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask import pl.szczodrzynski.edziennik.data.db.entity.Event.TYPE_HOMEWORK import pl.szczodrzynski.edziennik.data.db.entity.Lesson +import pl.szczodrzynski.edziennik.ui.widgets.LessonDialogActivity +import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.ItemWidgetTimetableModel import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Week -import pl.szczodrzynski.edziennik.widgets.WidgetConfig -import pl.szczodrzynski.edziennik.widgets.timetable.LessonDialogActivity -import pl.szczodrzynski.edziennik.widgets.timetable.WidgetTimetableService import java.lang.reflect.InvocationTargetException -class WidgetTimetable : AppWidgetProvider() { +class WidgetTimetableProvider : AppWidgetProvider() { + companion object { + const val ACTION_SYNC_DATA = "ACTION_SYNC_DATA" + private const val TAG = "WidgetTimetable" + + var timetables: SparseArray>? = null + + fun getPendingSelfIntent(context: Context, action: String): PendingIntent { + val intent = Intent(context, WidgetTimetableProvider::class.java) + intent.action = action + return getPendingSelfIntent(context, intent) + } + + fun getPendingSelfIntent(context: Context, intent: Intent): PendingIntent { + return PendingIntent.getBroadcast(context, 0, intent, 0) + } + + fun drawableToBitmap(drawable: Drawable): Bitmap { + + if (drawable is BitmapDrawable) { + return drawable.bitmap + } + + val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) + val canvas = Canvas(bitmap) + drawable.setBounds(0, 0, canvas.width, canvas.height) + drawable.draw(canvas) + + return bitmap + } + } override fun onReceive(context: Context, intent: Intent) { if (ACTION_SYNC_DATA == intent.action) { @@ -46,12 +80,12 @@ class WidgetTimetable : AppWidgetProvider() { private val ignoreCancelled = true override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { - val thisWidget = ComponentName(context, WidgetTimetable::class.java) + val thisWidget = ComponentName(context, WidgetTimetableProvider::class.java) timetables = SparseArray() - //timetables.clear(); val app = context.applicationContext as App + val widgetConfigs = app.config.widgetConfigs var bellSyncDiffMillis: Long = 0 app.config.timetable.bellSyncDiff?.let { @@ -63,37 +97,32 @@ class WidgetTimetable : AppWidgetProvider() { val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget) allWidgetIds?.forEach { appWidgetId -> - var widgetConfig = app.appConfig.widgetTimetableConfigs[appWidgetId] - if (widgetConfig == null) { - widgetConfig = WidgetConfig(app.profileFirstId()) - app.appConfig.widgetTimetableConfigs[appWidgetId] = widgetConfig - app.appConfig.savePending = true - } + val config = widgetConfigs.getJsonObject(appWidgetId.toString())?.let { app.gson.fromJson(it, WidgetConfig::class.java) } ?: return@forEach - val views = if (widgetConfig.bigStyle) { - RemoteViews(context.packageName, if (widgetConfig.darkTheme) R.layout.widget_timetable_dark_big else R.layout.widget_timetable_big) + val views = if (config.bigStyle) { + RemoteViews(context.packageName, if (config.darkTheme) R.layout.widget_timetable_dark_big else R.layout.widget_timetable_big) } else { - RemoteViews(context.packageName, if (widgetConfig.darkTheme) R.layout.widget_timetable_dark else R.layout.widget_timetable) + RemoteViews(context.packageName, if (config.darkTheme) R.layout.widget_timetable_dark else R.layout.widget_timetable) } - val refreshIntent = Intent(app, WidgetTimetable::class.java) + val refreshIntent = Intent(app, WidgetTimetableProvider::class.java) refreshIntent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds) - val pendingRefreshIntent = PendingIntent.getBroadcast(context, + val refreshPendingIntent = PendingIntent.getBroadcast(context, 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT) - views.setOnClickPendingIntent(R.id.widgetTimetableRefresh, pendingRefreshIntent) + views.setOnClickPendingIntent(R.id.widgetTimetableRefresh, refreshPendingIntent) views.setOnClickPendingIntent(R.id.widgetTimetableSync, getPendingSelfIntent(context, ACTION_SYNC_DATA)) views.setImageViewBitmap(R.id.widgetTimetableRefresh, IconicsDrawable(context, CommunityMaterial.Icon2.cmd_refresh) .colorInt(Color.WHITE) - .sizeDp(if (widgetConfig.bigStyle) 24 else 16).toBitmap()) + .sizeDp(if (config.bigStyle) 24 else 16).toBitmap()) views.setImageViewBitmap(R.id.widgetTimetableSync, IconicsDrawable(context, CommunityMaterial.Icon.cmd_download_outline) .colorInt(Color.WHITE) - .sizeDp(if (widgetConfig.bigStyle) 24 else 16).toBitmap()) + .sizeDp(if (config.bigStyle) 24 else 16).toBitmap()) - prepareAppWidget(app, appWidgetId, views, widgetConfig, bellSyncDiffMillis) + prepareAppWidget(app, appWidgetId, views, config, bellSyncDiffMillis) appWidgetManager.updateAppWidget(appWidgetId, views) appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widgetTimetableListView) @@ -329,20 +358,20 @@ class WidgetTimetable : AppWidgetProvider() { } // intent running when the header is clicked - val openIntent = Intent(app, MainActivity::class.java) - openIntent.action = "android.intent.action.MAIN" + val headerIntent = Intent(app, MainActivity::class.java) + headerIntent.action = "android.intent.action.MAIN" if (!unified) { // per-profile widget should redirect to it + correct day profileId?.let { - openIntent.putExtra("profileId", it) + headerIntent.putExtra("profileId", it) } displayingDate?.let { - openIntent.putExtra("timetableDate", it.value) + headerIntent.putExtra("timetableDate", it.value) } } - openIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE) - val pendingOpenIntent = PendingIntent.getActivity(app, appWidgetId, openIntent, 0) - views.setOnClickPendingIntent(R.id.widgetTimetableHeader, pendingOpenIntent) + headerIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE) + val headerPendingIntent = PendingIntent.getActivity(app, appWidgetId, headerIntent, 0) + views.setOnClickPendingIntent(R.id.widgetTimetableHeader, headerPendingIntent) timetables!!.put(appWidgetId, models) @@ -353,55 +382,21 @@ class WidgetTimetable : AppWidgetProvider() { views.setRemoteAdapter(R.id.widgetTimetableListView, listIntent) // create an intent used to display the lesson details dialog - val intentTemplate = Intent(app, LessonDialogActivity::class.java) - intentTemplate.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK /*or Intent.FLAG_ACTIVITY_CLEAR_TASK*/) - val pendingIntentTimetable = PendingIntent.getActivity(app, appWidgetId, intentTemplate, 0) - views.setPendingIntentTemplate(R.id.widgetTimetableListView, pendingIntentTimetable) + val itemIntent = Intent(app, LessonDialogActivity::class.java) + itemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK /*or Intent.FLAG_ACTIVITY_CLEAR_TASK*/) + val itemPendingIntent = PendingIntent.getActivity(app, appWidgetId, itemIntent, 0) + views.setPendingIntentTemplate(R.id.widgetTimetableListView, itemPendingIntent) if (!unified) views.setScrollPosition(R.id.widgetTimetableListView, scrollPos) } - override fun onEnabled(context: Context) { - // Enter relevant functionality for when the first widget is created - } - override fun onDeleted(context: Context, appWidgetIds: IntArray) { val app = context.applicationContext as App - for (appWidgetId in appWidgetIds) { - app.appConfig.widgetTimetableConfigs.remove(appWidgetId) - } - app.saveConfig("widgetTimetableConfigs") - } - - companion object { - const val ACTION_SYNC_DATA = "ACTION_SYNC_DATA" - private const val TAG = "WidgetTimetable" - - var timetables: SparseArray>? = null - - fun getPendingSelfIntent(context: Context, action: String): PendingIntent { - val intent = Intent(context, WidgetTimetable::class.java) - intent.action = action - return getPendingSelfIntent(context, intent) - } - - fun getPendingSelfIntent(context: Context, intent: Intent): PendingIntent { - return PendingIntent.getBroadcast(context, 0, intent, 0) - } - - fun drawableToBitmap(drawable: Drawable): Bitmap { - - if (drawable is BitmapDrawable) { - return drawable.bitmap - } - - val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) - val canvas = Canvas(bitmap) - drawable.setBounds(0, 0, canvas.width, canvas.height) - drawable.draw(canvas) - - return bitmap + val widgetConfigs = app.config.widgetConfigs + appWidgetIds.forEach { + widgetConfigs.remove(it.toString()) } + app.config.widgetConfigs = widgetConfigs } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableService.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableService.java new file mode 100644 index 00000000..d12fdccd --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableService.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2020-1-6. + */ + +package pl.szczodrzynski.edziennik.ui.widgets.timetable; + +import android.content.Intent; +import android.widget.RemoteViewsService; + +public class WidgetTimetableService extends RemoteViewsService { + @Override + public RemoteViewsFactory onGetViewFactory(Intent intent) { + return (new WidgetTimetableFactory(this.getApplicationContext(), intent)); + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/AppConfig.java b/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/AppConfig.java index 021449ff..2654fce3 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/AppConfig.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/AppConfig.java @@ -8,7 +8,7 @@ import java.util.Map; import java.util.TreeMap; import pl.szczodrzynski.edziennik.App; -import pl.szczodrzynski.edziennik.widgets.WidgetConfig; +import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig; public class AppConfig { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/luckynumber/WidgetLuckyNumber.java b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/luckynumber/WidgetLuckyNumber.java index b871080d..50993daf 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/luckynumber/WidgetLuckyNumber.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/luckynumber/WidgetLuckyNumber.java @@ -26,7 +26,7 @@ import pl.szczodrzynski.edziennik.MainActivity; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask; import pl.szczodrzynski.edziennik.data.db.entity.Profile; -import pl.szczodrzynski.edziennik.widgets.WidgetConfig; +import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig; import static pl.szczodrzynski.edziennik.utils.Utils.getCellsForSize; diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/notifications/WidgetNotifications.java b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/notifications/WidgetNotifications.java deleted file mode 100644 index bcc07838..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/notifications/WidgetNotifications.java +++ /dev/null @@ -1,171 +0,0 @@ -package pl.szczodrzynski.edziennik.widgets.notifications; - -import android.app.PendingIntent; -import android.appwidget.AppWidgetManager; -import android.appwidget.AppWidgetProvider; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.graphics.Color; -import android.graphics.PorterDuff; -import android.net.Uri; -import android.os.Build; -import android.view.View; -import android.widget.RemoteViews; - -import com.mikepenz.iconics.IconicsColor; -import com.mikepenz.iconics.IconicsDrawable; -import com.mikepenz.iconics.IconicsSize; -import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import pl.szczodrzynski.edziennik.App; -import pl.szczodrzynski.edziennik.MainActivity; -import pl.szczodrzynski.edziennik.R; -import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask; -import pl.szczodrzynski.edziennik.widgets.WidgetConfig; - -public class WidgetNotifications extends AppWidgetProvider { - - public static final String ACTION_SYNC_DATA = "ACTION_SYNC_DATA"; - private static final String TAG = "WidgetNotifications"; - - @Override - public void onReceive(Context context, Intent intent) { - if (ACTION_SYNC_DATA.equals(intent.getAction())){ - EdziennikTask.Companion.sync().enqueue(context); - } - super.onReceive(context, intent); - } - - public static PendingIntent getPendingSelfIntent(Context context, String action) { - Intent intent = new Intent(context, WidgetNotifications.class); - intent.setAction(action); - return getPendingSelfIntent(context, intent); - } - public static PendingIntent getPendingSelfIntent(Context context, Intent intent) { - return PendingIntent.getBroadcast(context, 0, intent, 0); - } - - @Override - public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { - ComponentName thisWidget = new ComponentName(context, WidgetNotifications.class); - - App app = (App)context.getApplicationContext(); - - int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); - // There may be multiple widgets active, so update all of them - for (int appWidgetId : allWidgetIds) { - - WidgetConfig widgetConfig = app.appConfig.widgetTimetableConfigs.get(appWidgetId); - if (widgetConfig == null) { - widgetConfig = new WidgetConfig(-1); - app.appConfig.widgetTimetableConfigs.put(appWidgetId, widgetConfig); - app.appConfig.savePending = true; - } - - RemoteViews views; - if (widgetConfig.bigStyle) { - views = new RemoteViews(context.getPackageName(), widgetConfig.darkTheme ? R.layout.widget_notifications_dark_big : R.layout.widget_notifications_big); - } - else { - views = new RemoteViews(context.getPackageName(), widgetConfig.darkTheme ? R.layout.widget_notifications_dark : R.layout.widget_notifications); - } - - PorterDuff.Mode mode = PorterDuff.Mode.DST_IN; - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { - // this code seems to crash the launcher on >= P - float transparency = widgetConfig.opacity; //0...1 - long colorFilter = 0x01000000L * (long) (255f * transparency); - try { - final Method[] declaredMethods = Class.forName("android.widget.RemoteViews").getDeclaredMethods(); - final int len = declaredMethods.length; - if (len > 0) { - for (int m = 0; m < len; m++) { - final Method method = declaredMethods[m]; - if (method.getName().equals("setDrawableParameters")) { - method.setAccessible(true); - method.invoke(views, R.id.widgetNotificationsListView, true, -1, (int) colorFilter, mode, -1); - method.invoke(views, R.id.widgetNotificationsHeader, true, -1, (int) colorFilter, mode, -1); - break; - } - } - } - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } - } - - Intent refreshIntent = new Intent(context, WidgetNotifications.class); - refreshIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); - refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); - PendingIntent pendingRefreshIntent = PendingIntent.getBroadcast(context, - 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT); - views.setOnClickPendingIntent(R.id.widgetNotificationsRefresh, pendingRefreshIntent); - - views.setOnClickPendingIntent(R.id.widgetNotificationsSync, getPendingSelfIntent(context, ACTION_SYNC_DATA)); - - views.setImageViewBitmap(R.id.widgetNotificationsRefresh, new IconicsDrawable(context, CommunityMaterial.Icon2.cmd_refresh) - .color(IconicsColor.colorInt(Color.WHITE)) - .size(IconicsSize.dp(widgetConfig.bigStyle ? 24 : 16)).toBitmap()); - - views.setImageViewBitmap(R.id.widgetNotificationsSync, new IconicsDrawable(context, CommunityMaterial.Icon.cmd_download_outline) - .color(IconicsColor.colorInt(Color.WHITE)) - .size(IconicsSize.dp(widgetConfig.bigStyle ? 24 : 16)).toBitmap()); - - //d(TAG, "Profiles: "+ Arrays.toString(profileList.toArray())); - - if (app.appConfig.notifications.size() == 0) { - views.setViewVisibility(R.id.widgetNotificationsLoading, View.VISIBLE); - views.setRemoteAdapter(R.id.widgetNotificationsListView, new Intent()); - views.setTextViewText(R.id.widgetNotificationsLoading, app.getString(R.string.widget_notifications_no_data)); - } - else { - views.setViewVisibility(R.id.widgetNotificationsLoading, View.GONE); - - Intent listIntent = new Intent(context, WidgetNotificationsService.class); - listIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); - listIntent.putExtra("bigStyle", widgetConfig.bigStyle); - listIntent.putExtra("darkTheme", widgetConfig.darkTheme); - listIntent.setData(Uri.parse(listIntent.toUri(Intent.URI_INTENT_SCHEME))); - views.setRemoteAdapter(R.id.widgetNotificationsListView, listIntent); - - // template to handle the click listener for each item - Intent intentTemplate = new Intent(context, MainActivity.class); - intentTemplate.setAction("android.intent.action.MAIN"); - PendingIntent pendingIntentNotifications = PendingIntent.getActivity(context, 0, intentTemplate, 0); - views.setPendingIntentTemplate(R.id.widgetNotificationsListView, pendingIntentNotifications); - } - - Intent openIntent = new Intent(context, MainActivity.class); - openIntent.setAction("android.intent.action.MAIN"); - openIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_NOTIFICATIONS); - PendingIntent pendingOpenIntent = PendingIntent.getActivity(context, - appWidgetId, openIntent, PendingIntent.FLAG_UPDATE_CURRENT); - views.setOnClickPendingIntent(R.id.widgetNotificationsHeader, pendingOpenIntent); - - appWidgetManager.updateAppWidget(appWidgetId, views); - appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widgetNotificationsListView); - } - //modeInt++; - } - - @Override - public void onDeleted(Context context, int[] appWidgetIds) { - App app = (App) context.getApplicationContext(); - for (int appWidgetId: appWidgetIds) { - app.appConfig.widgetTimetableConfigs.remove(appWidgetId); - } - app.saveConfig("widgetTimetableConfigs"); - } -} - - diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/notifications/WidgetNotificationsListProvider.java b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/notifications/WidgetNotificationsListProvider.java deleted file mode 100644 index b3da2ee6..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/notifications/WidgetNotificationsListProvider.java +++ /dev/null @@ -1,98 +0,0 @@ -package pl.szczodrzynski.edziennik.widgets.notifications; - -import android.appwidget.AppWidgetManager; -import android.content.Context; -import android.content.Intent; -import android.util.Log; -import android.widget.RemoteViews; -import android.widget.RemoteViewsService; - -import pl.szczodrzynski.edziennik.App; -import pl.szczodrzynski.edziennik.R; -import pl.szczodrzynski.edziennik.utils.models.Date; -import pl.szczodrzynski.edziennik.utils.models.Notification; - -public class WidgetNotificationsListProvider implements RemoteViewsService.RemoteViewsFactory { - - private static final String TAG = "WidgetNotificationsProv"; - private App app; - private Context context; - private int appWidgetId; - private boolean bigStyle; - private boolean darkTheme; - - //For obtaining the activity's context and intent - public WidgetNotificationsListProvider(Context context, Intent intent) { - this.app = (App) context.getApplicationContext(); - this.context = context; - this.appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0); - this.bigStyle = intent.getBooleanExtra("bigStyle", false); - this.darkTheme = intent.getBooleanExtra("darkTheme", false); - // executed only ONCE - Log.d(TAG, "appWidgetId: "+appWidgetId); - } - - @Override - public void onCreate() { - } - - @Override - public void onDataSetChanged() { - // executed EVERY TIME - Log.d(TAG, "onDataSetChanged for appWidgetId: "+appWidgetId); - } - - @Override - public void onDestroy() { - } - - @Override - public int getCount() { - return (app.appConfig.notifications == null ? 0 : app.appConfig.notifications.size()); - } - - @Override - public RemoteViews getViewAt(int i) { - RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.row_widget_notifications_item); - if (i > app.appConfig.notifications.size()-1) - return views; - Notification notification = app.appConfig.notifications.get(i); - - if (bigStyle) { - views = new RemoteViews(context.getPackageName(), darkTheme ? R.layout.row_widget_notifications_dark_big_item : R.layout.row_widget_notifications_big_item); - } - else if (darkTheme) { - views = new RemoteViews(context.getPackageName(), R.layout.row_widget_notifications_dark_item); - } - - Intent intent = new Intent(); - notification.fillIntent(intent); - views.setOnClickFillInIntent(R.id.widgetNotificationsRoot, intent); - - views.setTextViewText(R.id.widgetNotificationsTitle, app.getString(R.string.widget_notifications_title_format, notification.title, Notification.stringType(context, notification.type))); - views.setTextViewText(R.id.widgetNotificationsText, notification.text); - views.setTextViewText(R.id.widgetNotificationsDate, Date.fromMillis(notification.addedDate).getFormattedString()); - - return views; - } - - @Override - public RemoteViews getLoadingView() { - return null; - } - - @Override - public int getViewTypeCount() { - return 1; - } - - @Override - public long getItemId(int i) { - return i; - } - - @Override - public boolean hasStableIds() { - return true; - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/notifications/WidgetNotificationsService.java b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/notifications/WidgetNotificationsService.java deleted file mode 100644 index 66d2e88e..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/notifications/WidgetNotificationsService.java +++ /dev/null @@ -1,11 +0,0 @@ -package pl.szczodrzynski.edziennik.widgets.notifications; - -import android.content.Intent; -import android.widget.RemoteViewsService; - -public class WidgetNotificationsService extends RemoteViewsService { - @Override - public RemoteViewsFactory onGetViewFactory(Intent intent) { - return (new WidgetNotificationsListProvider(this.getApplicationContext(), intent)); - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/WidgetTimetableService.java b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/WidgetTimetableService.java deleted file mode 100644 index 594fe591..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/timetable/WidgetTimetableService.java +++ /dev/null @@ -1,17 +0,0 @@ -package pl.szczodrzynski.edziennik.widgets.timetable; - -import android.content.Intent; -import android.widget.RemoteViewsService; - -public class WidgetTimetableService extends RemoteViewsService { - /* - * So pretty simple just defining the Adapter of the listview - * here Adapter is ListProvider - * */ - - @Override - public RemoteViewsFactory onGetViewFactory(Intent intent) { - return (new WidgetTimetableListProvider(this.getApplicationContext(), intent)); - } - -} diff --git a/app/src/main/res/layout/widget_notifications.xml b/app/src/main/res/layout/widget_notifications.xml index 71d06381..5b652da0 100644 --- a/app/src/main/res/layout/widget_notifications.xml +++ b/app/src/main/res/layout/widget_notifications.xml @@ -1,6 +1,4 @@ - - - - - - - - diff --git a/app/src/main/res/xml/widget_notifications_info.xml b/app/src/main/res/xml/widget_notifications_info.xml index e15ea4b9..4720f1b1 100644 --- a/app/src/main/res/xml/widget_notifications_info.xml +++ b/app/src/main/res/xml/widget_notifications_info.xml @@ -11,5 +11,5 @@ android:resizeMode="horizontal|vertical" android:updatePeriodMillis="5400000" android:widgetCategory="home_screen" - android:configure="pl.szczodrzynski.edziennik.widgets.WidgetConfigActivity" + android:configure="pl.szczodrzynski.edziennik.ui.widgets.WidgetConfigActivity" tools:ignore="UnusedAttribute" /> diff --git a/app/src/main/res/xml/widget_timetable_info.xml b/app/src/main/res/xml/widget_timetable_info.xml index a549737f..c0a5b3d4 100644 --- a/app/src/main/res/xml/widget_timetable_info.xml +++ b/app/src/main/res/xml/widget_timetable_info.xml @@ -11,5 +11,5 @@ android:resizeMode="horizontal|vertical" android:updatePeriodMillis="1800000" android:widgetCategory="home_screen" - android:configure="pl.szczodrzynski.edziennik.widgets.WidgetConfigActivity" + android:configure="pl.szczodrzynski.edziennik.ui.widgets.WidgetConfigActivity" tools:ignore="UnusedAttribute" />