【问题标题】:JSON query doesn't show items even if there is no errors when compiling即使编译时没有错误,JSON 查询也不显示项目
【发布时间】:2020-02-12 10:24:06
【问题描述】:

我刚开始学习 android,所以现在我的目标是使用具有多种功能的 Youtube API 创建一个应用程序,但其中一项功能是搜索视频并在我的屏幕上列出它们 - 无法正常工作并且没有错误,但是当我按下搜索按钮时,什么也没有发生。这是主类的代码


import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;

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 com.app.youtubedownloader.Adapter.MyAdapter;
import com.app.youtubedownloader.Model.VideoDetails;
import com.google.android.youtube.player.YouTubeBaseActivity;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    String API_KEY = "here is my api key";
    ListView listView;
    ArrayList<VideoDetails> videoDetailsArrayList;
    MyAdapter myadapter;
    String url = "https://www.googleapis.com/youtube/v3/search?";
    String part = "snippet";
    ImageButton searchbtn;
    EditText searchfield;
    String keySearch;
    Integer maxResults = 10;
    String order = "title";

    @Override
    protected void onCreate(Bundle savedInstanceState) {

                getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = findViewById(R.id.listvideos);
        videoDetailsArrayList = new ArrayList<>();
        myadapter = new MyAdapter(MainActivity.this, videoDetailsArrayList);
        searchfield = findViewById(R.id.searchfield);
        searchbtn = findViewById(R.id.searchbtn);

        searchbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                keySearch =  searchfield.getText().toString();
                displayVideos();
            }
        });





    }

    public void displayVideos(){
        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());

        url = "https://www.googleapis.com/youtube/v3/search?" + "part=" + part + "&q=" + keySearch + "&maxResults=3" + "&order=" + order + "&key=" + API_KEY;

        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(myadapter);
                    myadapter.notifyDataSetChanged();

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


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


        requestQueue.add(stringRequest);


    }

}

这是用于适配器类的


import android.app.Activity;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.app.youtubedownloader.Model.VideoDetails;
import com.app.youtubedownloader.R;
import com.squareup.picasso.Picasso;

import java.util.ArrayList;

public class MyAdapter extends BaseAdapter {

    public Activity activity;
    public ArrayList<VideoDetails> videoDetailsArrayList;
    public LayoutInflater inflater;

    public MyAdapter(Activity activity, ArrayList<VideoDetails> videoDetailsArrayList){
    this.activity = activity;
    this.videoDetailsArrayList = videoDetailsArrayList;
    }

    @Override
    public Object getItem(int position) {
        return this.videoDetailsArrayList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return (long)position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {

        if(inflater==null){
            inflater = this.activity.getLayoutInflater();
        }

        if( convertView==null){
            convertView = inflater.inflate(R.layout.list_item, null);
        }

        ImageView imageView =  convertView.findViewById(R.id.ImageView);
        TextView textView =  convertView.findViewById(R.id.titleofitem);

        LinearLayout linearLayout =  convertView.findViewById(R.id.root);
        final VideoDetails videoDetails = this.videoDetailsArrayList.get(position);
        linearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent(activity, com.app.youtubedownloader.VideoPlay.class);
                i.putExtra("videoId",videoDetails.getVideoID());
                activity.startActivity(i);

            }
        });



        Picasso.get().load(videoDetails.getUrl()).into(imageView);
        textView.setText(videoDetails.getTitle());


        return  convertView;
    }

    @Override
    public int getCount() {
        return this.videoDetailsArrayList.size();
    }

}

这是给 getter 和 setter 的


public class VideoDetails {
    public String videoID, title, description, url;

    public  VideoDetails(String videoID,String title,String description,String url){
        this.videoID = videoID;
        this.title = title;
        this.description = description;
        this.url = url;
    }
    public VideoDetails(){

    }

    public String getVideoID() {
        return videoID;
    }

