feat: currently airing widget

This commit is contained in:
rebelonion 2024-03-25 21:20:17 -05:00
parent 95cddbd409
commit df23b2f62f
15 changed files with 446 additions and 182 deletions

View file

@ -49,20 +49,21 @@
android:name=".App" android:name=".App"
android:allowBackup="true" android:allowBackup="true"
android:banner="@mipmap/ic_banner_foreground" android:banner="@mipmap/ic_banner_foreground"
android:enableOnBackInvokedCallback="true"
android:icon="${icon_placeholder}" android:icon="${icon_placeholder}"
android:label="@string/app_name" android:label="@string/app_name"
android:largeHeap="true" android:largeHeap="true"
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:enableOnBackInvokedCallback="true"
android:roundIcon="${icon_placeholder_round}" android:roundIcon="${icon_placeholder_round}"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.Dantotsu" android:theme="@style/Theme.Dantotsu"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
tools:ignore="AllowBackup" tools:ignore="AllowBackup"
tools:targetApi="tiramisu"> tools:targetApi="tiramisu">
<receiver <receiver
android:name=".widgets.CurrentlyAiringWidget" android:name=".widgets.CurrentlyAiringWidget"
android:exported="false"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter> </intent-filter>
@ -71,9 +72,15 @@
android:name="android.appwidget.provider" android:name="android.appwidget.provider"
android:resource="@xml/currently_airing_widget_info" /> android:resource="@xml/currently_airing_widget_info" />
</receiver> </receiver>
<activity
android:name=".widgets.CurrentlyAiringWidgetConfigureActivity"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<receiver android:name=".notifications.IncognitoNotificationClickReceiver" /> <receiver android:name=".notifications.IncognitoNotificationClickReceiver" />
<activity <activity
android:name=".media.novel.novelreader.NovelReaderActivity" android:name=".media.novel.novelreader.NovelReaderActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
@ -106,27 +113,25 @@
android:parentActivityName=".MainActivity" /> android:parentActivityName=".MainActivity" />
<activity <activity
android:name=".settings.ExtensionsActivity" android:name=".settings.ExtensionsActivity"
android:windowSoftInputMode="adjustResize|stateHidden" android:parentActivityName=".MainActivity"
android:parentActivityName=".MainActivity" /> android:windowSoftInputMode="adjustResize|stateHidden" />
<activity <activity
android:name=".profile.ProfileActivity" android:name=".profile.ProfileActivity"
android:windowSoftInputMode="adjustResize|stateHidden" android:parentActivityName=".MainActivity"
android:parentActivityName=".MainActivity" /> android:windowSoftInputMode="adjustResize|stateHidden" />
<activity <activity
android:name=".profile.FollowActivity" android:name=".profile.FollowActivity"
android:windowSoftInputMode="adjustResize|stateHidden" android:parentActivityName=".MainActivity"
android:parentActivityName=".MainActivity" /> android:windowSoftInputMode="adjustResize|stateHidden" />
<activity <activity
android:name=".profile.activity.FeedActivity" android:name=".profile.activity.FeedActivity"
android:label="Inbox Activity"
android:configChanges="orientation|screenSize|screenLayout" android:configChanges="orientation|screenSize|screenLayout"
android:parentActivityName=".MainActivity" > android:label="Inbox Activity"
</activity> android:parentActivityName=".MainActivity" />
<activity <activity
android:name=".profile.activity.NotificationActivity" android:name=".profile.activity.NotificationActivity"
android:label="Inbox Activity" android:label="Inbox Activity"
android:parentActivityName=".MainActivity" > android:parentActivityName=".MainActivity" />
</activity>
<activity <activity
android:name=".others.imagesearch.ImageSearchActivity" android:name=".others.imagesearch.ImageSearchActivity"
android:parentActivityName=".MainActivity" /> android:parentActivityName=".MainActivity" />
@ -139,8 +144,9 @@
android:name=".media.CalendarActivity" android:name=".media.CalendarActivity"
android:parentActivityName=".MainActivity" /> android:parentActivityName=".MainActivity" />
<activity android:name=".media.user.ListActivity" /> <activity android:name=".media.user.ListActivity" />
<activity android:name=".profile.SingleStatActivity" <activity
android:parentActivityName=".profile.ProfileActivity"/> android:name=".profile.SingleStatActivity"
android:parentActivityName=".profile.ProfileActivity" />
<activity <activity
android:name=".media.manga.mangareader.MangaReaderActivity" android:name=".media.manga.mangareader.MangaReaderActivity"
android:excludeFromRecents="true" android:excludeFromRecents="true"
@ -152,7 +158,7 @@
android:name=".media.MediaDetailsActivity" android:name=".media.MediaDetailsActivity"
android:parentActivityName=".MainActivity" android:parentActivityName=".MainActivity"
android:theme="@style/Theme.Dantotsu.NeverCutout" android:theme="@style/Theme.Dantotsu.NeverCutout"
android:windowSoftInputMode="adjustResize|stateHidden"/> android:windowSoftInputMode="adjustResize|stateHidden" />
<activity android:name=".media.CharacterDetailsActivity" /> <activity android:name=".media.CharacterDetailsActivity" />
<activity android:name=".home.NoInternet" /> <activity android:name=".home.NoInternet" />
<activity <activity
@ -234,7 +240,6 @@
<data android:host="discord.dantotsu.com" /> <data android:host="discord.dantotsu.com" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".connections.anilist.UrlMedia" android:name=".connections.anilist.UrlMedia"
android:configChanges="orientation|screenSize|layoutDirection" android:configChanges="orientation|screenSize|layoutDirection"
@ -293,7 +298,9 @@
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content" /> <data android:scheme="content" />
<data android:mimeType="*/*" /> <data android:mimeType="*/*" />
<data android:pathPattern=".*\\.ani" /> <data android:pathPattern=".*\\.ani" />
@ -306,22 +313,23 @@
android:exported="false" android:exported="false"
android:theme="@android:style/Theme.Translucent.NoTitleBar" /> android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<receiver android:name=".notifications.AlarmPermissionStateReceiver" <receiver
android:name=".notifications.AlarmPermissionStateReceiver"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED" /> <action android:name="android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver
<receiver android:name=".notifications.BootCompletedReceiver" android:name=".notifications.BootCompletedReceiver"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".notifications.anilist.AnilistNotificationReceiver"/> <receiver android:name=".notifications.anilist.AnilistNotificationReceiver" />
<receiver android:name=".notifications.comment.CommentNotificationReceiver"/> <receiver android:name=".notifications.comment.CommentNotificationReceiver" />
<receiver android:name=".notifications.subscription.SubscriptionNotificationReceiver"/> <receiver android:name=".notifications.subscription.SubscriptionNotificationReceiver" />
<meta-data <meta-data
android:name="preloaded_fonts" android:name="preloaded_fonts"

