อัปเดตวิดเจ็ตโดยใช้โปรแกรมจากกิจกรรม / บริการ / ผู้รับ


97

ฉันรู้ว่าเป็นไปได้ แต่ฉันไม่สามารถหาวิธีเรียกการอัปเดตวิดเจ็ตของฉันจากกิจกรรมหลักได้ ไม่มีเจตนาทั่วไปที่ฉันสามารถออกอากาศได้หรือไม่?

คำตอบ:


192

หากคุณกำลังใช้AppWidgetProviderคุณสามารถปรับปรุงมันด้วยวิธีนี้:

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
ตั้งตรงwidgetIdไหน?
Kris B

38
@KrisB จากคำตอบด้านล่างรับอาร์เรย์โดยทำดังนี้: int ids [] = AppWidgetManager.getInstance (getApplication ()). getAppWidgetIds (ComponentName ใหม่ (getApplication (), WidgetProvider.class));
MobileMon

11
คุณสามารถใช้ค่าคงที่โดยไม่จำเป็นต้องฮาร์ดโค้ด:intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
Mārtiņš Briedis

3
อย่าทำตามความคิดเห็น @gelupa เพื่อใช้ R.xml.mywidget สำหรับ widgetID! มันผิดอย่างสมบูรณ์และเสียค่าใช้จ่ายในการแก้จุดบกพร่อง 4 ชั่วโมง !!! ใช้โซลูชัน MobileMon เพื่อรับ widgetID ที่ถูกต้อง
Ilja S.

5
สำหรับ ids: `int widgetIDs [] = AppWidgetManager.getInstance (activity) .getAppWidgetIds (ComponentName ใหม่ (activity, widget.class));`
abbasalim

77

สิ่งนี้ช่วยได้เมื่อฉันค้นหาวิธีอัปเดตวิดเจ็ตจากบริการ / หรือการดำเนินการ (แต่อาจเป็นไปได้จากทุกบริบท):

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);

ฉันรู้ว่าฉันกระโดดเข้ามาที่นี่เหมือนช้าไป 6 เดือน แต่ฉันเห็นด้วยกับแอนดรูว์ ฉันลองวิธีการดั้งเดิมในหัวข้อนี้ และบางอย่างเกี่ยวกับวิธีการคว้า ID ทำให้เริ่มล้มเหลว วิธีนี้ (ในการอัปเดตฟิลด์โดยตรงด้วยตนเอง) ทำงานได้ดีขึ้น สำหรับวัตถุประสงค์ของฉันอย่างน้อย
durbnpoisn

สิ่งที่ยอดเยี่ยม ไม่รู้ว่าคุณลงเอยด้วยสิ่งนี้ได้อย่างไร แต่ใช้งานได้ดีและราบรื่นสำหรับทุกอินสแตนซ์ของวิดเจ็ตของฉัน :)
Atul O Holic

สิ่งนี้ได้ผลสำหรับฉันเช่นกัน ฉันคิดว่าเราจะต้องออกอากาศและ onReceive แต่ความต้องการของฉันพอดีกับสิ่งนี้อย่างสมบูรณ์
ปลากระเบน

30

ดังนั้นในการอัปเดตวิดเจ็ตจากกิจกรรมคุณสามารถทำได้ดังนี้:

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);

ใช้ได้ผลสำหรับฉัน :)


มันเรียกเมธอด onRecieve override แต่ฉันต้องการวิธีเรียกใช้เมธอด onUpdate
Amit Thaper

25

ลองสิ่งนี้:

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

2
น่าประหลาดใจที่คำตอบเพียงเล็กน้อยนี้เท่านั้นที่แก้ไข ฉันยังไม่ทราบผลของการสร้างอินสแตนซ์คลาส Widget และเรียกใช้เมธอด onUpdate โดยตรง แต่เดี๋ยวก่อนมันก็ใช้งานได้ในที่สุด :)
Henrique de Sousa

1
ขอบคุณ. ตอนนี้ฉันกำลังทดสอบและจะโพสต์ความคิดเห็น ผ่านการทดสอบและยืนยันการทำงาน ฉันสงสัยว่าถ้ามีวิดเจ็ตประเภทต่างๆจะใช้งานได้เหมือนกันหรือไม่? (+1 โดยวิธีการทำงาน)
Si8

ฉันได้รับรหัสเสมอ 0
omor

สิ่งนี้จะใช้ไม่ได้กับ Android Oreo การแก้ไขปัญหาใด ๆ ?
stuckedoverflow

15

ในกรณีที่คุณกำลังทำงานกับวิดเจ็ตที่ใช้คอลเล็กชันเช่น ListView, GridView หรือ StackView เพื่ออัปเดตไอเท็มของวิดเจ็ตให้ทำดังต่อไปนี้:

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);

ด้วยวิธีนี้ alertAppWidgetViewDataChanged () คุณสามารถบังคับให้รายการวิดเจ็ตดึงข้อมูลใหม่แบบเรียลไทม์


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
ต้องการระดับ min-api: 11.
Anirudh Ramanathan

น่ากลัว คุณไม่จำเป็นต้องวนซ้ำมีรุ่นnotifyAppWidgetViewDataChanged()ที่ใช้อาร์เรย์
Lawrence Kesteloot

2

โซลูชันที่ได้รับการยอมรับของ Phaethon ใน 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)

โดยที่ MyAppWidgetProvider มาจาก AppWidgetProvider:
class MyAppWidgetProvider : AppWidgetProvider() {


2

หากคุณกำลังพยายามอัปเดตวิดเจ็ตโดยใช้โปรแกรมโดยที่คุณไม่มีสิทธิ์เข้าถึง YourWidgetProvider.class อย่างชัดเจนเช่นจากโมดูลหรือไลบรารีอื่นคุณสามารถจับสิ่งที่ YourWidgetProvider.class.getName () เอาต์พุตและสร้างค่าคงที่:

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

จากนั้นคุณจะสามารถใช้สิ่งนี้โดยปริยาย:

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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.