Issue
The TextView in my widgetis set correctly with the correct info when it's getting placed at the home screen. But when I update the info in the main app, the widget still shows the old info.
Manifest:
<receiver android:name=".WidgetProvider" android:label="@string/app_name" android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget" />
</receiver>
WidgetProvider.java:
package com.example.huskeliste;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
public class WidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
int widgetId = appWidgetIds[i];
DBAdapter info = new DBAdapter(context);
info.open();
String data = info.getTextViewData();
info.close();
Intent intent = new Intent(context, Main.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.loWidget, pendingIntent);
views.setTextViewText(R.id.txtView, data);
appWidgetManager.updateAppWidget(widgetId, views);
}
}
}
res - widget.xml:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/widget"
android:minWidth="294dp"
android:minHeight="72dp"
android:updatePeriodMillis="1800000">
</appwidget-provider>
layout - widget.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/loWidget"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:layout_margin="1dp"
android:background="@drawable/background">
<TextView
android:id="@+id/txtView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22dp"
android:textColor="#ffffff"
android:text="" />
</LinearLayout>
background.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:startColor="#CC111111" android:endColor="#CC111111" android:angle="0" />
<padding android:left="4dp" android:top="1dp" android:right="4dp" android:bottom="1dp" />
<corners android:radius="3dp" />
</shape>
getTextViewData() from DBAdapter.java:
public String getTextViewData() {
String[] columns = new String[] { KEY_NAME };
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
String result = "";
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
if (result.length() > 0) {
result += ", ";
}
result += c.getString(0);
}
return result;
}
Anyone have a clue what's missing in my code?
Solution
You need to set an update interval in milliseconds inside your Widget provider XML. Example code:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="294dp"
android:minHeight="72dp"
android:updatePeriodMillis="86400000"
android:previewImage="@drawable/preview"
android:initialLayout="@layout/example_appwidget"
android:configure="com.example.android.ExampleAppWidgetConfigure"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen|keyguard"
android:initialKeyguardLayout="@layout/example_keyguard">
</appwidget-provider>
However, you should know that the system does not guarantee the widget to be updated as often. Also, if you want the widget to update more often (e.g. after a configuration change, as it is with your question), you need to do it manually. Here's how I proceed:
In this example my Widget class is simply called Widget.class:
public class Widget extends AppWidgetProvider {
// TODO: Don't forget to override the onUpdate method also
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("update_widget")) {
// Manual or automatic widget update started
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget);
// Update text, images, whatever - here
remoteViews.setTextViewText(R.id.yourTextID, "My updated text");
// Trigger widget layout update
AppWidgetManager.getInstance(context).updateAppWidget(
new ComponentName(context, Widget.class), remoteViews);
}
}
}
Make sure to replace the layout and the TextView
with references to your widget layout.
Then whenever you want to update your widget (e.g. in the onPause
method of your main activity or whenever a Save button is clicked), you call a PendingIntent
:
Intent updateWidget = new Intent(context, Widget.class); // Widget.class is your widget class
updateWidget.setAction("update_widget");
PendingIntent pending = PendingIntent.getBroadcast(context, 0, updateWidget, PendingIntent.FLAG_CANCEL_CURRENT);
pending.send();
Answered By - Dzhuneyt
Answer Checked By - Robin (JavaFixing Admin)