带有 youtubeAPI 显示的应用程序是空白的,Logcat 中没有任何内容,也没有错误
App with youtubeAPI display is blank with nothing in the Logcat and no error
我正在运行使用 youtube 数据 API 将频道嵌入到 android 应用中 API。
- Youtube API 已导入
- 已授予 Internet 权限
- Youtube 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
对象不一定仅指视频。)
我正在运行使用 youtube 数据 API 将频道嵌入到 android 应用中 API。
- Youtube API 已导入
- 已授予 Internet 权限
- Youtube 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 theid.kind
property's value isyoutube#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
对象不一定仅指视频。)