Vamshi Krishna Vamshi Krishna - 1 year ago 57
Android Question

Android Widget doesn't display data

I am creating an Android Application which is supposed to show a list of items (Strings) in a widget, but for some reason I am unable to get it to work.

Code

Widget Ingredients

package com.example.vamshi.baking.Widget;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.RemoteViews;

import com.example.vamshi.baking.R;
import com.example.vamshi.baking.Widget.Service.WidgetService;

/**
* Implementation of App Widget functionality.
*/
public class Ingredients extends AppWidgetProvider {

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {

CharSequence widgetText = context.getString(R.string.appwidget_text);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.ingredients);


// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
final int N = appWidgetIds.length;
for (int i = 0; i<N; ++i) {
RemoteViews remoteViews = updateWidgetListView(context,
appWidgetIds[i]);
appWidgetManager.updateAppWidget(appWidgetIds[i],
remoteViews);
}

}

private RemoteViews updateWidgetListView(Context context, int appWidgetId) {
RemoteViews remoteViews = new RemoteViews(
context.getPackageName(),R.layout.ingredients);

//RemoteViews Service needed to provide adapter for ListView
Intent svcIntent = new Intent(context, WidgetService.class);
//passing app widget id to that RemoteViews Service
svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
//setting a unique Uri to the intent
//don't know its purpose to me right now
svcIntent.setData(Uri.parse(
svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
//setting adapter to listview of the widget
remoteViews.setRemoteAdapter(R.id.list_view_widget,
svcIntent);

return 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
}
}


Widget Service

package com.example.vamshi.baking.Widget.Service;

import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.widget.RemoteViewsService;

import com.example.vamshi.baking.Widget.WidgetViewAdapter;

/**
* Created by Vamshi on 7/27/2017.
*/

public class WidgetService extends RemoteViewsService {

@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
int appWidgetID = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
return (new WidgetViewAdapter(this.getApplicationContext(), intent));
}
}


Widget View Adapter

package com.example.vamshi.baking.Widget;

import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
import android.widget.Toast;

import com.example.vamshi.baking.Data.*;
import com.example.vamshi.baking.Data.Ingredients;
import com.example.vamshi.baking.R;
import com.example.vamshi.baking.Retrofit.IRecipe;
import com.example.vamshi.baking.Retrofit.RetrofitBuilder;

import java.util.ArrayList;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
* Created by Vamshi on 7/27/2017.
*/

public class WidgetViewAdapter implements RemoteViewsService.RemoteViewsFactory {

Context context;
ArrayList<Recipe> r;
ArrayList<com.example.vamshi.baking.Data.Ingredients> i;
private int appWidgetID;
ArrayList<String> iList;

public WidgetViewAdapter(Context c, Intent in){
populate();
this.context = c;
appWidgetID = in.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);

}

private void populate() {

IRecipe irecipie = RetrofitBuilder.Retrieve();
final Call<ArrayList<Recipe>> recipie = irecipie.getRecipe();
recipie.enqueue(new Callback<ArrayList<Recipe>>() {
@Override
public void onResponse(Call<ArrayList<Recipe>> call, Response<ArrayList<Recipe>> response) {
r = response.body();
i = r.get(0).getIngredients();
for(int j = 0; j<=i.size(); j++){
iList.add(i.get(0).getIngredient());
}
}

@Override
public void onFailure(Call<ArrayList<Recipe>> call, Throwable t) {
Toast.makeText(context, "No Internet Connection", Toast.LENGTH_SHORT).show();
}
});
}

@Override
public void onCreate() {

populate();
}

@Override
public void onDataSetChanged() {

IRecipe irecipie = RetrofitBuilder.Retrieve();
final Call<ArrayList<Recipe>> recipie = irecipie.getRecipe();
recipie.enqueue(new Callback<ArrayList<Recipe>>() {
@Override
public void onResponse(Call<ArrayList<Recipe>> call, Response<ArrayList<Recipe>> response) {
r = response.body();
i = r.get(0).getIngredients();
for(int j = 0; j<=i.size(); j++){
iList.add(i.get(0).getIngredient());
}
}

@Override
public void onFailure(Call<ArrayList<Recipe>> call, Throwable t) {
Toast.makeText(context, "No Internet Connection", Toast.LENGTH_SHORT).show();
}
});

}

@Override
public void onDestroy() {

}

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

@Override
public RemoteViews getViewAt(int position) {
final RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.row);
Ingredients in = i.get(position);
remoteView.setTextViewText(R.id.text_for_widget, in.getIngredient());
return remoteView;
}

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

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

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

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


Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.vamshi.baking">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<service
android:name=".WidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".UI.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".UI.SecondScreenDetails" />
<activity android:name=".UI.StepsActivity" />
<activity android:name=".UI.SingleStepItem" />

<receiver android:name=".Widget.BakingWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>

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

<activity android:name=".UI.MasterDetailFlow" />

<receiver android:name=".Widget.Ingredients">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>

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

</manifest>


Layout Files

Ingredients.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/widget_margin">

<ListView
android:id="@+id/list_view_widget"
android:layout_width="match_parent"
android:layout_height="match_parent">

</ListView>

</LinearLayout>


row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/text_for_widget"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>


Thanks in advance

Answer Source

My aim was to display a list of strings in widget and since widget does not allow recycler views to be displayed i had to go for a list view i had quite a lot of trouble in finding out what was the problem but i got referred to an amazing article that demonstrates perfectly how to do it i am posting the link here so incase any of you need help can refer to this

https://dharmangsoni.blogspot.in/2014/03/collection-widget-with-event-handling.html

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download