使用 API 数据更新小部件的 TextView
Posted
技术标签:
【中文标题】使用 API 数据更新小部件的 TextView【英文标题】:Update widget's TextView with API data 【发布时间】:2021-12-19 05:47:50 【问题描述】:简介
我的目标是将 TextView 的文本设置为我使用 Volley 和 JSON 从 API 获得的字符串。
函数 getData() 似乎工作正常(检查 Logcat)。
问题
在 API 返回其值的那一刻,updateAppWidget(...) 已经通过,TextView 文本已经设置为“”(这是默认的静态值)。如果我在线程中添加 TextView,由于线程性质,它将无法工作。
战略
我需要一种方法来使 updateAppWidget(...) 函数等待几秒钟,直到从 API 中撤回该值。还是有更好的选择?
我编辑的唯一文件是我在此处附加的文件和 androidManifest(只是为了允许上网)。
提前致谢。
package com.bosswell.samplewidgetapi;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.widget.RemoteViews;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONException;
import org.json.JSONObject;
public class NewAppWidget extends AppWidgetProvider
static String value ="";
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId)
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
getData(views, context);
views.setTextViewText(R.id.appwidget_text, value);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
Log.d("INFO", "onUpdate");
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds)
updateAppWidget(context, appWidgetManager, appWidgetId);
@Override
public void onEnabled(Context context)
Log.d("INFO", "onEnabled");
// 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
private static void getData(RemoteViews views, Context c)
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(c);
String url ="https://www.worldtimeapi.org/api/timezone/Europe/Moscow";
Log.d("INFO", url);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>()
@Override
public void onResponse(String response)
try
JSONObject j = new JSONObject(response);
value = j.getString("datetime").toString();
Log.d("INFO", value);
catch (JSONException e)
value = e.getMessage();
, new Response.ErrorListener()
@Override
public void onErrorResponse(VolleyError error)
value = error.getMessage();
);
// Add the request to the RequestQueue.
queue.add(stringRequest);
【问题讨论】:
如果您重复执行此类 API 相关活动,您可以查看 MVVM 和观察者,这是推荐的操作方式 使用AsyncTask调用API,然后尝试更新widget @Style-7 如何对代码进行排序以首先调用 API,然后(完成后)尝试更新小部件?如果可能,请提供正式回复,我会尽力解决。非常感谢 【参考方案1】:您只需要在您的TextView
中设置值
响应
这样的方法
@Override
public void onResponse(String response)
try
JSONObject j = new JSONObject(response);
value = j.getString("datetime").toString();
yourTextView.setText(value.toString());
Log.d("INFO", value);
catch (JSONException e)
value = e.getMessage();
【讨论】:
感谢您的回复。更改意味着将视图作为参数传递,我这样做了,但没有奏效。 主屏幕小部件没有 setText。【参考方案2】:扩展 AsyncTask
以调用 API。在方法doInBackground
尝试连接到互联网,然后通过AppWidgetManager
更新小部件。
添加到 onUpdate 方法
@Override
public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds )
super.onUpdate( context, appWidgetManager, appWidgetIds );
new AsyncTaskUpdater(context).execute(...);
因此,方法 onUpdate 不会更新小部件。
【讨论】:
以上是关于使用 API 数据更新小部件的 TextView的主要内容,如果未能解决你的问题,请参考以下文章