studio - oncancelled asynctask android
AppWidgetProvider public void onEnabled(Contexto de contexto) no afecta el widget (2)
Estoy usando un AppWidgetProvider e intento anular el onEnabled, que supongo es el que se llama cuando el usuario agrega la aplicación a la pantalla de inicio. Mi clase AppWidgetProvider se ve así y llama a una tarea asíncrona que se supone que actualiza mi vista de texto:
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
}
}
Mi widget de archivo xml que muestra cómo se ve el widget es:
<?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>
Y mi tarea asíncrona que eventualmente analizará algunos JSON para agregar a mi widget se ve así:
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();
}
}
Basado en mi código anterior, cuando el usuario agrega el widget a la pantalla de su casa, debe ejecutar onEnabled () que debería llamar a mi tarea asincrónica y cambiar la vista de texto de "probar 123" a "cambiar en la tarea asíncrona".
En este momento, nada está cambiando y no puedo entender por qué.
Actualizar:
Aquí está el código que tengo en mi manifiesto relacionado con mi widget:
<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>
También sé que se está llamando a mi tarea asincrónica porque simplemente puse Log.d en ella y está ejecutando la tarea asincrónica, simplemente no está configurando el valor de la vista de texto en el widget.
Actualización 2
También intenté usar la vista remota con la respuesta sugerida a continuación y ahora tengo esto en mi tarea asíncrona:
@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]);
}
Pero obtengo un error de método no resuelto
RemoteViews rv = HelloWidget.buildRemoteViews(c, mgr, appWidgetIds);
en buildRemoteViews
El método buildRemoteViews () no es cómo obtienes un objeto RemoteViews en un widget; usa un constructor en su lugar.
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
Sin ofender, pero esto está muy claramente establecido en el ejemplo en la guía API para los widgets de aplicaciones .
Regístrese para la transmisión en su manifiesto:
<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>
También tenga en cuenta esto sobre onEnabled ():
"Esto se llama cuando una instancia se crea el widget de la aplicación por primera vez. Por ejemplo, si el usuario agrega dos instancias de su widget de aplicación, esto solo se llama la primera vez".
También tiene el hecho de que se llamará a onUpdate () de todos modos cuando se agrega una instancia, por lo que hacer lo mismo en onEnabled () puede ser redundante.
Además, una vez que obtenga esa AsyncTask para ejecutar, tendrá una gran cantidad de problemas, el primero de los cuales es que el objeto Contexto no es una Actividad.
EDITAR: Ahora que se llama a su método, tendrá que configurar el texto mediante RemoteViews. No necesita hacerlo en onPostExecute () ya que esta es una actualización de proceso cruzado.
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);
}
Eso actualizará todos tus AppWidget, si solo quieres uno para actualizar, necesitarás ingresar su identificación.