【问题标题】:Update widget's TextView with API data使用 API 数据更新小部件的 TextView
【发布时间】: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,然后(完成后)尝试更新小部件?如果可能,请提供正式回复,我会尽力解决。非常感谢

标签: android widget android-widget


【解决方案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】:
  1. 扩展 AsyncTask 以调用 API。在方法doInBackground 尝试连接到互联网,然后通过AppWidgetManager 更新小部件。

  2. 添加到 onUpdate 方法

     @Override
     public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds ){
         super.onUpdate( context, appWidgetManager, appWidgetIds );
    
         new AsyncTaskUpdater(context).execute(...);
     }
    

因此,方法 onUpdate 不会更新小部件。

【讨论】:

    猜你喜欢
    • 2013-02-02
    • 2013-03-21
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多