    public void setVideoID(String videoID) {
        this.videoID = videoID;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

我认为不需要 XML 文件。谢谢! 附言我试图用邮递员测试我的 url 请求,它可以工作。 编辑:

 "kind": "youtube#searchListResponse",
 "etag": "\"p4VTdlkQv3HQeTEaXgvLePAydmU/zXtOj-qJByP8JvZOdTDcmmhSWNY\"",
 "nextPageToken": "CAMQAA",
 "regionCode": "MD",
 "pageInfo": {
  "totalResults": 1000000,
  "resultsPerPage": 3
 },
 "items": [
  {
   "kind": "youtube#searchResult",
   "etag": "\"p4VTdlkQv3HQeTEaXgvLePAydmU/XnyDQHIyLKnsfFTz76JxER0AjMg\"",
   "id": {
    "kind": "youtube#video",
    "videoId": "aBABkTN8n_w"
   },
   "snippet": {
    "publishedAt": "2018-12-17T12:07:35.000Z",
    "channelId": "UCod_t2sXD_gRI11yFFGkoXg",
    "title": "Best Funny Videos 2018 ● Cute girls doing funny things P3",
    "description": "Hi my friends, please check our new compilation. Here is moments people funny videos and we hope that this video make your life more fun & you enjoy it ...",
    "thumbnails": {
     "default": {
      "url": "https://i.ytimg.com/vi/aBABkTN8n_w/default.jpg",
      "width": 120,
      "height": 90
     },
     "medium": {
      "url": "https://i.ytimg.com/vi/aBABkTN8n_w/mqdefault.jpg",
      "width": 320,
      "height": 180
     },
     "high": {
      "url": "https://i.ytimg.com/vi/aBABkTN8n_w/hqdefault.jpg",
      "width": 480,
      "height": 360
     }
    },
    "channelTitle": "Vines best fun",
    "liveBroadcastContent": "none"
   }
  },
  {
   "kind": "youtube#searchResult",
   "etag": "\"p4VTdlkQv3HQeTEaXgvLePAydmU/W8J9Seta9NO6dAqIWb5gcwfliPo\"",
   "id": {
    "kind": "youtube#video",
    "videoId": "BgluGCjZKjM"
   },
   "snippet": {
    "publishedAt": "2017-06-20T17:26:22.000Z",
    "channelId": "UCeiZcfuj0r1ggNl0N_DVOgQ",
    "title": "Best FAILS &amp; Funny Videos ★ June 2017 Compilation ★ FailCity",
    "description": "Best fails and funny videos compilation of the June 2017! Every week there's new funny fails and awesome win fail video compilations! SUBSCRIBE ғᴏʀ ᴍᴏʀᴇ ...",
    "thumbnails": {
     "default": {
      "url": "https://i.ytimg.com/vi/BgluGCjZKjM/default.jpg",
      "width": 120,
      "height": 90
     },
     "medium": {
      "url": "https://i.ytimg.com/vi/BgluGCjZKjM/mqdefault.jpg",
      "width": 320,
      "height": 180
     },
     "high": {
      "url": "https://i.ytimg.com/vi/BgluGCjZKjM/hqdefault.jpg",
      "width": 480,
      "height": 360
     }
    },
    "channelTitle": "Net Fail",
    "liveBroadcastContent": "none"
   }
  },
  {
   "kind": "youtube#searchResult",
   "etag": "\"p4VTdlkQv3HQeTEaXgvLePAydmU/sy1iQ191YnpipX54MZQ-Z-bd2YU\"",
   "id": {
    "kind": "youtube#channel",
    "channelId": "UCUd0dDUCXsjBPnG1qeUHZLw"
   },
   "snippet": {
    "publishedAt": "2011-01-17T15:26:32.000Z",
    "channelId": "UCUd0dDUCXsjBPnG1qeUHZLw",
    "title": "funnyvideos",
    "description": "",
    "thumbnails": {
     "default": {
      "url": "https://yt3.ggpht.com/-mULWh9j1SAI/AAAAAAAAAAI/AAAAAAAAAAA/wtk972XjVNk/s88-c-k-no-mo-rj-c0xffffff/photo.jpg"
     },
     "medium": {
      "url": "https://yt3.ggpht.com/-mULWh9j1SAI/AAAAAAAAAAI/AAAAAAAAAAA/wtk972XjVNk/s240-c-k-no-mo-rj-c0xffffff/photo.jpg"
     },
     "high": {
      "url": "https://yt3.ggpht.com/-mULWh9j1SAI/AAAAAAAAAAI/AAAAAAAAAAA/wtk972XjVNk/s800-c-k-no-mo-rj-c0xffffff/photo.jpg"
     }
    },
    "channelTitle": "funnyvideos",
    "liveBroadcastContent": "upcoming"
   }
  }
 ]
}

【问题讨论】:

