2016-10-10 5 views
0

ユーザーテキストの入力とGoogle Books APIの検索が必要なアプリに問題があります。これまでのところ、私は正常にユーザー入力を受け取り、それをクエリ文字列に追加し、AsyncTaskを開始し、HttpRequestを開始し、inputStreamを取得して文字列を構築し、文字列から項目の配列を作成してから、アダプターを使用して、ユーザーの画面にその書籍のリストを表示します。Android Java:APIからのすべての応答を表示するListViewのトラブル

私が抱えている問題は、コードが実行されると(ユーザーが入力したものに関係なく、食べ物、ギリシャ、アンドロイドなど)、画面に表示される応答が1つだけになるということです。なぜ1つの本しか出てこないのか分かりません。 APIクエリ文字列は10を指定しています(2、4、& 7も使用しています)が最大の結果を示していますが、これまでに1つのリストしか取得できませんでした。デバッガでチェックした後、特定の長さの入力の後にStringbuilderが停止するか、またはarraylistが残りのJSONObjectのインデックスを作成していないかのいずれかに絞り込んだ。以下は

帳アクティビティコードです:誰でもを台無しに全体のコードを持っているしたい場合はここで

package com.ovidioreyna.android.googlebooksapiapp; 

import android.content.Context; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.text.TextUtils; 
import android.util.Log; 
import android.widget.ListView; 

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

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.nio.charset.Charset; 
import java.util.ArrayList; 

import static com.ovidioreyna.android.googlebooksapiapp.MainActivity.LOG_TAG; 


public class BooksActivity extends AppCompatActivity { 

    //Creates blank global string which will be used the search parameters in this class 
    public String gglBookSearch = "https://www.googleapis.com/books/v1/volumes?q="; 

    //After the user enters what they want to search for we pass that in from the main activity 
    //and add it to our global variable here. We then add some modifiers so that we can control 
    //the amount of info being return. This will later be changed to 10 once the app is functioning 

    Context context = this; 

    String jsonResponse = ""; 

    ListView booksListView; 
    BookAdapter adapter; 

    //inflates the book_layout.xml so we can see the book info 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.book_list); 

     //passes the user input to this activity 
     Bundle extras = getIntent().getExtras(); 
     if (extras != null) { 
      String textSearchUpdate = extras.getString("EDITTEXTUPDATE"); 
      //takes user input and appends it to the initial Google Books API Query 
      updateApiSearch(textSearchUpdate); 
     } 

