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?

Nuvious
sumber

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);
phaethon.dll
sumber
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);
Terjebak
sumber
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 :)

Kode Void
sumber
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);
Oleg Tarashkevich
sumber
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.

thanhtd
sumber
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);
}
Jakob Eriksson
sumber
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() {

Elletlar
sumber
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)
gareoke
sumber