我正在使用AppWidgetProvider并试图覆盖onEnabled,我假设是当应用程序从用户添加到主屏幕时调用的内容。我的AppWidgetProvider类看起来像这样,并调用异步任务,该任务应该更新我的文本视图:
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
}
}
显示小部件外观的我的小部件xml文件是:
<?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>
我的异步任务最终将解析一些JSON以添加到我的小部件,如下所示:
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();
}
}
根据我上面的代码,当用户将小部件添加到他们的主屏幕时,它应该运行onEnabled(),它应该调用我的异步任务并将textview从“测试123”更改为“更改异步任务!”
现在一切都没有改变,我无法弄清楚原因。
更新
以下是我的清单中与我的小部件相关的代码:
<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>
我也知道我的异步任务正在被调用,因为我只是将一些Log.d放入其中并且它正在运行异步任务,它只是没有在小部件中设置textview值。
更新2
我也尝试使用下面建议的答案使用远程视图,现在我在异步任务中有这个:
@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]);
}
但我得到一个无法解决方法错误
RemoteViews rv = HelloWidget.buildRemoteViews(c, mgr, appWidgetIds);
<{1>} 下的
答案 0 :(得分:3)
在清单中注册广播:
<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>
还要注意onEnabled():
“当第一次创建App Widget的实例时调用此方法。例如,如果用户添加了App Widget的两个实例,则只会在第一次调用它。”
你还有一个事实是,当添加一个实例时,无论如何都会调用onUpdate(),所以在onEnabled()中做同样的事情可能是多余的。
此外,一旦你执行了AsyncTask,你就会遇到很多问题,首先是Context对象不是Activity。
编辑:既然正在调用您的方法,您将需要使用RemoteViews设置文本。您不需要在onPostExecute()中执行此操作,因为这是跨进程更新。
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);
}
这会更新你的所有AppWidget,如果你只想更新一个,你需要传递它的id。
答案 1 :(得分:0)
buildRemoteViews()方法不是如何在窗口小部件中获取RemoteViews对象;改为使用构造函数。
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
没有冒犯,但API guide for App Widgets。
中的例子清楚地说明了这一点