I know this has been asked for many times but I went through the documentation from top to bottom, read all answers here and none of them helped. To be honest, each answer says
I had a widget implementation in my project. I have modified the below code so that data in widget can be changed from one of my Activity in application. Only showing the essential code for your specific use case.
Here I am having a button with text in my widget. Through login button click in my Activity , I am modifying the button text in my widget
Below is my AppWidgetProvider.java
class
public class AppWidgetTrackAsset extends AppWidgetProvider{
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// Perform this loop procedure for each App Widget that belongs to this provider
final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
// Create an Intent to launch Activity
Intent intent = new Intent(context, WidgetAlertActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.app_widget_track_asset);
views.setOnClickPendingIntent(R.id.sosButton, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Log.v(Constants.WIDGET_LOG, "onReceive called with " + intent.getAction());
if (intent.getAction().equals("update_widget")) {
// widget update started
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.app_widget_track_asset);
// Update text , images etc
remoteViews.setTextViewText(R.id.sosButton, "My updated text");
// Trigger widget layout update
AppWidgetManager.getInstance(context).updateAppWidget(
new ComponentName(context, AppWidgetTrackAsset.class), remoteViews);
}
}
@Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
@Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
}
Below is my Activity where I am updating the widget button text on click of my login button
LoginActivity.java
public class LoginActivity extends AppCompatActivity implements View.OnClickListener{
Button loginButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
loginButton=(Button)findViewById(R.id.loginButton);
loginButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v.getId() == R.id.loginButton){
updateWidget();
}
}
private void updateWidget(){
try {
Intent updateWidget = new Intent(this, AppWidgetTrackAsset.class);
updateWidget.setAction("update_widget");
PendingIntent pending = PendingIntent.getBroadcast(this, 0, updateWidget, PendingIntent.FLAG_CANCEL_CURRENT);
pending.send();
} catch (PendingIntent.CanceledException e) {
Log.e(Constants.UI_LOG,"Error widgetTrial()="+e.toString());
}
}
}
Layout for app widget goes like this
app_widget_track_asset.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/widgetbackground"
android:padding="@dimen/widget_margin">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/sosButton"
android:text="SOS"
android:textSize="20sp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
/>
</RelativeLayout>
Below is the manifest file essential part for widget
<receiver android:name=".appwidget.AppWidgetTrackAsset">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/app_widget_track_asset_info" />
</receiver>
I would say that notifyAppWidgetViewDataChanged
method should work for you.
You have to build AppWidgetManager
and get appWidgetIds
and then just call notifyAppWidgetViewDataChanged
on your AppWidgetManager
.
Pseudo Code,
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int appWidgetIds[] = appWidgetManager.getAppWidgetIds(
new ComponentName(context, WidgetProvider.class));
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.listview);
For more, you can checkout my answer here which contains demo on github.