     //creates an instance of BooksAsynTask and executes it 
     BooksAsyncTask task = new BooksAsyncTask(); 
     task.execute(); 
    } 

    //Sets the appropriate info to the appropriate textviews 
    private void updateUi(ArrayList<Books> books) { 

     //creates an instance of the book list 
     booksListView = (ListView) findViewById(R.id.book_list); 

     //creates an instance of the book adapter 
     adapter = new BookAdapter(context, new ArrayList<Books>()); 

     //sets the adapter to the listview.xml 
     booksListView.setAdapter(adapter); 

     //in case user initiates multiple searches then we need to clear the adapter to start with 
     //clean adapter for the new search 
     adapter.clear(); 
     adapter.addAll(books); 
     adapter.notifyDataSetChanged(); 
    } 


    private class BooksAsyncTask extends AsyncTask<URL, Void, ArrayList<Books>> { 
     @Override 
     protected ArrayList<Books> doInBackground(URL... urls) { 
      //creates a new url object from the @gglBookSearch query 
      URL url = createUrl(gglBookSearch); 

      try { 
       //creates a string that will hold the raw data for the jsonarray 
       jsonResponse = makeHttpRequest(url); 
       Log.i(LOG_TAG, "JSON Results: " + jsonResponse); 
      } catch (IOException e) { 
       Log.e(LOG_TAG, "Error with make request", e); 
      } 

      //takes the raw string data and extracts it into an array 
      return extractBooks(jsonResponse); 
     } 

     @Override 
     protected void onPostExecute(ArrayList<Books> books) { 
      //checks to make sure that the arraylist books is not empty 
      if (books == null) { 
       return; 
      } 
      //if all goes well and books is populated then it displays that info 
      updateUi(books); 
     } 

     private URL createUrl(String stringUrl) { 
      //creates a new url object from the string passed in 
      URL url = null; 
      try { 
       url = new URL(stringUrl); 
      } catch (MalformedURLException exception) { 
       Log.e(LOG_TAG, "Error with creating URL", exception); 
      } 

      return url; 
     } 

     public ArrayList<Books> extractBooks(String jsonResponse) { 

      //craetes a new Arraylist that will hold all the json data 
      ArrayList<Books> books = new ArrayList<>(); 

      //checks to see that the string passed in is not empty 
      if (TextUtils.isEmpty(jsonResponse)) { 
       return null; 
      } 
      try { 
       //creates a jsonObject to hold the data. Then delves into the Array items 
       JSONObject baseJsonResponse = new JSONObject(jsonResponse); 
       JSONArray itemsArray = baseJsonResponse.getJSONArray("items"); 
       Log.i(LOG_TAG, "Length of books array: " + itemsArray.length()); 

       //create empty local variables in case the JSON objects are null 
       String bookTitle = ""; 
       String bookSubtitle = ""; 
       String author = ""; 
       String publishedDate = ""; 

       for (int i = 0; i < itemsArray.length(); i++) { 
        //checks to see that the Array isn't empty 
        if (itemsArray.length() > 0) { 
         JSONObject firstItem = itemsArray.getJSONObject(i); 

         JSONObject volumeInfo = firstItem.getJSONObject("volumeInfo"); 

         //checks to see if object is null, if not then executes code 
         if (!volumeInfo.isNull("title")) { 
          bookTitle = volumeInfo.getString("title"); 
         } 

         //checks to see if object is null, if not then executes code 
         if (!volumeInfo.isNull("subtitle")) { 
          bookSubtitle = volumeInfo.getString("subtitle"); 
         } 

         //creates an jsonArray object from the authors array 
         JSONArray authorArray = volumeInfo.getJSONArray("authors"); 
         if (!authorArray.isNull(i)) { 
          if (authorArray.length() == 1) { 
           author = authorArray.getString(i); 
          } else { 
           for (int k = 0; k < authorArray.length(); k++) { 
            //checks to see if object is null, if not then executes code 
            if (!authorArray.isNull(k)) { 
             author = authorArray.getString(k) + ","; 
            } 
           } 
          } 
         } 

         //checks to see if object is null, if not then executes code 
         if (!volumeInfo.isNull("publishedDate")) 
          publishedDate = volumeInfo.getString("publishedDate"); 

         //create a new instance of the Books class 
         Books book = new Books(bookTitle, bookSubtitle, author, publishedDate); 
         books.add(book); 
        } 

        return books; 
       } 


      } catch (JSONException e) { 
       Log.e(LOG_TAG, "Problem with parsing the books JSON results", e); 
      } 
      //if there is an error in the code above it returns null 
      return null; 
     } 

     private String makeHttpRequest(URL url) throws IOException { 


      //checks to see that the url object passed in is not empty. If empty then returns an 
      //empty string 
      if (url == null) { 
       return jsonResponse = ""; 
      } 
      //creates two empty objects 
      HttpURLConnection urlConnection = null; 
      InputStream inputStream = null; 

      //this is where we try to establish a connection and if successful take the input info 
      //and convert it into a usable form 
      try { 
       urlConnection = (HttpURLConnection) url.openConnection(); 
       urlConnection.setRequestMethod("GET"); 
       urlConnection.setReadTimeout(10000 /* milliseconds */); 
       urlConnection.setConnectTimeout(15000 /* milliseconds */); 
       urlConnection.connect(); 

       if (urlConnection.getResponseCode() == 200) { 
        //if we get a success code from the server we proceed to convert the bits and 
        //bytes into a usuable form and ultimately convert it into a usable string. 
        inputStream = urlConnection.getInputStream(); 
        jsonResponse = readFromStream(inputStream); 
       } else { 
        //if we don't get a success code from the server we log it. 
        Log.e(LOG_TAG, "Error Response Code: " + urlConnection.getResponseCode()); 
       } 
      } catch (IOException e) { 
       Log.e(LOG_TAG, "Problem With Connection: ", e); 
      } finally { 
       //regardless if we are successful gettting an inputstream or not we disconnect and 
       //close the inputstream 
       if (urlConnection != null) { 
        urlConnection.disconnect(); 
       } 
       if (inputStream != null) { 
        inputStream.close(); 
       } 
      } 

      //returns the string @jsonResponse whether it's empty or has information 
      return jsonResponse; 
     } 

     //uses StringBuilder to take the raw bits and make a legible string from it 
     private String readFromStream(InputStream inputStream) throws IOException { 
      StringBuilder output = new StringBuilder(); 
      if (inputStream != null) { 
       InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8")); 
       BufferedReader reader = new BufferedReader(inputStreamReader); 
       String line = reader.readLine(); 
       while (line != null) { 
        output.append(line); 
        line = reader.readLine(); 
       } 
      } 

      //once the entire input stream has been built we output it to a string 
      return output.toString(); 
     } 
    } 

    //takes the input text from the user and concatonates it to the query as well as adding a limit 
    //of 10 books at a time 
    public void updateApiSearch(String updatedEditText) { 
     gglBookSearch += updatedEditText; 
     gglBookSearch += "&maxResults=10"; 
    } 
} 

