Search code examples
android-studiokotlinandroid-volleyjsonobjectrequestmalformedurlexception

Bad URL Performing Second Volley Request Android Studio


New to mobile dev and following along a set of video tutorials. I perform a JSON Object request at the beginning of an activity. I need to perform a second request, but this time for an image using a link that I get from the JSON Object. The first request mostly works, updating all but one of my TextViews. The TextView containing the link to the image just says "https://" instead of the entire link and the ImageView does not change at all because the image requeest fails due to a "Bad URL".

This is the version of Volley I am currently using:

implementation 'com.android.volley:volley:1.2.1'

My first request looks like this:

val request = JsonObjectRequest(Request.Method.GET, requestURL, null, { response ->

            for (i in 0 until response.length()) {
                txtName.text = getString(R.string.name,response.getString("Title"))
                txtRating.text = getString(R.string.rating,response.getString("Rated"))
                txtSummary.text = getString(R.string.summary, response.getString("Plot"))
                txtGenre.text = getString(R.string.genre,response.getString("Genre"))
                txtLength.text = getString(R.string.length,response.getString("Runtime"))           
                txtUrl.text = getString(R.string.url,response.getString("Poster"))

                Log.d("Poster Link", posterLink)
            }
            Log.d("Response", "$response")
        }, {

            Log.d("Error Message", "Error: ${it.message}")
        })

        request.setShouldCache(false)
        RequestHandler.getInstance(applicationContext).addToRequestQueue(request)

I have it in onCreate. The request works, it changes most of the TextViews to display the fields I request except for the link TextView. In case this helps, in the logcat this is the information I get from my request for this particular search:

{"Title":"Star Wars: Episode IV - A New Hope","Year":"1977","Rated":"PG","Released":"25 May 1977","Runtime":"121 min","Genre":"Action, Adventure, Fantasy","Director":"George Lucas","Writer":"George Lucas","Actors":"Mark Hamill, Harrison Ford, Carrie Fisher","Plot":"Luke Skywalker joins forces with a Jedi Knight, a cocky pilot, a Wookiee and two droids to save the galaxy from the Empire's world-destroying battle station, while also attempting to rescue Princess Leia from the mysterious Darth ...","Language":"English","Country":"United States","Awards":"Won 6 Oscars. 65 wins & 31 nominations total","Poster":"https:\/\/m.media-amazon.com\/images\/M\/MV5BOTA5NjhiOTAtZWM0ZC00MWNhLThiMzEtZDFkOTk2OTU1ZDJkXkEyXkFqcGdeQXVyMTA4NDI1NTQx._V1_SX300.jpg","Ratings":[{"Source":"Internet Movie Database","Value":"8.6\/10"},{"Source":"Rotten Tomatoes","Value":"93%"},{"Source":"Metacritic","Value":"90\/100"}],"Metascore":"90","imdbRating":"8.6","imdbVotes":"1,393,554","imdbID":"tt0076759","Type":"movie","DVD":"06 Dec 2005","BoxOffice":"$460,998,507","Production":"N\/A","Website":"N\/A","Response":"True"}

Then I have a function that requests the image that looks like this:

fun imgRequest(link : String){
var img = createBitmap(1000,1000)

        val imageRequest = ImageRequest(link, { response ->
            img = response

            Log.d("Image Request Function", "Image requested")
        }, 0,  0, ImageView.ScaleType.FIT_CENTER, Bitmap.Config.ARGB_8888,
            {
                Log.d("Error Message", "Error: ${it.message}")
            })

        imageRequest.setShouldCache(false)
        RequestHandler.getInstance(applicationContext).addToRequestQueue(imageRequest)

        imgView.setImageBitmap(img)
}

I have tried both calling the function after the JSON Object request and also just ditching the function and posting the image request after the object request. It is basically just supposed to change the ImageView that I have, "imgView", to the image I request. I used "Log.d" to see if it was even getting the link properly and in the logcat during the first request, the Log.d message containing just the link looks like this: https://m.media-amazon.com/images/M/MV5BOTA5NjhiOTAtZWM0ZC00MWNhLThiMzEtZDFkOTk2OTU1ZDJkXkEyXkFqcGdeQXVyMTA4NDI1NTQx._V1_SX300.jpg and when I click on it, the image successfully pops up in a new window. Though for some reason, outside of the request, it turns into just "https://" when I set the TextView.text to it. Additionally, the Logcat provides me with this message upon image request failure:

[1094] NetworkDispatcher.processRequest: Unhandled exception java.lang.RuntimeException: Bad URL 
                                                                                                    java.lang.RuntimeException: Bad URL 
                                                                                                    

The videos I was following along with placed this task at the end of the video as a sort of independent challenge so it's not like I can find the solution there. I have tried moving the image request around, I have tried to declare the Bitmap to store the image in up at the top of the script right above onCreate, I tried to declare an empty var string "link" there as well and then change it to the link after the object response. I also tried to just perform the image request within the JSON object request but that really didn't work. I do not know what is wrong and where I should be looking to fix this.


Solution

  • My assumption is that there are special characters that need to be encoded in the URL that are trying to be used directly. It's good practice to sanitize urls before launching an image request.

    For instance use Uri.Builder().parse(amazonImgUrl).toString() to encode the url before launching the ImageRequest.