View file

@ -154,6 +154,7 @@ class App : MultiDexApplication() {
companion object { companion object {
private var instance: App? = null private var instance: App? = null
/** Reference to the application context. /** Reference to the application context.
* *
* USE WITH EXTREME CAUTION!**/ * USE WITH EXTREME CAUTION!**/

View file

@ -1430,6 +1430,24 @@ Page(page:$page,perPage:50) {
) )
} }
suspend fun getUpcomingAnime(id: String): List<Media> {
val res = executeQuery<Query.MediaListCollection>(
"""{MediaListCollection(userId:$id,type:ANIME){lists{name entries{media{id,isFavourite,title{userPreferred,romaji}coverImage{medium}nextAiringEpisode{timeUntilAiring}}}}}}""",
force = true
)
val list = mutableListOf<Media>()
res?.data?.mediaListCollection?.lists?.forEach { listEntry ->
listEntry.entries?.forEach { entry ->
entry.media?.nextAiringEpisode?.timeUntilAiring?.let {
list.add(Media(entry.media!!))
}
}
}
return list.sortedBy { it.timeUntilAiring }
.distinctBy { it.id }
.filter { it.timeUntilAiring != null }
}
suspend fun isUserFav(favType: AnilistMutations.FavType, id: Int): Boolean { //anilist isFavourite is broken, so we need to check it manually suspend fun isUserFav(favType: AnilistMutations.FavType, id: Int): Boolean { //anilist isFavourite is broken, so we need to check it manually
val res = getUserProfile(Anilist.userid?: return false) val res = getUserProfile(Anilist.userid?: return false)
return when (favType) { return when (favType) {

View file

@ -58,6 +58,8 @@ data class Media(
var endDate: FuzzyDate? = null, var endDate: FuzzyDate? = null,
var popularity: Int? = null, var popularity: Int? = null,
var timeUntilAiring: Long? = null,
var characters: ArrayList<Character>? = null, var characters: ArrayList<Character>? = null,
var staff: ArrayList<Author>? = null, var staff: ArrayList<Author>? = null,
var prequel: Media? = null, var prequel: Media? = null,
@ -84,7 +86,7 @@ data class Media(
name = apiMedia.title!!.english, name = apiMedia.title!!.english,
nameRomaji = apiMedia.title!!.romaji, nameRomaji = apiMedia.title!!.romaji,
userPreferredName = apiMedia.title!!.userPreferred, userPreferredName = apiMedia.title!!.userPreferred,
cover = apiMedia.coverImage?.large, cover = apiMedia.coverImage?.large ?: apiMedia.coverImage?.medium,
banner = apiMedia.bannerImage, banner = apiMedia.bannerImage,
status = apiMedia.status.toString(), status = apiMedia.status.toString(),
isFav = apiMedia.isFavourite!!, isFav = apiMedia.isFavourite!!,
@ -97,6 +99,7 @@ data class Media(
startDate = apiMedia.startDate, startDate = apiMedia.startDate,
endDate = apiMedia.endDate, endDate = apiMedia.endDate,
favourites = apiMedia.favourites, favourites = apiMedia.favourites,
timeUntilAiring = apiMedia.nextAiringEpisode?.timeUntilAiring?.let { it.toLong() * 1000},
anime = if (apiMedia.type == MediaType.ANIME) Anime( anime = if (apiMedia.type == MediaType.ANIME) Anime(
totalEpisodes = apiMedia.episodes, totalEpisodes = apiMedia.episodes,
nextAiringEpisode = apiMedia.nextAiringEpisode?.episode?.minus(1) nextAiringEpisode = apiMedia.nextAiringEpisode?.episode?.minus(1)

View file

@ -1,12 +1,24 @@
package ani.dantotsu.widgets package ani.dantotsu.widgets
import android.content.Context import android.content.Context
import android.content.Intent
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.BitmapShader
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.Shader
import android.widget.RemoteViews import android.widget.RemoteViews
import android.widget.RemoteViewsService import android.widget.RemoteViewsService
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.connections.anilist.Anilist
import ani.dantotsu.settings.saving.PrefManager
import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.util.Logger import ani.dantotsu.util.Logger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import java.io.InputStream import java.io.InputStream
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.URL import java.net.URL
@ -14,59 +26,47 @@ import java.net.URL
class CurrentlyAiringRemoteViewsFactory(private val context: Context) : class CurrentlyAiringRemoteViewsFactory(private val context: Context) :
RemoteViewsService.RemoteViewsFactory { RemoteViewsService.RemoteViewsFactory {
private var widgetItems = mutableListOf<WidgetItem>() private var widgetItems = mutableListOf<WidgetItem>()
private var refreshing = false
private val prefs =
context.getSharedPreferences(CurrentlyAiringWidget.PREFS_NAME, Context.MODE_PRIVATE)
override fun onCreate() { override fun onCreate() {
// 4 items for testing
widgetItems.clear()
Logger.log("CurrentlyAiringRemoteViewsFactory onCreate") Logger.log("CurrentlyAiringRemoteViewsFactory onCreate")
widgetItems = List(4) { fillWidgetItems()
WidgetItem( }
"Show $it",
"$it days $it hours $it minutes", private fun timeUntil(timeUntil: Long): String {
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg" val days = timeUntil / (1000 * 60 * 60 * 24)
) val hours = (timeUntil % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
}.toMutableList() val minutes = ((timeUntil % (1000 * 60 * 60 * 24)) % (1000 * 60 * 60)) / (1000 * 60)
return "$days days $hours hours $minutes minutes"
} }
override fun onDataSetChanged() { override fun onDataSetChanged() {
// 4 items for testing if (refreshing) return
Logger.log("CurrentlyAiringRemoteViewsFactory onDataSetChanged") Logger.log("CurrentlyAiringRemoteViewsFactory onDataSetChanged")
widgetItems.clear() widgetItems.clear()
widgetItems.add( fillWidgetItems()
WidgetItem(
"Show 1", }
"1 day 2 hours 3 minutes",
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg" private fun fillWidgetItems() {
) refreshing = true
) val userId = PrefManager.getVal<String>(PrefName.AnilistUserId)
widgetItems.add( runBlocking(Dispatchers.IO) {
WidgetItem( val upcoming = Anilist.query.getUpcomingAnime(userId)
"Show 2", upcoming.forEach {
"2 days 3 hours 4 minutes", widgetItems.add(
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg" WidgetItem(
) it.userPreferredName,
) timeUntil(it.timeUntilAiring ?: 0),
widgetItems.add( it.cover ?: "",
WidgetItem( it.id
"Show 3", )
"3 days 4 hours 5 minutes", )
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg" }
) refreshing = false
) }
widgetItems.add(
WidgetItem(
"Show 4",
"4 days 5 hours 6 minutes",
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"
)
)
widgetItems.add(
WidgetItem(
"Show 5",
"5 days 6 hours 7 minutes",
"https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg"
)
)
} }
override fun onDestroy() { override fun onDestroy() {
@ -80,12 +80,20 @@ class CurrentlyAiringRemoteViewsFactory(private val context: Context) :
override fun getViewAt(position: Int): RemoteViews { override fun getViewAt(position: Int): RemoteViews {
Logger.log("CurrentlyAiringRemoteViewsFactory getViewAt") Logger.log("CurrentlyAiringRemoteViewsFactory getViewAt")
val item = widgetItems[position] val item = widgetItems[position]
val titleTextColor = prefs.getInt(CurrentlyAiringWidget.PREF_TITLE_TEXT_COLOR, Color.WHITE)
val countdownTextColor =
prefs.getInt(CurrentlyAiringWidget.PREF_COUNTDOWN_TEXT_COLOR, Color.WHITE)
val rv = RemoteViews(context.packageName, R.layout.item_currently_airing_widget).apply { val rv = RemoteViews(context.packageName, R.layout.item_currently_airing_widget).apply {
setTextViewText(R.id.text_show_title, item.title) setTextViewText(R.id.text_show_title, item.title)
setTextViewText(R.id.text_show_countdown, item.countdown) setTextViewText(R.id.text_show_countdown, item.countdown)
setTextColor(R.id.text_show_title, titleTextColor)
setTextColor(R.id.text_show_countdown, countdownTextColor)
val bitmap = downloadImageAsBitmap(item.image) val bitmap = downloadImageAsBitmap(item.image)
//setImageViewUri(R.id.image_show_icon, Uri.parse(item.image))
setImageViewBitmap(R.id.image_show_icon, bitmap) setImageViewBitmap(R.id.image_show_icon, bitmap)
val fillInIntent = Intent().apply {
putExtra("mediaId", item.id)
}
setOnClickFillInIntent(R.id.widget_item, fillInIntent)
} }
return rv return rv
@ -108,16 +116,27 @@ class CurrentlyAiringRemoteViewsFactory(private val context: Context) :
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
// Handle the error according to your needs
} finally { } finally {
// Clean up resources
inputStream?.close() inputStream?.close()
urlConnection?.disconnect() urlConnection?.disconnect()
} }
return bitmap?.let { roundCorners(it) }
return bitmap
} }
private fun roundCorners(bitmap: Bitmap): Bitmap {
val cornerRadius = 20f
val output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
val paint = Paint()
paint.isAntiAlias = true
paint.shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
val rect = RectF(0f, 0f, bitmap.width.toFloat(), bitmap.height.toFloat())
canvas.drawRoundRect(rect, cornerRadius, cornerRadius, paint)
return output
}
override fun getLoadingView(): RemoteViews { override fun getLoadingView(): RemoteViews {
return RemoteViews(context.packageName, R.layout.item_currently_airing_widget) return RemoteViews(context.packageName, R.layout.item_currently_airing_widget)
} }
@ -135,4 +154,4 @@ class CurrentlyAiringRemoteViewsFactory(private val context: Context) :
} }
} }
data class WidgetItem(val title: String, val countdown: String, val image: String) data class WidgetItem(val title: String, val countdown: String, val image: String, val id: Int)

View file

@ -12,7 +12,9 @@ import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable import android.graphics.drawable.GradientDrawable
import android.net.Uri import android.net.Uri
import android.widget.RemoteViews import android.widget.RemoteViews
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import ani.dantotsu.MainActivity
import ani.dantotsu.R import ani.dantotsu.R
/** /**
@ -26,25 +28,15 @@ class CurrentlyAiringWidget : AppWidgetProvider() {
appWidgetIds: IntArray appWidgetIds: IntArray
) { ) {
appWidgetIds.forEach { appWidgetId -> appWidgetIds.forEach { appWidgetId ->
val intent = Intent(context, CurrentlyAiringRemoteViewsService::class.java).apply { val rv = updateAppWidget(context, appWidgetId)
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME))
}
val rv = RemoteViews(context.packageName, R.layout.currently_airing_widget).apply {
setRemoteAdapter(R.id.widgetListView, intent)
setEmptyView(R.id.widgetListView, R.id.empty_view)
}
appWidgetManager.updateAppWidget(appWidgetId, rv) appWidgetManager.updateAppWidget(appWidgetId, rv)
} }
super.onUpdate(context, appWidgetManager, appWidgetIds) super.onUpdate(context, appWidgetManager, appWidgetIds)
} }
override fun onDeleted(context: Context, appWidgetIds: IntArray) { override fun onDeleted(context: Context, appWidgetIds: IntArray) {
// When the user deletes the widget, delete the preference associated with it.
for (appWidgetId in appWidgetIds) { for (appWidgetId in appWidgetIds) {
deleteTitlePref(context, appWidgetId) context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE).edit().clear().apply()
} }
super.onDeleted(context, appWidgetIds) super.onDeleted(context, appWidgetIds)
} }
@ -57,34 +49,65 @@ class CurrentlyAiringWidget : AppWidgetProvider() {
super.onDisabled(context) super.onDisabled(context)
} }
companion object { companion object {
fun updateAppWidget( fun updateAppWidget(
context: Context, context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int, appWidgetId: Int,
color: Int ): RemoteViews {
) { val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
// Create an intent to launch the configuration activity when the widget is clicked val backgroundColor =
val intent = Intent(context, CurrentlyAiringWidgetConfigureActivity::class.java) prefs.getInt(PREF_BACKGROUND_COLOR, ContextCompat.getColor(context, R.color.theme))
val pendingIntent = val backgroundFade = prefs.getInt(PREF_BACKGROUND_FADE, Color.GRAY)
PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) val titleTextColor = prefs.getInt(PREF_TITLE_TEXT_COLOR, Color.WHITE)
val countdownTextColor = prefs.getInt(PREF_COUNTDOWN_TEXT_COLOR, Color.WHITE)
// Get the gradient drawable resource and update its start color with the user-selected color val intent = Intent(context, CurrentlyAiringRemoteViewsService::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME))
}
val gradientDrawable = ResourcesCompat.getDrawable( val gradientDrawable = ResourcesCompat.getDrawable(
context.resources, context.resources,
R.drawable.gradient_background, R.drawable.gradient_background,
null null
) as GradientDrawable ) as GradientDrawable
gradientDrawable.colors = intArrayOf(color, Color.GRAY) // End color is gray. gradientDrawable.colors = intArrayOf(backgroundColor, backgroundFade)
val intentTemplate = Intent(context, MainActivity::class.java)
intentTemplate.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
intentTemplate.putExtra("fromWidget", true)
// Create the RemoteViews object and set the background
val views = RemoteViews(context.packageName, R.layout.currently_airing_widget).apply { val views = RemoteViews(context.packageName, R.layout.currently_airing_widget).apply {
//setImageViewBitmap(R.id.backgroundView, convertDrawableToBitmap(gradientDrawable)) setImageViewBitmap(R.id.backgroundView, convertDrawableToBitmap(gradientDrawable))
//setOnClickPendingIntent(R.id.backgroundView, pendingIntent) setTextColor(R.id.text_show_title, titleTextColor)
setTextColor(R.id.text_show_countdown, countdownTextColor)
setTextColor(R.id.widgetTitle, titleTextColor)
setRemoteAdapter(R.id.widgetListView, intent)
setEmptyView(R.id.widgetListView, R.id.empty_view)
setPendingIntentTemplate(
R.id.widgetListView,
PendingIntent.getActivity(
context,
0,
intentTemplate,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
)
)
setOnClickPendingIntent(
R.id.logoView,
PendingIntent.getActivity(
context,
1,
Intent(context, CurrentlyAiringWidgetConfigureActivity::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
},
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
)
} }
// Instruct the widget manager to update the widget return views
appWidgetManager.updateAppWidget(appWidgetId, views)
} }
private fun convertDrawableToBitmap(drawable: Drawable): Bitmap { private fun convertDrawableToBitmap(drawable: Drawable): Bitmap {
@ -94,6 +117,12 @@ class CurrentlyAiringWidget : AppWidgetProvider() {
drawable.draw(canvas) drawable.draw(canvas)
return bitmap return bitmap
} }
const val PREFS_NAME = "ani.dantotsu.widgets.CurrentlyAiringWidget"
const val PREF_BACKGROUND_COLOR = "background_color"
const val PREF_BACKGROUND_FADE = "background_fade"
const val PREF_TITLE_TEXT_COLOR = "title_text_color"
const val PREF_COUNTDOWN_TEXT_COLOR = "countdown_text_color"
} }
} }
@ -102,11 +131,7 @@ internal fun updateAppWidget(
appWidgetManager: AppWidgetManager, appWidgetManager: AppWidgetManager,
appWidgetId: Int appWidgetId: Int
) { ) {
val widgetText = loadTitlePref(context, appWidgetId) val views = CurrentlyAiringWidget.updateAppWidget(context, appWidgetId)
// Construct the RemoteViews object
val views = RemoteViews(context.packageName, R.layout.currently_airing_widget)
views.setTextViewText(R.id.appwidget_text, widgetText)
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views) appWidgetManager.updateAppWidget(appWidgetId, views)
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widgetListView)
} }

View file

@ -1,42 +1,36 @@
package ani.dantotsu.widgets package ani.dantotsu.widgets
import android.app.Activity
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.widget.EditText import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import ani.dantotsu.R import ani.dantotsu.R
import ani.dantotsu.databinding.CurrentlyAiringWidgetConfigureBinding import ani.dantotsu.databinding.CurrentlyAiringWidgetConfigureBinding
import ani.dantotsu.themes.ThemeManager import ani.dantotsu.themes.ThemeManager
import eltos.simpledialogfragment.SimpleDialog
import eltos.simpledialogfragment.color.SimpleColorDialog
/** /**
* The configuration screen for the [CurrentlyAiringWidget] AppWidget. * The configuration screen for the [CurrentlyAiringWidget] AppWidget.
*/ */
class CurrentlyAiringWidgetConfigureActivity : Activity() { class CurrentlyAiringWidgetConfigureActivity : AppCompatActivity(),
SimpleDialog.OnDialogResultListener {
private var appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID private var appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID
private lateinit var appWidgetText: EditText
private var onClickListener = View.OnClickListener { private var onClickListener = View.OnClickListener {
val context = this@CurrentlyAiringWidgetConfigureActivity val context = this@CurrentlyAiringWidgetConfigureActivity
// When the button is clicked, store the string locally
val widgetText = appWidgetText.text.toString()
saveTitlePref(context, appWidgetId, widgetText)
// It is the responsibility of the configuration activity to update the app widget
val appWidgetManager = AppWidgetManager.getInstance(context) val appWidgetManager = AppWidgetManager.getInstance(context)
//updateAppWidget(context, appWidgetManager, appWidgetId)
updateAppWidget(
CurrentlyAiringWidget.updateAppWidget(
context, context,
appWidgetManager, appWidgetManager,
appWidgetId, appWidgetId,
-1
) )
// Make sure we pass back the original appWidgetId
val resultValue = Intent() val resultValue = Intent()
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
setResult(RESULT_OK, resultValue) setResult(RESULT_OK, resultValue)
@ -45,21 +39,87 @@ class CurrentlyAiringWidgetConfigureActivity : Activity() {
private lateinit var binding: CurrentlyAiringWidgetConfigureBinding private lateinit var binding: CurrentlyAiringWidgetConfigureBinding
public override fun onCreate(icicle: Bundle?) { public override fun onCreate(icicle: Bundle?) {
ThemeManager(this).applyTheme() ThemeManager(this).applyTheme()
super.onCreate(icicle) super.onCreate(icicle)
// Set the result to CANCELED. This will cause the widget host to cancel
// out of the widget placement if the user presses the back button.
setResult(RESULT_CANCELED) setResult(RESULT_CANCELED)
binding = CurrentlyAiringWidgetConfigureBinding.inflate(layoutInflater) binding = CurrentlyAiringWidgetConfigureBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
val prefs = getSharedPreferences(CurrentlyAiringWidget.PREFS_NAME, Context.MODE_PRIVATE)
binding.topBackgroundButton.setOnClickListener {
val tag = CurrentlyAiringWidget.PREF_BACKGROUND_COLOR
SimpleColorDialog().title(R.string.custom_theme)
.colorPreset(
prefs.getInt(
CurrentlyAiringWidget.PREF_BACKGROUND_COLOR,
ContextCompat.getColor(this, R.color.theme)
)
)
.colors(
this@CurrentlyAiringWidgetConfigureActivity,
SimpleColorDialog.MATERIAL_COLOR_PALLET
)
.allowCustom(true)
.showOutline(0x46000000)
.gridNumColumn(5)
.choiceMode(SimpleColorDialog.SINGLE_CHOICE)
.neg()
.show(this@CurrentlyAiringWidgetConfigureActivity, tag)
}
binding.bottomBackgroundButton.setOnClickListener {
val tag = CurrentlyAiringWidget.PREF_BACKGROUND_FADE
SimpleColorDialog().title(R.string.custom_theme)
.colorPreset(prefs.getInt(CurrentlyAiringWidget.PREF_BACKGROUND_FADE, Color.GRAY))
.colors(
this@CurrentlyAiringWidgetConfigureActivity,
SimpleColorDialog.MATERIAL_COLOR_PALLET
)
.allowCustom(true)
.showOutline(0x46000000)
.gridNumColumn(5)
.choiceMode(SimpleColorDialog.SINGLE_CHOICE)
.neg()
.show(this@CurrentlyAiringWidgetConfigureActivity, tag)
}
binding.titleColorButton.setOnClickListener {
val tag = CurrentlyAiringWidget.PREF_TITLE_TEXT_COLOR
SimpleColorDialog().title(R.string.custom_theme)
.colorPreset(prefs.getInt(CurrentlyAiringWidget.PREF_TITLE_TEXT_COLOR, Color.WHITE))
.colors(
this@CurrentlyAiringWidgetConfigureActivity,
SimpleColorDialog.MATERIAL_COLOR_PALLET
)
.allowCustom(true)
.showOutline(0x46000000)
.gridNumColumn(5)
.choiceMode(SimpleColorDialog.SINGLE_CHOICE)
.neg()
.show(this@CurrentlyAiringWidgetConfigureActivity, tag)
}
binding.countdownColorButton.setOnClickListener {
val tag = CurrentlyAiringWidget.PREF_COUNTDOWN_TEXT_COLOR
SimpleColorDialog().title(R.string.custom_theme)
.colorPreset(
prefs.getInt(
CurrentlyAiringWidget.PREF_COUNTDOWN_TEXT_COLOR,
Color.WHITE
)
)
.colors(
this@CurrentlyAiringWidgetConfigureActivity,
SimpleColorDialog.MATERIAL_COLOR_PALLET
)
.allowCustom(true)
.showOutline(0x46000000)
.gridNumColumn(5)
.choiceMode(SimpleColorDialog.SINGLE_CHOICE)
.neg()
.show(this@CurrentlyAiringWidgetConfigureActivity, tag)
}
appWidgetText = binding.appwidgetText
binding.addButton.setOnClickListener(onClickListener) binding.addButton.setOnClickListener(onClickListener)
// Find the widget id from the intent.
val intent = intent val intent = intent
val extras = intent.extras val extras = intent.extras
if (extras != null) { if (extras != null) {
@ -68,43 +128,66 @@ class CurrentlyAiringWidgetConfigureActivity : Activity() {
) )
} }
// If this activity was started with an intent without an app widget ID, finish with an error.
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish() finish()
return return
} }
appWidgetText.setText(
loadTitlePref(
this@CurrentlyAiringWidgetConfigureActivity,
appWidgetId
)
)
} }
} override fun onResult(dialogTag: String, which: Int, extras: Bundle): Boolean {
if (which == SimpleDialog.OnDialogResultListener.BUTTON_POSITIVE) {
when (dialogTag) {
CurrentlyAiringWidget.PREF_BACKGROUND_COLOR -> {
getSharedPreferences(
CurrentlyAiringWidget.PREFS_NAME,
Context.MODE_PRIVATE
).edit()
.putInt(
CurrentlyAiringWidget.PREF_BACKGROUND_COLOR,
extras.getInt(SimpleColorDialog.COLOR)
)
.apply()
}
private const val PREFS_NAME = "ani.dantotsu.parsers.CurrentlyAiringWidget" CurrentlyAiringWidget.PREF_BACKGROUND_FADE -> {
private const val PREF_PREFIX_KEY = "appwidget_" getSharedPreferences(
CurrentlyAiringWidget.PREFS_NAME,
Context.MODE_PRIVATE
).edit()
.putInt(
CurrentlyAiringWidget.PREF_BACKGROUND_FADE,
extras.getInt(SimpleColorDialog.COLOR)
)
.apply()
}
// Write the prefix to the SharedPreferences object for this widget CurrentlyAiringWidget.PREF_TITLE_TEXT_COLOR -> {
internal fun saveTitlePref(context: Context, appWidgetId: Int, text: String) { getSharedPreferences(
val prefs = context.getSharedPreferences(PREFS_NAME, 0).edit() CurrentlyAiringWidget.PREFS_NAME,
prefs.putString(PREF_PREFIX_KEY + appWidgetId, text) Context.MODE_PRIVATE
prefs.apply() ).edit()
} .putInt(
CurrentlyAiringWidget.PREF_TITLE_TEXT_COLOR,
extras.getInt(SimpleColorDialog.COLOR)
)
.apply()
}
// Read the prefix from the SharedPreferences object for this widget. CurrentlyAiringWidget.PREF_COUNTDOWN_TEXT_COLOR -> {
// If there is no preference saved, get the default from a resource getSharedPreferences(
internal fun loadTitlePref(context: Context, appWidgetId: Int): String { CurrentlyAiringWidget.PREFS_NAME,
val prefs = context.getSharedPreferences(PREFS_NAME, 0) Context.MODE_PRIVATE
val titleValue = prefs.getString(PREF_PREFIX_KEY + appWidgetId, null) ).edit()
return titleValue ?: context.getString(R.string.appwidget_text) .putInt(
} CurrentlyAiringWidget.PREF_COUNTDOWN_TEXT_COLOR,
extras.getInt(SimpleColorDialog.COLOR)
)
.apply()
}
}
}
return true
}
internal fun deleteTitlePref(context: Context, appWidgetId: Int) {
val prefs = context.getSharedPreferences(PREFS_NAME, 0).edit()
prefs.remove(PREF_PREFIX_KEY + appWidgetId)
prefs.apply()
} }

View file

@ -4,5 +4,5 @@
<gradient <gradient
android:angle="270" android:angle="270"
android:endColor="@color/grey_20" android:endColor="@color/grey_20"
android:startColor="#B313DC" /> android:startColor="@color/theme"/>
</shape> </shape>

View file

@ -20,8 +20,8 @@
<ImageView <ImageView
android:id="@+id/logoView" android:id="@+id/logoView"
android:layout_width="32dp" android:layout_width="40dp"
android:layout_height="32dp" android:layout_height="40dp"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:foregroundGravity="center_vertical" android:foregroundGravity="center_vertical"
@ -31,20 +31,24 @@
<TextView <TextView
android:id="@+id/widgetTitle" android:id="@+id/widgetTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="40dp"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_marginStart="0dp" android:layout_marginStart="0dp"
android:layout_toEndOf="@+id/logoView" android:layout_toEndOf="@+id/logoView"
android:gravity="center_vertical" android:gravity="center_vertical|start"
android:textAlignment="viewStart"
android:maxLines="1"
android:ellipsize="end"
android:text="@string/currently_airing" android:text="@string/currently_airing"
android:textSize="18sp" android:textSize="20sp"
android:textStyle="bold" /> android:textStyle="bold" />
<ListView <ListView
android:id="@+id/widgetListView" android:id="@+id/widgetListView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scrollbars="none"
android:layout_below="@id/widgetTitle" /> android:layout_below="@id/widgetTitle" />
<TextView <TextView
@ -52,6 +56,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center" android:gravity="center"
android:maxLines="1"
android:ellipsize="end"
android:text="@string/no_shows_to_display" android:text="@string/no_shows_to_display"
android:textColor="#ffffff" android:textColor="#ffffff"
android:textSize="20sp" android:textSize="20sp"

View file

@ -2,6 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:orientation="vertical"
android:padding="16dp"> android:padding="16dp">
@ -9,14 +10,103 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:labelFor="@id/appwidget_text"
android:text="@string/configure" /> android:text="@string/configure" />
<EditText <Button
android:id="@+id/appwidget_text" android:id="@+id/topBackgroundButton"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="64dp"
android:inputType="text" /> android:layout_marginStart="-31dp"
android:layout_marginEnd="-31dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingStart="31dp"
android:paddingEnd="31dp"
android:text="@string/top_background_color"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_round_color_picker_24"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<Button
android:id="@+id/bottomBackgroundButton"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="-31dp"
android:layout_marginEnd="-31dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingStart="31dp"
android:paddingEnd="31dp"
android:text="@string/bottom_background_color"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_round_color_picker_24"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<Button
android:id="@+id/titleColorButton"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="-31dp"
android:layout_marginEnd="-31dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingStart="31dp"
android:paddingEnd="31dp"
android:text="@string/title_color"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_round_color_picker_24"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<Button
android:id="@+id/countdownColorButton"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="-31dp"
android:layout_marginEnd="-31dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingStart="31dp"
android:paddingEnd="31dp"
android:text="@string/countdown_text_color"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_round_color_picker_24"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<Button <Button
android:id="@+id/add_button" android:id="@+id/add_button"

View file

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_item"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal" android:orientation="horizontal"
android:padding="8dp"> android:padding="8dp">
@ -9,9 +11,10 @@
<ImageView <ImageView
android:id="@+id/image_show_icon" android:id="@+id/image_show_icon"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="wrap_content"
android:contentDescription="@string/airing_image" app:shapeAppearanceOverlay="@style/roundedImageView"
android:src="@drawable/ic_launcher_foreground" /> android:contentDescription="@string/airing_image"/>
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
@ -25,8 +28,10 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="@font/poppins_bold" android:fontFamily="@font/poppins_bold"
android:text="Placeholder Title" android:text=""
android:textColor="@color/bg_white" android:textColor="@color/bg_white"
android:maxLines="3"
android:ellipsize="end"
android:textSize="16sp" /> android:textSize="16sp" />
<TextView <TextView
@ -34,8 +39,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="@font/poppins" android:fontFamily="@font/poppins"
android:text="Placeholder Countdown" android:text=""
android:textColor="@color/grey_60" android:textColor="@color/bg_white"
android:textSize="14sp" /> android:textSize="14sp" />
</LinearLayout> </LinearLayout>

View file

@ -19,6 +19,7 @@
<color name="button_icon">#A9FFFFFF</color> <color name="button_icon">#A9FFFFFF</color>
<color name="nav_status">#80FFFFFF</color> <color name="nav_status">#80FFFFFF</color>
<color name="fav">#ad5edd</color> <color name="fav">#ad5edd</color>
<color name="theme">#B313DC</color>
<color name="incognito">#291B65</color> <color name="incognito">#291B65</color>
<color name="filler">#54FF8400</color> <color name="filler">#54FF8400</color>
<color name="warning">#FF0000</color> <color name="warning">#FF0000</color>

View file

@ -11,7 +11,7 @@
<string name="discord" translatable="false">https://discord.gg/4HPZ5nAWwM</string> <string name="discord" translatable="false">https://discord.gg/4HPZ5nAWwM</string>
<string name="github" translatable="false">https://github.com/rebelonion/Dantotsu</string> <string name="github" translatable="false">https://github.com/rebelonion/Dantotsu</string>
<string name="telegram" tools:ignore="Typos" translatable="false">https://t.me/+gzBCQExtLQo1YTNh </string> <string name="telegram" translatable="false" tools:ignore="Typos">https://t.me/+gzBCQExtLQo1YTNh </string>
<string name="coffee" translatable="false">https://www.buymeacoffee.com/rebelonion</string> <string name="coffee" translatable="false">https://www.buymeacoffee.com/rebelonion</string>
<string name="home">Home</string> <string name="home">Home</string>
@ -811,4 +811,9 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc
<string name="donate">donate :)</string> <string name="donate">donate :)</string>
<string name="do_it">Do it!</string> <string name="do_it">Do it!</string>
<string name="password">Password</string> <string name="password">Password</string>
<string name="top_background_color">Top background color</string>
<string name="bottom_background_color">Bottom Background Color</string>
<string name="countdown_text_color">Countdown Text Color</string>
<string name="title_color">Title Color</string>
<string name="placeholder">Placeholder</string>
</resources> </resources>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/app_widget_description" android:description="@string/app_widget_description"
android:configure="ani.dantotsu.widgets.CurrentlyAiringWidgetConfigureActivity"
android:initialKeyguardLayout="@layout/currently_airing_widget" android:initialKeyguardLayout="@layout/currently_airing_widget"
android:initialLayout="@layout/currently_airing_widget" android:initialLayout="@layout/currently_airing_widget"
android:minWidth="160dp" android:minWidth="160dp"
@ -8,7 +9,5 @@
android:previewImage="@drawable/example_appwidget_preview" android:previewImage="@drawable/example_appwidget_preview"
android:previewLayout="@layout/currently_airing_widget" android:previewLayout="@layout/currently_airing_widget"
android:resizeMode="horizontal|vertical" android:resizeMode="horizontal|vertical"
android:targetCellWidth="1" android:updatePeriodMillis="3600000"
android:targetCellHeight="1" android:widgetCategory="home_screen"/>
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen"></appwidget-provider>

View file

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/app_widget_description" android:description="@string/app_widget_description"
android:configure="ani.dantotsu.widgets.CurrentlyAiringWidgetConfigureActivity"
android:initialKeyguardLayout="@layout/currently_airing_widget" android:initialKeyguardLayout="@layout/currently_airing_widget"
android:initialLayout="@layout/currently_airing_widget" android:initialLayout="@layout/currently_airing_widget"
android:minWidth="160dp" android:minWidth="160dp"
android:minHeight="160dp" android:minHeight="160dp"
android:previewImage="@drawable/example_appwidget_preview" android:previewImage="@drawable/example_appwidget_preview"
android:resizeMode="horizontal|vertical" android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000" android:updatePeriodMillis="3600000"
android:widgetCategory="home_screen"></appwidget-provider> android:widgetCategory="home_screen"/>