AppWidgetProvider public void onEnabled (context context) does not affect the widget

I am using AppWidgetProvider and trying to override onEnabled, which I assume is what gets called when the application is added to the user's main screen. My AppWidgetProvider class looks like this and calls the async task, which should update the text view:

package com.example.beerportfoliopro; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; /** * Created by Mike on 12/26/13. */ public class HelloWidget extends AppWidgetProvider { @Override public void onEnabled(Context context){ //build url for async task String url = "hiddenURL"; //call async task new GetRandomBeer(context).execute(url); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){ //todo: call update code, which should be the same as onEnabled } } 

My xml widget file displaying the widget view looks like this:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/widget_bg_normal" > <TextView android:id="@+id/widget_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="testing 123" android:layout_gravity="center_horizontal|center" android:layout_marginTop="5dip" android:padding="10dip" android:textColor="@android:color/black" > </TextView> </LinearLayout> 

And my async task, which will eventually parse some JSON to add to my widget, looks like this:

 public class GetRandomBeer extends AsyncTask <String, Void, String> { Context c; public GetRandomBeer(Context context) { c = context; } @Override protected String doInBackground(String... arg0) { // TODO Auto-generated method stub return readJSONFeed(arg0[0]); } protected void onPostExecute(String result){ Log.d("taste","Inside get taste"); //decode json here try{ //todo: get all beer data //todo: set text views with data TextView breweryTitle = (TextView) ((Activity) c).findViewById(R.id.widget_tv); breweryTitle.setText("changed in the async task!"); } catch(Exception e){ } } public String readJSONFeed(String URL) { StringBuilder stringBuilder = new StringBuilder(); HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(URL); try { HttpResponse response = httpClient.execute(httpGet); StatusLine statusLine = response.getStatusLine(); int statusCode = statusLine.getStatusCode(); if (statusCode == 200) { HttpEntity entity = response.getEntity(); InputStream inputStream = entity.getContent(); BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { stringBuilder.append(line); } inputStream.close(); } else { Log.d("JSON", "Failed to download file"); } } catch (Exception e) { Log.d("readJSONFeed", e.getLocalizedMessage()); } return stringBuilder.toString(); } } 

Based on my code above, when a user adds a widget to the screen of their homes, he should run onEnabled (), which should call my async task and change the text view, saying "123 test" to "change the async task!".

Now nothing is changing, and I can’t understand why.

Update:

Here is the code I have in my manifest related to my widgets:

  <receiver android:name="com.example.beerportfoliopro.HelloWidget" android:label="@string/app_name"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_ENABLED" /> </intent-filter> 

I also know that my async task is called because I just put some Log.d in it, and it runs the async task, just not setting the textview value in the widgets.

Update 2

I also tried using remote view with the answer below, and now I have this in my asynchronous task:

  @Override protected String doInBackground(String... arg0) { // TODO Auto-generated method stub String beerText = "try number 3"; AppWidgetManager mgr = AppWidgetManager.getInstance(c); int[] appWidgetIds = mgr.getAppWidgetIds(new ComponentName(c, HelloWidget.class)); //You need a static method somewhere (I usually put in widget provider class) //that builds the RemoteView and sets everything up. RemoteViews rv = HelloWidget.buildRemoteViews(c, mgr, appWidgetIds); rv.setTextViewText(R.id.widget_tv, beerText); mgr.updateAppWidget(appWidgetIds, rv); return readJSONFeed(arg0[0]); } 

But I get can not resolve the method error

  RemoteViews rv = HelloWidget.buildRemoteViews(c, mgr, appWidgetIds); 

under buildRemoteViews

0
source share
2 answers

Register to broadcast in the manifest:

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

Also pay attention to aboutEnabled ():

"This is caused when the first instance of the App Widget is created. For example, if the user adds two instances of your application widget, it is called only for the first time."

You also have the fact that onUpdate () will be called anyway when an instance is added, so doing the same in onEnabled () may be redundant.

In addition, once you get AsyncTask running, you will have many problems, the first of which is a Context object, not an Activity.

EDIT: Now that your method is called, you will need to set the text using RemoteView. You do not need to do this in onPostExecute (), as this is a cross-process update.

 protected Void doInBackground(String... arg0) { String beerText = readJSONFeed(arg0[0]); AppWidgetManager mgr = AppWidgetManager.getInstance(c); int[] appWidgetIds = mgr.getAppWidgetIds(new ComponentName(c, HelloWidget.class)); //You need a static method somewhere (I usually put in widget provider class) //that builds the RemoteView and sets everything up. RemoteViews rv = HelloWidget.buildRemoteViews(c, mgr, appWidgetIds); rv.setTextViewText(R.id.text_view_in_layout, beerText); mgr.updateAppWidget(appWidgetIds, rv); } 

This will update all your AppWidget, if you only want to update it, you will need to pass its id.

+3
source

The buildRemoteViews () method is not how you get the RemoteViews object in widgets; use the constructor instead.

 RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout); 

Do not be offended, but this is pretty clearly laid out in the example in the API guide for the application widget .

0
source

Source: https://habr.com/ru/post/1488859/


All Articles