0

I am a beginning computer science student. For school I have to make an app that can display data from an API. I use this API: http://openlibrary.org/search.json?q= The user of my app has to enter a booktitle or author, so they can find a book. I add the search value to the url. For example, if I want to search "The hobbit", the url would look like this: http://openlibrary.org/search.json?q=the%hobbit". However, the data does not get displayed. I don't have any errors either. Is there anyone that can help me? Thanks in advance!

My API service class

private const val BASE_URL = "http://openlibrary.org/"

private val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .build()

private val retrofit = Retrofit.Builder()
    .addConverterFactory(MoshiConverterFactory.create(moshi))
    .baseUrl(BASE_URL)
    .build()



interface BoekenAPIService {
    @GET("search.json")
    suspend fun getBooksByTitle(@Query("q")search: String) : Base_BookTitle
}

object BookAPI {
    val retrofitService : BoekenAPIService by lazy { retrofit.create(BoekenAPIService::class.java) }
}

My Base_BookTitle class

data class Base_BookTitle (
    val numFound : Int,
    val start : Int,
    val numFoundExact : Boolean,
    val docs : List<Q>,
    val num_found : Int,
    val book : String,
    val offset : String
)

My Q class

@Parcelize
data class Q (
    val key : String,
    val type : String,
    val seed : List<String>,
    val title : String,
    val title_suggest : String,
    val has_fulltext : Boolean,
    val edition_count : Int,
    val edition_edition_key : List<String>,
    val publish_date : List<String>,
    val publish_year : List<Int>,
    val first_publish_year : Int,
    val number_of_pages_median : Int,
    val lccn : List<Int>,
    val publish_place : List<String>,
    val oclc : List<Int>,
    val contributor : List<String>,
    val lcc : List<String>,
    val ddc : List<Double>,
    val isbn : List<Int>,
    val last_modified_i : Int,
    val ebook_count_i : Int,
    val ia : List<String>,
    val public_scan_b : Boolean,
    val ia_collection_s : String,
    val lending_edition_s : String,
    val lending_identifier_s : String,
    val printdisabled_s : String,
    val cover_edition_cover_edition_key : String,
    val cover_i : Int,
    val publisher : List<String>,
    val language : List<String>,
    val author_author_key : List<String>,
    val author_name : List<String>,
    val author_alternative_name : List<String>,
    val person : List<String>,
    val place : List<String>,
    val subject : List<String>,
    val time : List<String>,
    val id_alibris_id : List<Int>,
    val id_amazon : List<String>,
    val id_canadian_national_library_archive : List<Int>,
    val id_depósito_legal : List<String>,
    val id_goodreads : List<Int>,
    val id_google : List<String>,
    val id_librarything : List<Int>,
    val id_overdrive : List<String>,
    val id_paperback_swap : List<Int>,
    val id_wikidata : List<String>,
    val ia_loaded_id : List<String>,
    val ia_box_id : List<String>,
    val publisher_facet : List<String>,
    val person_person_key : List<String>,
    val place_place_key : List<String>,
    val time_facet : List<String>,
    val person_facet : List<String>,
    val subject_facet : List<String>,
    val _version_ : Int,
    val place_facet : List<String>,
    val lcc_sort : String,
    val author_facet : List<String>,
    val subject_subject_key : List<String>,
    val ddc_sort : Double,
    val time_time_key : List<String>
): Parcelable

I got the Base_Booktitle and Q class from a json to kotlin converter.

The ViewModel in which i call the method to display the data

class SearchViewModel(__user: User) : ViewModel() {
   var _user = MutableLiveData<User>()
   val user:LiveData<User>
       get() {
           return _user
       }
   var _baseBookTitle = MutableLiveData<Base_BookTitle?>()
   val baseBooktitle : LiveData<Base_BookTitle?>
   get() {
       return _baseBookTitle
   }
   var search = MutableLiveData<String>()
   var _error = MutableLiveData<String>()
   val error : LiveData<String>
   get() {
       return _error
   }
   var _response = MutableLiveData<Q?>()
   val response: LiveData<Q?>
   get(){
       return _response
   }
   init {
       _user.value = __user
       _error.value = null

   }
   fun searchBtnClicked(){
       viewModelScope.launch {
           try{
               _baseBookTitle.value = BookAPI.retrofitService.getBooksByTitle(search.value!!)
           }
           catch (e: Exception){
               _error.value = e.localizedMessage
           }
       }
   }
   fun onBookClicked(book: Q){
       _response.value = book
   }
   fun navigateToBookFinished(){
       _response.value = null
   }
}

Thanks to a comment, I am now able to use a LoggingIntercepter

This is what I see in the logcat when I click the search button

2022-01-07 11:24:50.035 18171-18233/be.nienke.eindopdracht D/OkHttp: --> GET http://openlibrary.org/search.json?q=hobbit
2022-01-07 11:24:50.035 18171-18233/be.nienke.eindopdracht D/OkHttp: --> END GET
2022-01-07 11:24:50.055 18171-18215/be.nienke.eindopdracht I/OpenGLRenderer: Davey! duration=1591ms; Flags=0, IntendedVsync=183638171307131, Vsync=183639721307069, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=183639736870720, AnimationStart=183639736926020, PerformTraversalsStart=183639737189320, DrawStart=183639737431620, SyncQueued=183639738395720, SyncStart=183639738576620, IssueDrawCommandsStart=183639739072520, SwapBuffers=183639760591820, FrameCompleted=183639762891920, DequeueBufferDuration=250000, QueueBufferDuration=644000, 
2022-01-07 11:24:50.237 18171-18233/be.nienke.eindopdracht D/OkHttp: <-- HTTP FAILED: java.net.UnknownServiceException: CLEARTEXT communication to openlibrary.org not permitted by network security policy

To solve the UnknownServiceException, I added this line to the AndroidManifest file:

android:usesCleartextTraffic="true"

Now the logcat shows the data from my API, but it doesn't display it on screen. Anyone that can help?

Nienke
  • 1
  • 4

1 Answers1

0

Changing http to https in BASE_URL solved it for me