は全体のレポへのリンクです:

https://github.com/ovidioreyna/GoogleBooksAPIApp

に感謝あなたの助けを前にして

更新:

は、だから私はjsonResponse = makeHttpRequest(url);後のJSONの結果を表示するには、ログイベントを作成し、ログはこのことを示した:私も配列であり、それが10として表示されますどのくらいの時間を示すためにログイベントを追加しました

10-09 20:50:36.846 32119-32463/com.ovidioreyna.android.googlebooksapiapp I/MainActivity: JSON Results: { "kind": "books#volumes", "totalItems": 1431, "items": [ { "kind": "books#volume", "id": "vdXmDAAAQBAJ", "etag": "pSHAL8HBKSs", "selfLink": "https://www.googleapis.com/books/v1/volumes/vdXmDAAAQBAJ", "volumeInfo": { "title": "Molly on the Range", "subtitle": "Recipes and Stories from an Unlikely Life on a Farm", "authors": [  "Molly Yeh" ], "publisher": "Rodale", "publishedDate": "2016-10-04", "description": "In 2013, food blogger and classical musician Molly Yeh left Brooklyn to live on a farm on the North Dakota-Minnesota border, where her fiancé was a fifth-generation Norwegian-American sugar beet farmer. Like her award-winning blog My Name is Yeh, Molly on the Range chronicles her life through photos, more than 120 new recipes, and hilarious stories from life in the city and on the farm. Molly’s story begins in the suburbs of Chicago in the 90s, when things like Lunchables and Dunkaroos were the objects of her affection; continues into her New York years, when Sunday mornings meant hangovers and bagels; and ends in her beloved new home, where she’s currently trying to master the art of the hotdish. Celebrating Molly's Jewish/Chinese background with recipes for Asian Scotch Eggs and Scallion Pancake Challah Bread and her new hometown Scandinavian recipes for Cardamom Vanilla Cake and Marzipan Mandel Bread, Molly on the Range will delight everyone, from longtime readers to those discovering her glorious writing and recipes for the first time.", "industryIdentifiers": [  {  "type": "ISBN_13",  "identifier": "9781623366957"  },  {  "type": "ISBN_10",  "identifier": "162336695X"  } ], "readingModes": {  "text": false,  "image": false }, "pageCount": 304, "printType": "BOOK", "categories": [  "Cooking" ], "maturityRating": "NOT_MATURE", "allowAnonLogging": false, "contentVersion": "1.1.1.0.preview.0", "imageLinks": {  "smallThumbnail": "http://books.google.com/books/content?id=vdXmDAAAQBAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",  "thumbnail": "http://books.google.com/books/content?id=vdXmDAAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api" }, "language": "en", "previewLink": "http://books.google.com/books?id=vdXmDAAAQBAJ&printsec=frontcover&dq=Food&hl=&cd=1&source=gbs_api", "infoLink": "http://books.google.com/books?id=vdXmDAAAQBAJ&dq=Food&hl=&source=gbs_api", "canonicalVolumeLink": "http://books.google.com/books/about/Molly_on_the_Range.html?hl=&id=vdXmDAAAQBAJ" }, "saleInfo": { "country": "US", "saleability": "NOT_FOR_SALE", "isEbook": false }, "accessInfo": { "country": "US", "viewability": "PARTIAL", "embeddable": true, "publicDomain": false, "textToSpeechPermission": "ALLOWED", "epub": {  "isAvailable": false }, "pdf": {  "isAvailable": false }, "webReaderLink": "http://books.google.com/books/reader?id=vdXmDAAAQBAJ&hl=&printsec=frontcover&output=reader&source=gbs_api", "accessViewStatus": "SAMPLE", "quoteSharingAllowed": false }, "searchInfo": { "textSnippet": "Celebrating Molly&#39;s Jewish/Chinese background with recipes for Asian Scotch Eggs and Scallion Pancake Challah Bread and her new hometown Scandinavian recipes for Cardamom Vanilla Cake and Marzipan Mandel Bread, Molly on the Range will ..." } }, { "kind": "books#volume", "id": "DY-dBAAAQBAJ", "etag": "t4JLTMFKOGc", "selfLink": "https://www.googleapis.com/books/v1/volumes/DY-dBAAAQBAJ", "volumeInfo": { "title": "Real Baby Food", "subtitle": "Easy, All-Natural Recipes for Your Baby and Toddler", "authors": [  "Jenna Helwig" ], "publisher": "Houghton Mifflin Harcourt", "publishedDate": "2015-04-28", "description": "Simple Recipes for a Wholesome Start Nothing compares with making your own baby food: It's fresh and unprocessed, you choose what goes into it, and it is a delicious way to introduce your child to a world of flavors. In Real Baby Foo 
10-09 20:50:36.861 32119-32463/com.ovidioreyna.android.googlebooksapiapp I/MainActivity: Length of books array: 10 

どのHttpRequestメソッドから2つのインスタンスしか書かれていないので、奇妙です。

+1

これまで見てきたように、レスポンスから結果が得られるたびにアダプタを作成するので、listViewは新しいデータでしか埋められません。リストビュー用に1つのアダプターを作成し、新しいアダプターに置き換えるのではなく、単にそのアダプターのデータを更新するだけです。 – Bennyhuo

+0

私はあなたが言っていることを理解することができますが、私はそれをどのように実装するかはわかりません。アダプタ宣言をグローバル変数にする必要がありますか?意味は、私は本のアダプターを作成する場所の上に 'adapter = new BookAdapter(context、new ArrayList ());'この行を移動する必要がありますか? –

+1

そうです。あなたの "1冊の"問題を解決するには、私の答えを見てください。 – Bennyhuo

答えて

1

for-loopであまりにも早い時期に書籍を返送しました。 BooksActivityの144-186行で注意深く確認してください。

  for (int i = 0; i < itemsArray.length(); i++) { 
       //checks to see that the Array isn't empty 
       if (itemsArray.length() > 0) { 
        JSONObject firstItem = itemsArray.getJSONObject(i); 

        JSONObject volumeInfo = firstItem.getJSONObject("volumeInfo"); 

        //checks to see if object is null, if not then executes code 
        if (!volumeInfo.isNull("title")) { 
         bookTitle = volumeInfo.getString("title"); 
        } 

        //checks to see if object is null, if not then executes code 
        if (!volumeInfo.isNull("subtitle")) { 
         bookSubtitle = volumeInfo.getString("subtitle"); 
        } 

        //creates an jsonArray object from the authors array 
        JSONArray authorArray = volumeInfo.getJSONArray("authors"); 
        if (!authorArray.isNull(i)) { 
         if (authorArray.length() == 1) { 
          author = authorArray.getString(i); 
         } else { 
          for (int k = 0; k < authorArray.length(); k++) { 
           //checks to see if object is null, if not then executes code 
           if (!authorArray.isNull(k)) { 
            author = authorArray.getString(k) + ","; 
           } 
          } 
         } 
        } 

        //checks to see if object is null, if not then executes code 
        if (!volumeInfo.isNull("publishedDate")) 
         publishedDate = volumeInfo.getString("publishedDate"); 

        //create a new instance of the Books class 
        Books book = new Books(bookTitle, bookSubtitle, author, publishedDate); 
        books.add(book); 
       } 
//See that? You return your books with only one extracted from your itemArray!!!! 
       return books; 
      } 
+0

Bennyhuo、あなたは素晴らしいです!気づいてくれてありがとう。私はちょうどライン188でブレースを通過し、それらのすべてをロード!再度、感謝します! –

関連する問題