  • 如果您还没有这样做,您应该在 onResponse 覆盖中的“try”下面的第一条指令上放置一个断点,以及同一覆盖中的“catch”中的指令。而且,也在 onErrorResponse 的第一条指令上。向我们展示 onResponse 中返回的字符串,或返回的任何错误消息。您还应该在字符串连接后向我们显示 url(混淆您的 api 密钥)。
  • 你的意思是我应该添加什么断点?而且,没有返回错误,也没有返回来自 Response.ErrorListener 的 toast,因为响应没有错误。而拼接后的网址是这样的https://www.googleapis.com/youtube/v3/search?part=snippet&amp;q=Funnyvideos&amp;order=title&amp;maxResults=3&amp;key=(key)
  • 在您的 onResponse 覆盖中,您应该突出显示这行代码 JSONObject jsonObject = new JSONObject(response);并选择 Run 菜单,然后选择 Toggle Line Breakpoint。这应该在最左边的行号旁边放一个红点(快捷方式,只需点击行号的右侧,红点就会出现。这将导致您的代码在执行期间暂停,以便您可以显示发生了什么返回响应字符串,或者,添加指令 Log.i("My App", "response:" + response); 在 catch e.printStackTrace(); 或 Log.e("My App", e.getLocalizedMessage();
  • 运行应用程序时,请确保单击运行调试(看起来像瓢虫)而不是运行(看起来像三角形),否则,您的代码将不会在断点处停止。
  • 我编辑了问题并在搜索有趣的视频时添加了我在响应字符串中得到的内容

标签: java android android-studio youtube-api


【解决方案1】:

哦,我想我明白了。看起来您的响应恢复正常,并且在处理每个“项目”的“for”循环时,您将获得对象“id”,并且在该对象内部,您正在寻找“videoId”。这很好,除了三个结果中的最后一个,在你的邮递员结果中看起来像这样:

{
 "kind": "youtube#searchResult",
 "etag": "\"p4VTdlkQv3HQeTEaXgvLePAydmU/sy1iQ191YnpipX54MZQ-Z-bd2YU\"",
 "id": {
  "kind": "youtube#channel",
  "channelId": "UCUd0dDUCXsjBPnG1qeUHZLw"
 },

它有一个 channelId 而不是 videoId。你应该做的是将每个 JSON 表达式捕获在它自己的 try/catch 块中,这样一个错误的响应就不会停止你的整个结果。像这样的:

JSONObject jsonObject1 = jsonArray.getJSONObject(i);
JSONObject jsonId = jsonObject1.getJSONObject("id");
String video_id = "";
String channel_id = "";


try {

   video_id = jsonId.getString("videoId");

}catch(JSONException e) {
   channel_id = jsonId.getString("channelId");
}

您可以尝试添加更多日志记录,然后在运行代码时,至少您会通过查看日志知道发生了什么:

    public void displayVideos(){
        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());

        url = "https://www.googleapis.com/youtube/v3/search?" + "part=" + part + "&q=" + keySearch + "&maxResults=3" + "&order=" + order + "&key=" + API_KEY;

        Log.i("My App", "url=" + url);

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {

                Log.i("My App", "response=" + response);

                try{
                    Log.i("My App", "before jsonObject");
                    JSONObject jsonObject = new JSONObject(response);
                    Log.i("My App", "after jsonObject:" + jsonObject.toString());

                    Log.i("My App", "before jsonArray");
                    JSONArray jsonArray = jsonObject.getJSONArray("items");
                    Log.i("My App", "after jsonArray: count=" + jsonArray.length());

                    for(int i=0; i<jsonArray.length(); i++){
                       Log.i("My App", "before jsonObject1");
                        JSONObject jsonObject1 = jsonArray.getJSONObject(i);
                       Log.i("My App", "after jsonObject1:" + jsonObject1.toString());

                        Log.i("My App", "before jsonVideoId");
                        JSONObject jsonVideoId = jsonObject1.getJSONObject("id");
                        Log.i("My App", "after jsonVideoId:" + jsonVideoId.toString());    

...  (your other code here)

                        Log.i("My App", "before videoId");  
                        String video_id = jsonVideoId.getString("videoId");
                        Log.i("My App", "after videoId:" + video_id); 

... (your other code here)   

                    }

                    listView.setAdapter(myadapter);
                    myadapter.notifyDataSetChanged();

                } catch(JSONException e){
                    Log.e("My App", e.getLocalizedMessage());
                    e.printStackTrace();
                }


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


        requestQueue.add(stringRequest);


    }

}

【讨论】:

  • 我尝试使用您上面的代码序列,但也没有任何反应,并且我尝试修改for(int i=0; i&lt;1; i++) 中的for(int i=0; i&lt;jsonArray.length(); i++) 部分以获得仅存在videoId 的部分,但无论如何它不工作
  • 但是当我尝试for(int i=0; i&lt;1; i++时,断点异常没有返回任何内容,所以异常消失了,但视频仍然没有显示
  • 我不记得是 jsonArray.length() 还是 jsonArray.count() 但这是要走的路。如果你说 i
  • 我知道如果我使用 i
  • 尝试使用&type=video,没有任何反应,当我搜索时仍然没有任何内容,并且jsonarray.count不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-15
  • 1970-01-01
  • 1970-01-01
  • 2016-12-27
  • 1970-01-01
  • 2013-07-16
  • 2017-07-30
相关资源
最近更新 更多