SAbbasizadeh
SAbbasizadeh

Reputation: 730

update textView in a widget

I've read a lot of Q&As but I couldn't find my answer.
May be something in my implementation is wrong.
The problem is that my TextView in the widget doesn't get updated.

The logic is this:

1.setOnClickPendingIntent on a specific button in the onUpdate()
2.clicking on this button will broadcast an intent with a declared action
3.at last i'll update the text of the textView in the onRecieve()

Widget2.class :

public class Widget2 extends AppWidgetProvider {

private static final String SCROLL_LEFT = "widget2.SCROLL_LEFT";

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

    super.onUpdate(context, appWidgetManager, appWidgetIds);

    for (int i = 0; i < appWidgetIds.length; i++) {
        int appWidgetId = appWidgetIds[i];
        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.small);

        Intent scrollLeft = new Intent(Widget2.SCROLL_LEFT);
        PendingIntent leftScrollPendingIntent = PendingIntent.getBroadcast(context,
                appWidgetId, scrollLeft, appWidgetId);
        remoteViews.setOnClickPendingIntent(R.id.left_scroller, leftScrollPendingIntent);

        appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
    }
}

@Override
public void onReceive(Context context, Intent intent) {

    Log.e(getClass().getSimpleName(), "onReceive()");
    int appWidgetId = intent.getFlags();
    if (intent.getAction().equals(SCROLL_LEFT)) {
        updateCurrentWidget(context, appWidgetId);
        Log.i("onReceive", SCROLL_LEFT + "   appWidgetId = " + appWidgetId);
    }
            super.onReceive(context,intent);  
}

private void updateCurrentWidget(Context context, int appWidgetId) {
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.small);
    remoteViews.setString(R.id.name_of_the_app, "setText", "android os");
    remoteViews.setTextViewText(R.id.description, "best ever");

    Log.i("updateCurrentWidget", "the text have been set");
    AppWidgetManager manager = AppWidgetManager.getInstance(context);
    manager.updateAppWidget(appWidgetId, remoteViews);
}  

manifest.xml :

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="4"
        android:targetSdkVersion="14" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <receiver android:name=".Widget2" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="widget2.SCROLL_LEFT" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_small" />
        </receiver>
    </application>

</manifest>  

and here is the simplified logcat logs:

   onReceive()
   "myPackageName".Widget2.SCROLL_LEFT
   the text have been set
   "myPackageName".Widget2.SCROLL_LEFT appWidgetId = 268435456  

everything seems to be correct but the text is never changed!

Upvotes: 3

Views: 4248

Answers (2)

SAbbasizadeh
SAbbasizadeh

Reputation: 730

The key in the widget is you have to set every View and every Intent before calling the updateAppWidget() method. Here You can call updateWidgetInstance(...) from your onReceive() method:

// action = the String that you get from your intent in the onRecive() method
// id = the id of the appWidget instance that you want to update
// you can get the id in the onReceive() method like this:
// int id = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
private static void updateWidgetInstance(Context context, AppWidgetManager manager, String action, int id) {
    RemoteViews remoteViews = updateCurrentWidget(context, id);
    remoteViews = setIntents(remoteViews, context, id);
    manager.updateAppWidget(id, remoteViews);
}

updating the View: (Here you can also change the layout of this instance depending on your needs)

  private static RemoteViews updateCurrentWidget(Context context, int appWidgetId) {
    RemoteViews remoteViews;

        remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_small_layout);
        remoteViews.setTextViewText(R.id.widget_name_of_the_app, "Android OS");
        remoteViews.setTextViewText(R.id.widget_app_description, "best ever");
        remoteViews.setImageViewUri(R.id.widget_icon_of_the_app, ...);

    return remoteViews;
}

updating intents:

private static RemoteViews setIntents(RemoteViews rm, Context context, int appWidgetId) {

    Intent click = new Intent(context, Widget.class);
    click.setAction("[name of the action]");
    click.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    PendingIntent pendingIntent =
            PendingIntent.getBroadcast(context, appWidgetId, click, PendingIntent.FLAG_UPDATE_CURRENT);
    rm.setOnClickPendingIntent(R.id.button1, pendingIntent);

    return rm;
}

Upvotes: 3

Ran
Ran

Reputation: 4157

you are setting your appWidgetId in the PendingIntent flags. that's just wrong since PendingIntet flags have meanings, they are not meant to save some data.

You should use the extras for that.

Upvotes: 0

Related Questions