-
-
Notifications
You must be signed in to change notification settings - Fork 112
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
82bc215
commit b6be707
Showing
23 changed files
with
681 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
app/src/main/java/ani/dantotsu/widgets/CurrentlyAiringRemoteViewsFactory.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package ani.dantotsu.widgets | ||
|
||
import android.content.Context | ||
import android.content.Intent | ||
import android.graphics.Bitmap | ||
import android.graphics.BitmapFactory | ||
import android.net.Uri | ||
import android.widget.RemoteViews | ||
import android.widget.RemoteViewsService | ||
import androidx.core.net.toUri | ||
import ani.dantotsu.R | ||
import ani.dantotsu.logger | ||
import java.io.InputStream | ||
import java.net.HttpURLConnection | ||
import java.net.URL | ||
|
||
class CurrentlyAiringRemoteViewsFactory(private val context: Context, intent: Intent) : RemoteViewsService.RemoteViewsFactory { | ||
private var widgetItems = mutableListOf<WidgetItem>() | ||
|
||
override fun onCreate() { | ||
// 4 items for testing | ||
widgetItems.clear() | ||
logger("CurrentlyAiringRemoteViewsFactory onCreate") | ||
widgetItems = List(4) { | ||
WidgetItem("Show $it", "$it days $it hours $it minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg") | ||
}.toMutableList() | ||
} | ||
|
||
override fun onDataSetChanged() { | ||
// 4 items for testing | ||
logger("CurrentlyAiringRemoteViewsFactory onDataSetChanged") | ||
widgetItems.clear() | ||
widgetItems.add(WidgetItem("Show 1", "1 day 2 hours 3 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg")) | ||
widgetItems.add(WidgetItem("Show 2", "2 days 3 hours 4 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg")) | ||
widgetItems.add(WidgetItem("Show 3", "3 days 4 hours 5 minutes", "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx14741-alxqoP4yx6WF.jpg")) | ||
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() { | ||
widgetItems.clear() | ||
} | ||
|
||
override fun getCount(): Int { | ||
return widgetItems.size | ||
} | ||
|
||
override fun getViewAt(position: Int): RemoteViews { | ||
logger("CurrentlyAiringRemoteViewsFactory getViewAt") | ||
val item = widgetItems[position] | ||
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_countdown, item.countdown) | ||
val bitmap = downloadImageAsBitmap(item.image) | ||
//setImageViewUri(R.id.image_show_icon, Uri.parse(item.image)) | ||
setImageViewBitmap(R.id.image_show_icon, bitmap) | ||
} | ||
|
||
return rv | ||
} | ||
|
||
private fun downloadImageAsBitmap(imageUrl: String): Bitmap? { | ||
var bitmap: Bitmap? = null | ||
var inputStream: InputStream? = null | ||
var urlConnection: HttpURLConnection? = null | ||
|
||
try { | ||
val url = URL(imageUrl) | ||
urlConnection = url.openConnection() as HttpURLConnection | ||
urlConnection.requestMethod = "GET" | ||
urlConnection.connect() | ||
|
||
if (urlConnection.responseCode == HttpURLConnection.HTTP_OK) { | ||
inputStream = urlConnection.inputStream | ||
bitmap = BitmapFactory.decodeStream(inputStream) | ||
} | ||
} catch (e: Exception) { | ||
e.printStackTrace() | ||
// Handle the error according to your needs | ||
} finally { | ||
// Clean up resources | ||
inputStream?.close() | ||
urlConnection?.disconnect() | ||
} | ||
|
||
return bitmap | ||
} | ||
|
||
override fun getLoadingView(): RemoteViews { | ||
return RemoteViews(context.packageName, R.layout.item_currently_airing_widget) | ||
} | ||
|
||
override fun getViewTypeCount(): Int { | ||
return 1 | ||
} | ||
|
||
override fun getItemId(p0: Int): Long { | ||
return p0.toLong() | ||
} | ||
|
||
override fun hasStableIds(): Boolean { | ||
return true | ||
} | ||
} | ||
|
||
data class WidgetItem(val title: String, val countdown: String, val image: String) |
11 changes: 11 additions & 0 deletions
11
app/src/main/java/ani/dantotsu/widgets/CurrentlyAiringRemoteViewsService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package ani.dantotsu.widgets | ||
|
||
import android.content.Intent | ||
import android.widget.RemoteViewsService | ||
import ani.dantotsu.logger | ||
class CurrentlyAiringRemoteViewsService : RemoteViewsService() { | ||
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory { | ||
logger("CurrentlyAiringRemoteViewsFactory onGetViewFactory") | ||
return CurrentlyAiringRemoteViewsFactory(applicationContext, intent) | ||
} | ||
} |
101 changes: 101 additions & 0 deletions
101
app/src/main/java/ani/dantotsu/widgets/CurrentlyAiringWidget.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package ani.dantotsu.widgets | ||
|
||
import android.app.PendingIntent | ||
import android.appwidget.AppWidgetManager | ||
import android.appwidget.AppWidgetProvider | ||
import android.content.Context | ||
import android.content.Intent | ||
import android.graphics.Bitmap | ||
import android.graphics.Canvas | ||
import android.graphics.Color | ||
import android.graphics.drawable.Drawable | ||
import android.graphics.drawable.GradientDrawable | ||
import android.net.Uri | ||
import android.widget.RemoteViews | ||
import androidx.core.content.res.ResourcesCompat | ||
import ani.dantotsu.R | ||
|
||
/** | ||
* Implementation of App Widget functionality. | ||
* App Widget Configuration implemented in [CurrentlyAiringWidgetConfigureActivity] | ||
*/ | ||
class CurrentlyAiringWidget : AppWidgetProvider() { | ||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { | ||
appWidgetIds.forEach { appWidgetId -> | ||
val intent = Intent(context, CurrentlyAiringRemoteViewsService::class.java).apply { | ||
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) | ||
} | ||
super.onUpdate(context, appWidgetManager, appWidgetIds) | ||
} | ||
override fun onDeleted(context: Context, appWidgetIds: IntArray) { | ||
// When the user deletes the widget, delete the preference associated with it. | ||
for (appWidgetId in appWidgetIds) { | ||
deleteTitlePref(context, appWidgetId) | ||
} | ||
super.onDeleted(context, appWidgetIds) | ||
} | ||
|
||
override fun onEnabled(context: Context) { | ||
super.onEnabled(context) | ||
} | ||
|
||
override fun onDisabled(context: Context) { | ||
super.onDisabled(context) | ||
} | ||
companion object { | ||
fun updateAppWidget( | ||
context: Context, | ||
appWidgetManager: AppWidgetManager, | ||
appWidgetId: Int, | ||
color: Int | ||
) { | ||
// Create an intent to launch the configuration activity when the widget is clicked | ||
val intent = Intent(context, CurrentlyAiringWidgetConfigureActivity::class.java) | ||
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) | ||
|
||
// Get the gradient drawable resource and update its start color with the user-selected color | ||
val gradientDrawable = ResourcesCompat.getDrawable(context.resources, R.drawable.gradient_background, null) as GradientDrawable | ||
gradientDrawable.colors = intArrayOf(color, Color.GRAY) // End color is gray. | ||
|
||
// Create the RemoteViews object and set the background | ||
val views = RemoteViews(context.packageName, R.layout.currently_airing_widget).apply { | ||
//setImageViewBitmap(R.id.backgroundView, convertDrawableToBitmap(gradientDrawable)) | ||
//setOnClickPendingIntent(R.id.backgroundView, pendingIntent) | ||
} | ||
|
||
// Instruct the widget manager to update the widget | ||
appWidgetManager.updateAppWidget(appWidgetId, views) | ||
} | ||
|
||
private fun convertDrawableToBitmap(drawable: Drawable): Bitmap { | ||
val bitmap = Bitmap.createBitmap(100, 300, Bitmap.Config.ARGB_8888) | ||
val canvas = Canvas(bitmap) | ||
drawable.setBounds(0, 0, canvas.width, canvas.height) | ||
drawable.draw(canvas) | ||
return bitmap | ||
} | ||
} | ||
} | ||
|
||
internal fun updateAppWidget( | ||
context: Context, | ||
appWidgetManager: AppWidgetManager, | ||
appWidgetId: Int | ||
) { | ||
val widgetText = loadTitlePref(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) | ||
} |
111 changes: 111 additions & 0 deletions
111
app/src/main/java/ani/dantotsu/widgets/CurrentlyAiringWidgetConfigureActivity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package ani.dantotsu.widgets | ||
|
||
import android.app.Activity | ||
import android.appwidget.AppWidgetManager | ||
import android.content.Context | ||
import android.content.Intent | ||
import android.os.Bundle | ||
import android.view.View | ||
import android.widget.EditText | ||
import ani.dantotsu.R | ||
import ani.dantotsu.databinding.CurrentlyAiringWidgetConfigureBinding | ||
import ani.dantotsu.others.LangSet | ||
import ani.dantotsu.themes.ThemeManager | ||
|
||
/** | ||
* The configuration screen for the [CurrentlyAiringWidget] AppWidget. | ||
*/ | ||
class CurrentlyAiringWidgetConfigureActivity : Activity() { | ||
private var appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID | ||
private lateinit var appWidgetText: EditText | ||
private var onClickListener = View.OnClickListener { | ||
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) | ||
//updateAppWidget(context, appWidgetManager, appWidgetId) | ||
|
||
|
||
CurrentlyAiringWidget.updateAppWidget( | ||
context, | ||
appWidgetManager, | ||
appWidgetId, | ||
-1 | ||
) | ||
|
||
// Make sure we pass back the original appWidgetId | ||
val resultValue = Intent() | ||
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) | ||
setResult(RESULT_OK, resultValue) | ||
finish() | ||
} | ||
private lateinit var binding: CurrentlyAiringWidgetConfigureBinding | ||
|
||
public override fun onCreate(icicle: Bundle?) { | ||
LangSet.setLocale(this) | ||
ThemeManager(this).applyTheme() | ||
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) | ||
|
||
binding = CurrentlyAiringWidgetConfigureBinding.inflate(layoutInflater) | ||
setContentView(binding.root) | ||
|
||
appWidgetText = binding.appwidgetText as EditText | ||
binding.addButton.setOnClickListener(onClickListener) | ||
|
||
// Find the widget id from the intent. | ||
val intent = intent | ||
val extras = intent.extras | ||
if (extras != null) { | ||
appWidgetId = extras.getInt( | ||
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID | ||
) | ||
} | ||
|
||
// If this activity was started with an intent without an app widget ID, finish with an error. | ||
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { | ||
finish() | ||
return | ||
} | ||
|
||
appWidgetText.setText( | ||
loadTitlePref( | ||
this@CurrentlyAiringWidgetConfigureActivity, | ||
appWidgetId | ||
) | ||
) | ||
|
||
} | ||
|
||
} | ||
|
||
private const val PREFS_NAME = "ani.dantotsu.parsers.CurrentlyAiringWidget" | ||
private const val PREF_PREFIX_KEY = "appwidget_" | ||
|
||
// Write the prefix to the SharedPreferences object for this widget | ||
internal fun saveTitlePref(context: Context, appWidgetId: Int, text: String) { | ||
val prefs = context.getSharedPreferences(PREFS_NAME, 0).edit() | ||
prefs.putString(PREF_PREFIX_KEY + appWidgetId, text) | ||
prefs.apply() | ||
} | ||
|
||
// Read the prefix from the SharedPreferences object for this widget. | ||
// If there is no preference saved, get the default from a resource | ||
internal fun loadTitlePref(context: Context, appWidgetId: Int): String { | ||
val prefs = context.getSharedPreferences(PREFS_NAME, 0) | ||
val titleValue = prefs.getString(PREF_PREFIX_KEY + appWidgetId, null) | ||
return titleValue ?: context.getString(R.string.appwidget_text) | ||
} | ||
|
||
internal fun deleteTitlePref(context: Context, appWidgetId: Int) { | ||
val prefs = context.getSharedPreferences(PREFS_NAME, 0).edit() | ||
prefs.remove(PREF_PREFIX_KEY + appWidgetId) | ||
prefs.apply() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?xml version="1.0" encoding="utf-8"?><!-- | ||
Background for widgets to make the rounded corners based on the | ||
appWidgetRadius attribute value | ||
--> | ||
<shape xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:shape="rectangle"> | ||
|
||
<corners android:radius="?attr/appWidgetRadius" /> | ||
<solid android:color="?android:attr/colorBackground" /> | ||
</shape> |
10 changes: 10 additions & 0 deletions
10
app/src/main/res/drawable-v21/app_widget_inner_view_background.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?xml version="1.0" encoding="utf-8"?><!-- | ||
Background for views inside widgets to make the rounded corners based on the | ||
appWidgetInnerRadius attribute value | ||
--> | ||
<shape xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:shape="rectangle"> | ||
|
||
<corners android:radius="?attr/appWidgetInnerRadius" /> | ||
<solid android:color="?android:attr/colorAccent" /> | ||
</shape> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<shape xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:shape="rectangle"> | ||
<gradient | ||
android:angle="270" | ||
android:endColor="@color/grey_20" | ||
android:startColor="#B313DC" /> | ||
</shape> |
Oops, something went wrong.