Memperbarui widget secara terprogram dari aktivitas / layanan / penerima


97

Saya tahu itu mungkin, tetapi saya tidak tahu cara untuk memicu pembaruan widget saya dari aktivitas utama. Apakah tidak ada maksud umum yang bisa saya siarkan?

Jawaban:


191

Jika Anda sedang menggunakan AppWidgetProvider, Anda dapat memperbaruinya dengan cara ini:

Intent intent = new Intent(this, MyAppWidgetProvider.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(getApplication())
    .getAppWidgetI‌​ds(new ComponentName(getApplication(), MyAppWidgetProvider.class));
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
sendBroadcast(intent);

30
Di mana Anda mengatur widgetId?
Kris B

38
@KrisB dari jawaban di bawah ini, dapatkan array dengan melakukan ini: int ids [] = AppWidgetManager.getInstance (getApplication ()). GetAppWidgetIds (new ComponentName (getApplication (), WidgetProvider.class));
MobileM

11
Anda dapat menggunakan konstanta, tidak perlu hardcode:intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
Mārtiņš Briedis

3
JANGAN ikuti komentar @gelupa untuk menggunakan R.xml.mywidget untuk widgetID! Ini SEPENUHNYA salah dan saya hanya membutuhkan 4 jam debugging !!! GUNAKAN solusi MobileMon untuk mendapatkan widgetID yang benar
Ilja S.

5
untuk id: `int widgetIDs [] = AppWidgetManager.getInstance (activity) .getAppWidgetIds (new ComponentName (activity, widget.class));`
abbasalim

75

Ini membantu ketika saya mencari tentang cara memperbarui widget dari layanan / atau tindakan (tetapi mungkin dari setiap Konteks):

Context context = this;
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_2x1);
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
remoteViews.setTextViewText(R.id.my_text_view, "myText" + System.currentTimeMillis());
appWidgetManager.updateAppWidget(thisWidget, remoteViews);

Saya tahu saya melompat ke sini seperti terlambat 6 bulan. Tapi saya setuju dengan Andrew. Saya mencoba metode asli di utas ini. Dan sesuatu tentang bagaimana ID diambil menyebabkannya mulai gagal. Metode ini (memperbarui bidang secara manual secara langsung) bekerja lebih baik. Setidaknya untuk tujuan saya.
durbnpoisn

Hal-hal mengagumkan. Tidak tahu bagaimana Anda berakhir dengan ini tetapi berfungsi dengan baik dan lancar untuk semua contoh Widget saya. :)
Atul O Holic

ini berhasil untuk saya juga. Saya pikir kami perlu melakukan broadcast dan onReceive, tetapi persyaratan saya sangat cocok dengan ini
stingray_

30

Jadi untuk memperbarui widget dari suatu aktivitas, Anda dapat melakukannya seperti ini:

Intent intent = new Intent(this, DppWidget.class);
intent.setAction("android.appwidget.action.APPWIDGET_UPDATE");
int ids[] = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), DppWidget.class));
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,ids);
sendBroadcast(intent);

Bekerja untuk saya :)


Ini memanggil metode penggantian onRecieve. Tetapi saya ingin cara memanggil metode onUpdate.
Amit Thaper

25

Coba ini:

int[] ids = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), MyWidget.class));
        MyWidget myWidget = new MyWidget();
        myWidget.onUpdate(this, AppWidgetManager.getInstance(this),ids);

2
Hebatnya, hanya jawaban kecil ini yang menyelesaikannya. Saya masih tidak tahu implikasi dari membuat instance kelas Widget dan secara langsung memanggil metode onUpdate, tapi hei, akhirnya berhasil :)
Henrique de Sousa

1
Terima kasih. Saya sedang mengujinya sekarang dan akan mengirimkan umpan balik. Diuji dan dikonfirmasi bekerja. Saya bertanya-tanya, jika ada berbagai jenis widget, apakah akan berfungsi sama? (+1 omong-omong untuk bekerja)
Si8

saya selalu mendapatkan id 0
omor

Ini tidak akan berfungsi di Android Oreo, ada perbaikan solusi?
stuckedoverflow

15

Jika Anda bekerja dengan widget yang menggunakan koleksi seperti ListView, GridView, atau StackView, untuk memperbarui item widget, lakukan hal berikut:

Context context = getApplicationContext();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisWidget = new ComponentName(context, StackWidgetProvider.class);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.stack_view);

Dengan metode notifyAppWidgetViewDataChanged () ini, Anda bisa memaksa item widget untuk mengambil data baru apa pun secara real time.


12
int widgetIDs[] = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), WidgetProvider.class));

for (int id : widgetIDs)
    AppWidgetManager.getInstance(getApplication()).notifyAppWidgetViewDataChanged(id, R.id.widget_view);
}

1
Membutuhkan min-api level: 11.
Anirudh Ramanathan

Hebat. Anda bahkan tidak perlu melakukan loop, ada versi notifyAppWidgetViewDataChanged()yang membutuhkan array.
Lawrence Kesteloot

2

Solusi yang diterima Phaethon di Kotlin:

    val intent = Intent(this, MyAppWidgetProvider::class.java)
    intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
    val ids = AppWidgetManager.getInstance(application).getAppWidgetIds(ComponentName(getApplicationContext(),MyAppWidgetProvider::class.java!!))
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
    sendBroadcast(intent)

Di mana MyAppWidgetProvider berasal dari AppWidgetProvider:
class MyAppWidgetProvider : AppWidgetProvider() {


2

Jika Anda mencoba memperbarui widget secara terprogram di mana Anda tidak memiliki akses ke YourWidgetProvider.class secara eksplisit, misalnya dari modul atau pustaka lain, Anda dapat menangkap apa yang dihasilkan YourWidgetProvider.class.getName () dan membuat konstanta:

val WIDGET_CLASS_NAME = "com.example.yourapplication.YourWidgetProvider"

Anda kemudian akan dapat menggunakan ini secara implisit:

val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE)
val widgetManager = AppWidgetManager.getInstance(context)
val ids = widgetManager.getAppWidgetIds(ComponentName(context, WIDGET_CLASS_NAME))
AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(ids, android.R.id.list)
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
context.sendBroadcast(intent)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.