I am developing a meme app in which you can share memes. I have used
"https://meme-api.herokuapp.com/gimme"
for API. Whenever I try to run the code I do not get the image.
I am new to kotlin and stuck in this for hours
MainActivity.kt
package com.example.memeapp
import android.os.Bundle
import android.view.View
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import com.android.volley.Request
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley
import com.bumptech.glide.Glide
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
private fun loadMeme(){
val queue = Volley.newRequestQueue(this)
val url = "https://meme-api.herokuapp.com/gimme"
// Request a string response from the provided URL.
val jsonObjectRequest = JsonObjectRequest(
Request.Method.GET, url,null,
{ response ->
val url = response.getString("url")
val meme:ImageView= findViewById(R.id.memeImageView)
print(url)
Glide.with(this).load(url).into(meme)
},
{
})
queue.add(jsonObjectRequest)
}
fun nextMeme(view: View) {
}
fun shareMeme(view: View) {
}
}
the image is not showing but the buttons are showing, Note: the buttons are currently null.
// Request a string response from the provided URL.
val jsonObjectRequest = JsonObjectRequest(
Request.Method.GET, url,null,
Response.Listener {response ->
val url = response.getString("url")
Glide.with(this).load(url).into(meme)
},
Response.ErrorListener{
Toast.makeText(this,"Something wrong", Toast.LENGTH_lONG).show()
})
queue.add(jsonObjectRequest)
}
Related
error : "Not enough information to infer type variable T", I get this error while parsing Json
Here is my code:
package com.example.chatopenai
import android.os.Bundle
import android.util.Log
import android.widget.EditText
import android.widget.ImageButton
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import okhttp3.OkHttpClient
import okhttp3.ResponseBody
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Body
import retrofit2.http.HeaderMap
import retrofit2.http.POST
class MainActivity : AppCompatActivity() {
private lateinit var questionEditText: EditText
private lateinit var answerTextView: TextView
private lateinit var generateButton: ImageButton
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Get references to the UI elements
questionEditText = findViewById(R.id.message_input)
answerTextView = findViewById(R.id.textAns)
generateButton = findViewById(R.id.sendBtn)
// Set up the generate button click listener
generateButton.setOnClickListener {
// Get the user's question from the EditText
val question = questionEditText.text.toString()
// Send the request to the API
generateText(question)
}
}
// Service interface for the OpenAI API
interface OpenAIService {
#POST("v1/images/generations")
fun generateText(
#HeaderMap headers: Map<String, String>,
#Body request: Map<String, Any>
): Call<ResponseBody>
}
// Data class to hold the API response
data class ResponseData(val data: Data)
data class Data(val text: String)
private fun generateText(prompt: String) {
// Create a logger for debugging purposes
val logger = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
// Add the logger to the HTTP client
val client = OkHttpClient.Builder()
.addInterceptor(logger)
.build()
// Configure the Retrofit object
val retrofit = Retrofit.Builder()
.baseUrl("https://api.openai.com/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
// Create an instance of the OpenAIService
val service = retrofit.create(OpenAIService::class.java)
// Set the request parameters
// Set the request parameters
val request = mapOf(
"prompt" to prompt,
"model" to "text-davinci-002"
)
// Set the request headers
val headers = mapOf(
"Content-Type" to "application/json",
"Authorization" to "Bearer MY_API_KEY"
)
// Make the API request
service.generateText(headers, request).enqueue(object : Callback<ResponseBody> {
override fun onResponse(
call: Call<ResponseBody>,
response: Response<ResponseBody>
) {
if (response.isSuccessful) {
// Parse the JSON response
val gson = Gson()
val responseString = response.body()!!.string()
val type = object : TypeToken<ResponseData>() {}.type
//I am getting error on below line on fromJson
val responseData = gson.fromJson(response.body()?.string(), type)
Log.d("JSON response", responseString)
Log.d("Type", type.toString())
// Display the response text in the TextView
answerTextView.text = responseData.data.text
} else {
// Display the error message in the TextView
answerTextView.text = response.errorBody()?.string()
}
}
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
// Display the error message in the TextView
answerTextView.text = t.message
}
})
}
}
Please help me to fix this bug or let me know I missed any dependencies. I have mentioned where is the bug on the code.
Aplogize for my bad code
I tried to modify the code but not resolved. May be I missed some dependencies I don't know. Please help me to solve and fix this error
I need to send GET request with body from android application, but it seems that volley ignore it (body). It's always empty on the server side.
I was trying to send body in request and ovverride getBody() - no effect.
In Request.java I saw the comment that getBody only send body for POST or PUT.
Maybe I need to override another method or need to use another library for such task?
My last custom request:
package by.lsd.rmapiconnector
import com.android.volley.NetworkResponse
import com.android.volley.ParseError
import com.android.volley.Response
import com.android.volley.toolbox.HttpHeaderParser
import com.android.volley.toolbox.JsonRequest
import org.json.JSONArray
import org.json.JSONException
import java.io.ByteArrayOutputStream
import java.io.ObjectOutputStream
import java.io.UnsupportedEncodingException
import java.nio.charset.Charset
class CustomJsonRequest(
method: Int,
url: String?,
requestObject: HashMap<String, Any>,
private val mResponseListener: Response.Listener<JSONArray>,
errorListener: Response.ErrorListener?
) : JsonRequest<JSONArray>(
method,
url,
requestObject.toString(),
mResponseListener,
errorListener
) {
private val mRequestObject = requestObject
override fun deliverResponse(response: JSONArray) {
mResponseListener.onResponse(response)
}
override fun parseNetworkResponse(response: NetworkResponse): Response<JSONArray> {
return try {
val json = String(response.data, Charset.forName(HttpHeaderParser.parseCharset(response.headers)))
try {
Response.success(
JSONArray(json),
HttpHeaderParser.parseCacheHeaders(response)
)
} catch (e: JSONException) {
Response.error(ParseError(e))
}
} catch (e: UnsupportedEncodingException) {
Response.error(ParseError(e))
}
}
override fun getHeaders(): Map<String, String> {
val headers: HashMap<String, String> = HashMap()
headers["Accept"] = "application/json"
headers["Content-Type"] = "application/json"
//headers["Transfer-Encoding"] = "chunked"
return headers
}
override fun getBody(): ByteArray {
val byteOut = ByteArrayOutputStream()
val out = ObjectOutputStream(byteOut)
out.writeObject(mRequestObject)
return byteOut.toByteArray()
}
}
I would like to send a request volley connection to this api below to get this online data to make a for loop inside getAllData function, so how can i do
code below
the api: https://adeega.xisaabso.online/android.php
Person.kt model
package com.example.first_jetpackcompose_app.model
data class Person(
val id: Int,
val firstName: String,
val lastName: String,
val description: String,
val age: Int
)
PersonRepository.kt model
package com.example.first_jetpackcompose_app.repository
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.core.content.ContentProviderCompat.requireContext
import com.android.volley.Request
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import com.example.first_jetpackcompose_app.MainActivity
import com.example.first_jetpackcompose_app.model.Person
import java.security.AccessController.getContext as getContext1
class PersonRepository {
fun getAllData(): List<Person> {
// Instantiate the RequestQueue.
val queue = Volley.newRequestQueue(this)
val url = "https://adeega.xisaabso.online/android.php"
val stringRequest = StringRequest(
Request.Method.GET, url,
{ response ->
//textView.text = "Response is: ${response.substring(0, 500)}"
Toast.makeText(this, "Response is: ${response.substring(0, 500)}", Toast.LENGTH_SHORT).show()
},
{
Toast.makeText(this, "That didn't work!", Toast.LENGTH_SHORT).show()
//textView.text = "That didn't work!"
})
queue.add(stringRequest)
return listOf(
Person(
id = 0,
firstName = "John",
lastName = "Doe",
description = "i'm learning how to request volley connection",
age = 20
)
)
}
}
I am trying to get data from an Http request to my own API. Running the request in my browser (swapping the IP with localhost) gets me:
["Herbalism","Mining","Skinning","Alchemy","Blacksmithing","Enchanting","Engineering","Inscription","Jewelcrafting","Leatherworking","Tailoring","Archaeology","Cooking","Fishing"]
I am using the following code, modified from the example provided here: https://www.tutorialspoint.com/how-to-use-volley-library-to-parse-json-in-android-kotlin-app
It does not print my "Print anything at all". From what I can tell this does nothing. I have tried many different things including suggestions from here: Can I do a synchronous request with volley? and here: Volley Timeout Error and feel that I am in no way closer to getting this request to work. The firewall permits this traffic. The catch JSONException and Response.ErrorListener are also not putting anything out. I am using plain http, no certs or anything. Ultimately I want to populate a Spinner with this data but for now I can't even get this most basic implementation to work.
package com.wowahapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.*
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.Response
import com.android.volley.toolbox.*
import org.json.JSONException
class AddRecipeActivity : AppCompatActivity() {
lateinit var searchTextView : TextView
private var requestQueue : RequestQueue? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_recipe)
searchTextView = findViewById<TextView>(R.id.searchTextView) as TextView
getAllProfessions(searchTextView)
}
fun getAllProfessions(searchText : TextView) {
val url = "http://192.168.0.24:49155/allprofessions"
val request = JsonObjectRequest(Request.Method.GET, url, null, Response.Listener {
response ->try {
val jsonArray = response.getJSONArray("name")
println("Print anything at all!")
for (i in 0 until jsonArray.length()) {
println(jsonArray.getJSONObject(i))
}
} catch (e: JSONException) {
e.printStackTrace()
}
}, Response.ErrorListener { error -> error.printStackTrace() })
requestQueue?.add(request)
}
}
First create custom VolleyWebService class as follows:
class VolleyWebService constructor(context: Context) {
private var INSTANCE: VolleyWebService? = null
companion object {
#Volatile
private var INSTANCE: VolleyWebService? = null
fun getInstance(context: Context) =
INSTANCE ?: synchronized(this) {
INSTANCE ?: VolleyWebService(context).also {
INSTANCE = it
}
}
}
val requestQueue: RequestQueue by lazy {
Volley.newRequestQueue(context.applicationContext)
}
fun <T> addToRequestQueue(req: Request<T>) {
requestQueue.add(req)
}
}
Then modify your function getAllProfessions like this:
fun getAllProfessions(searchText : TextView) {
val url = "http://192.168.0.24:49155/allprofessions"
val request = JsonObjectRequest(Request.Method.GET, url, null, Response.Listener {
response ->try {
val jsonArray = response.getJSONArray("name")
println("Print anything at all!")
for (i in 0 until jsonArray.length()) {
println(jsonArray.getJSONObject(i))
}
} catch (e: JSONException) {
e.printStackTrace()
}
}, Response.ErrorListener { error -> error.printStackTrace() })
//changes made here
VolleyWebService.getInstance(context).addToRequestQueue(request)
}
}
This document explain the implementation of a VolleyWebService class:
http://code.sunnyjohn.in/index.php/2020/12/24/retrieve-data-volley/
You have to instantiate the class, create a new request queue and then add to the request queue.
I'm trying to create a general Request class with kotlin, which I can use to make Request with Volley.
The problem I'm having is that I can not return the response of the Request.
I'm trying to get the response of the request so that I can proces the data.
I can't seem to find a good source which describes how to make a Helper class for making Request
Request class
import android.content.Context
import android.util.Log
import com.android.volley.RequestQueue
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
class Request(var context: Context, var url: String) {
var response : String? = null
fun makePOSTRequest() {
val requestQueue: RequestQueue? = Volley.newRequestQueue(context)
val stringRequest = object : StringRequest(
Method.POST, url,
Response.Listener { response ->
}, Response.ErrorListener { error ->
Log.i("Error", "[" + error + "]")
}) {
override fun getParams(): Map<String, String> {
val params = HashMap<String, String>()
return params
}
}
requestQueue?.add(stringRequest)
}
fun makeGETRequest() {
val requestQueue: RequestQueue? = Volley.newRequestQueue(context)
val stringRequest = object : StringRequest(
Method.GET, url,
Response.Listener { response ->
println(response) // Response: {"message":"ok","locaties"[{"id":"739","name":"Company","code":"","klant":"Client"}]}
this.response = response // Here I'm trying to fill the response var
}, Response.ErrorListener { error ->
Log.i("Error", "[" + error + "]")
}) {
}
requestQueue?.add(stringRequest)
}
}
Implementation
var request = context?.let { Request(it, BuildConfig.API_URL + "getLocatiesLijst.php?name=" + bdl?.getString("name")) }
request?.makeGETRequest()
var response = request?.response
println(response) // This give Null back
I guess the problem is that request is async, but when you run this come, println("") will be called immediately. You should wait for a result.
You can add some callback to the listener or try to use coroutines.
I have been busy with implementing a request helper class with coroutines. And I think I have found a solution to my own problem. I'm using coroutines to make the request async.
Source of solution
Request.kt
import android.content.Context
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import kotlin.coroutines.*;
class Request(var context: Context, var url: String) {
suspend fun makeGetRequest() = suspendCoroutine<String> { cont ->
val queue = Volley.newRequestQueue(context)
val stringRequest = StringRequest(
Request.Method.GET, url,
Response.Listener<String> { response ->
cont.resume("Response is: ${response}")
},
Response.ErrorListener { cont.resume("Something went wrong!") })
queue.add(stringRequest)
}
}
Implementation
class LocationFragment : Fragment(), CoroutineScope {
protected lateinit var job: Job
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
var rootView = inflater.inflate(R.layout.location_list, container, false)
//TODO doe verzoek voor lijst van locaties
val bdl = arguments
var request = context?.let { Request(it, BuildConfig.API_URL + "getLocatiesLijst.php?name=" + bdl?.getString("name")) }
job = Job()
launch {
val data = request?.makeGetRequest()
println(data)
}
}
Result
I/System.out: Response is:{"message":"ok","locaties":[{"id":"739","name":"Company","lce_code":"code","klant":"Client"}]}