W
W
Wolframius2017-07-05 16:08:39
Android
Wolframius, 2017-07-05 16:08:39

Why is the list on the widget displaying information from the database not updated?

My bookmarks application has a DB that stores entries. Each entry contains a link and a page title. The application has an interface for viewing, navigating through a bookmark, adding, editing and deleting bookmarks. I wanted to add a widget (on the main screen of the system) that displays a list with bookmark titles. Everything works fine here is a piece of manifest code

<receiver
      android:icon="@drawable/ic_icon"
      android:label="Закладки"
      android:name=".WidgetProvider" >
      <intent-filter >
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
      </intent-filter>

      <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/widget_info" />
    </receiver>
    <service
      android:name=".WidgetService"
      android:permission="android.permission.BIND_REMOTEVIEWS">
    </service>

Here is my res/xml/widget_info.xml
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget_layout"
  android:minHeight="180dp"
    android:minWidth="180dp"
  android:resizeMode="horizontal|vertical"
     >

</appwidget-provider>

Here is my res/layout/widget_layout.xml
<ListView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/widget_list"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  android:background="#FFFFFF">

</ListView>

Here is the markup of the list item res/layout/widget_item.xml
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:clickable="true"
  android:id="@+id/widget_item_root"
  android:background="?android:attr/selectableItemBackground"
  android:layout_height="wrap_content"
  android:orientation="vertical">

  <TextView
    android:layout_height="wrap_content"
    android:id="@+id/widget_item_text"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:layout_width="match_parent"
    android:text=""
    android:singleLine="true"
    android:textColor="#000000"
    android:padding="10dp"/>

</LinearLayout>

Here is WidgetProvider.java
public class WidgetProvider extends AppWidgetProvider
{
  @Override
  public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
  {
    ComponentName widget = new ComponentName(context, WidgetProvider.class);
    int[] ids = appWidgetManager.getAppWidgetIds(widget);
    for (int id : ids)
    {
      RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
      Intent adapter = new Intent(context, WidgetService.class);
      adapter.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
      views.setRemoteAdapter(R.id.widget_list, adapter);
      appWidgetManager.updateAppWidget(id, views);
    }
  }
}

Here is WidgetService.java
public class WidgetService extends RemoteViewsService {
  @Override
  public RemoteViewsFactory onGetViewFactory(Intent intent) {
    return new WidgetFactory(getApplicationContext(), intent);
  }
}

Here is WidgetFactory.java
public class WidgetFactory implements RemoteViewsFactory
{
  private Cursor cursor;
  private Context context;
  private int widgetID;
  
  public WidgetFactory(Context ctx, Intent intent)
  {
    context = ctx;
    widgetID = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
  }
  
  @Override
  public void onCreate()
  {
    Database db = new Database(context);
    SQLiteDatabase sql = db.getWritableDatabase();
    cursor = sql.query(Database.TABLE_BOOKMARKS, new String[]{BaseColumns._ID, Database.LINK, Database.TITLE}, null, null, null, null, null);
  }

  @Override
  public int getCount()
  {
    return cursor.getCount();
  }

  @Override
  public long getItemId(int position)
  {
    return position;
  }

  @Override
  public RemoteViews getLoadingView()
  {
    return null;
  }

  @Override
  public RemoteViews getViewAt(int position)
  {
    RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_item);
    cursor.moveToPosition(position);
    rv.setTextViewText(R.id.widget_item_text, cursor.getString(cursor.getColumnIndex(Database.TITLE)));
    return rv;
  }

  @Override
  public int getViewTypeCount()
  {
    return 1;
  }

  @Override
  public boolean hasStableIds()
  {
    return true;
  }

  @Override
  public void onDataSetChanged()
  {
    cursor.requery();
  }

  @Override
  public void onDestroy()
  {

  }

}

This is how I am trying to update the widget adapter
private void updateAppWidget(){
    Intent intent = new Intent(this,WidgetProvider.class);
    intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
    int[] ids = {R.id.widget_list};
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,ids);
    sendBroadcast(intent);
  }

Arranged logs, this method pulls onUpdate from WidgetProvider but does not pull onDataSetChanged from WidgetFactory. What am I doing wrong?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question