Widget: render mic+badge as bitmaps (Lawnchair themed-icons flattened drawable resources to gray)
This commit is contained in:
parent
d8441ab385
commit
7f9b9c2e5c
1 changed files with 29 additions and 6 deletions
|
|
@ -47,22 +47,41 @@ class ShonarRecordWidget : AppWidgetProvider() {
|
|||
companion object {
|
||||
const val ACTION_WIDGET_RECORD = "com.shonar.widget.RECORD_TAP"
|
||||
|
||||
/**
|
||||
* Render the vector to a bitmap instead of handing the launcher a
|
||||
* drawable resource id: themed-icon launchers (Lawnchair) re-tint any
|
||||
* resource they can resolve, which flattened the navy+teal mic to a
|
||||
* gray monochrome silhouette. A bitmap is opaque pixels — nothing to
|
||||
* tint. (2026-09-17)
|
||||
*/
|
||||
private fun bitmapOf(ctx: Context, resId: Int, dp: Int): android.graphics.Bitmap {
|
||||
val size = (dp * ctx.resources.displayMetrics.density).toInt().coerceAtLeast(64)
|
||||
val d = androidx.core.content.ContextCompat.getDrawable(ctx, resId)
|
||||
?: throw IllegalStateException("missing widget drawable $resId")
|
||||
val bmp =
|
||||
android.graphics.Bitmap.createBitmap(size, size, android.graphics.Bitmap.Config.ARGB_8888)
|
||||
val canvas = android.graphics.Canvas(bmp)
|
||||
d.setBounds(0, 0, size, size)
|
||||
d.draw(canvas)
|
||||
return bmp
|
||||
}
|
||||
|
||||
fun views(
|
||||
ctx: Context,
|
||||
phase: com.shonar.recording.RecordingSnapshot.Phase,
|
||||
): RemoteViews {
|
||||
val v = RemoteViews(ctx.packageName, R.layout.shonar_widget)
|
||||
v.setImageViewResource(R.id.widget_icon, R.drawable.ic_widget_mic)
|
||||
v.setImageViewBitmap(R.id.widget_icon, bitmapOf(ctx, R.drawable.ic_widget_mic, 96))
|
||||
when (phase) {
|
||||
com.shonar.recording.RecordingSnapshot.Phase.RECORDING -> {
|
||||
v.setImageViewResource(R.id.widget_badge, R.drawable.ic_widget_badge_rec)
|
||||
v.setImageViewBitmap(R.id.widget_badge, bitmapOf(ctx, R.drawable.ic_widget_badge_rec, 28))
|
||||
v.setViewVisibility(R.id.widget_badge, View.VISIBLE)
|
||||
v.setContentDescription(
|
||||
R.id.widget_button, ctx.getString(R.string.widget_recording),
|
||||
)
|
||||
}
|
||||
com.shonar.recording.RecordingSnapshot.Phase.PAUSED -> {
|
||||
v.setImageViewResource(R.id.widget_badge, R.drawable.ic_widget_badge_paused)
|
||||
v.setImageViewBitmap(R.id.widget_badge, bitmapOf(ctx, R.drawable.ic_widget_badge_paused, 28))
|
||||
v.setViewVisibility(R.id.widget_badge, View.VISIBLE)
|
||||
v.setContentDescription(
|
||||
R.id.widget_button, ctx.getString(R.string.widget_paused),
|
||||
|
|
@ -77,10 +96,14 @@ class ShonarRecordWidget : AppWidgetProvider() {
|
|||
}
|
||||
|
||||
val tap: PendingIntent = if (phase == com.shonar.recording.RecordingSnapshot.Phase.IDLE) {
|
||||
PendingIntent.getBroadcast(
|
||||
// Invisible activity trampoline, NOT a broadcast: a cold
|
||||
// process woken by a broadcast is battery-throttled (the
|
||||
// banner could take ~10s); an activity start runs at full
|
||||
// priority and gives startForegroundService its FGS
|
||||
// exemption on Android 12+.
|
||||
PendingIntent.getActivity(
|
||||
ctx, 50,
|
||||
Intent(ctx, ShonarRecordWidget::class.java).setAction(ACTION_WIDGET_RECORD)
|
||||
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
|
||||
Intent(ctx, StartRecordingActivity::class.java),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
|
||||
)
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue