带有 youtubeAPI 显示的应用程序是空白的,Logcat 中没有任何内容,也没有错误

App with youtubeAPI display is blank with nothing in the Logcat and no error

我正在运行使用 youtube 数据 API 将频道嵌入到 android 应用中 API。

但是当我 运行 应用程序时,它什么也不显示。 Logcat 中没有显示任何内容。但是,运行 选项卡以蓝色显示这些消息。

W/System.err: org.json.JSONException: No value for videoId
W/System.err:     at org.json.JSONObject.get(JSONObject.java:392)
        at org.json.JSONObject.getString(JSONObject.java:553)
W/System.err:     at com.currentmedia.channel.MainActivity.onResponse(MainActivity.java:65)
W/System.err:     at com.currentmedia.channel.MainActivity.onResponse(MainActivity.java:50)
        at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:82)
W/System.err:     at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:29)
        at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
        at android.os.Handler.handleCallback(Handler.java:790)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:7025)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

MainActivity 代码如下

public class MainActivity extends AppCompatActivity {
    String API_Key = "API_KEY";
    ListView listView;
    ArrayList<VideoDetails> videoDetailsArrayList;
    MyCustomAdapter myCustomAdapter;
    String url="https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCS5PDM-3ThA1BNhuyqWwG_w&maxResults=50&key={API_KEY}";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.listView);
        videoDetailsArrayList = new ArrayList<>();
        myCustomAdapter = new MyCustomAdapter(MainActivity.this, videoDetailsArrayList);


        displayVideos();
    }

        private void displayVideos () {
            RequestQueue requestQueue= Volley.newRequestQueue(getApplicationContext());
            StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {

                    try {
                        JSONObject jsonObject = new JSONObject(response);
                        JSONArray jsonArray=jsonObject.getJSONArray("items");

                        for(int i=0; i<jsonArray.length();i++)
                        {
                            JSONObject jsonObject1=jsonArray.getJSONObject(i);
                            JSONObject jsonVideoId=jsonObject1.getJSONObject("id");
                            JSONObject jsonObjectsnippet=jsonObject1.getJSONObject("snippet");
                            JSONObject jsonObjectDefault=jsonObjectsnippet.getJSONObject("thumbnails").getJSONObject("medium");

                            String video_id=jsonVideoId.getString("videoId");

                            VideoDetails vd=new VideoDetails();
                            vd.setVideoId(video_id);
                            vd.setTitle(jsonObjectsnippet.getString("title"));
                            vd.setDescription(jsonObjectsnippet.getString("description"));
                            vd.setUrl(jsonObjectDefault.getString("url"));

                            videoDetailsArrayList.add(vd);

                        }
                        listView.setAdapter(myCustomAdapter);
                        myCustomAdapter.notifyDataSetChanged();


                    }catch (JSONException e)
                    {
                        e.printStackTrace();
                    }

                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                   Toast.makeText(getApplicationContext(),error.getMessage(), LENGTH_LONG).show();

                }
            }
            );
            requestQueue.add(stringRequest);
    }

我不明白 videoId 没有值是什么意思。

请注意,根据 Search.list API 端点的官方文档,id.videoId 可能不会出现在获得的结果集中的每一项中来自该端点的响应:

id.videoId (string)
If the id.kind property's value is youtube#video, then this property will be present and its value will contain the ID that YouTube uses to uniquely identify a video that matches the search query.

(请注意,我确实更正了文档,将 id.type 替换为 id.kind。)

这是非常可以接受的,因为在 URL:

上调用 Search.list

https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCS5PDM-3ThA1BNhuyqWwG_w&maxResults=50&key={API_KEY}

返回的结果集很可能包含不一定指视频的项目;如果事实上第一个条目的 id.kind 的值为 youtube#channel:

{
  "kind": "youtube#searchListResponse",
  "etag": "2VoDDmPbFOrlKO9COuJvLIPTGsc",
  "nextPageToken": "CDIQAA",
  "regionCode": "...",
  "pageInfo": {
    "totalResults": 70,
    "resultsPerPage": 50
  },
  "items": [
    {
      "kind": "youtube#searchResult",
      "etag": "qP4nftiUBo-HCqeTOulVW0GSmuI",
      "id": {
        "kind": "youtube#channel",
        "channelId": "UCS5PDM-3ThA1BNhuyqWwG_w"
      },
      "snippet": {
        "publishedAt": "2016-06-30T07:46:01Z",
        "channelId": "UCS5PDM-3ThA1BNhuyqWwG_w",
        "title": "Slimy guy",
        "description": "Hi Guys hope your all having a wonderful day I am a family friendly Youtuber, Gamer and a reactor I will also try to make some Vlogs.",
        "thumbnails": {
          ...
        },
        "channelTitle": "Slimy guy",
        "liveBroadcastContent": "upcoming",
        "publishTime": "2016-06-30T07:46:01Z"
      }
    },
    ...
  ]
}

如果您有兴趣从 Search.list 获取 仅视频 ,则将参数 type 添加到调用 URL 中作为type=video。然后您的代码将正常工作,因为 API 将 return 仅向您提供代表视频的项目。

尽管如此,在您的代码中使用以下形式的断言是一种很好的做法:

assert jsonVideoId.getString("kind") == "youtube#video";

就在调用 jsonVideoId.getString("videoId").

之前

(我确实注意到变量名称 jsonVideoId 很不幸,因为如上所述,JSON id 对象不一定仅指视频。)