import android.graphics.Bitmap
import android.graphics.BitmapFactory
import org.json.JSONObject
import java.io.*
import java.net.HttpURLConnection
import java.net.URL
import java.net.URLEncoder
import javax.net.ssl.HttpsURLConnection
/*
Перед использованием не забудьте добавить в манифест
разрешение
И атрибут в тег application
android:usesCleartextTraffic="true"
Использование:
HTTP.requestGET(
"http://s4a.kolei.ru/Product",
mapOf(
"token" to token
)
){result, error, code ->
runOnUiThread{
if(result!=null){
resultTextView.text = result
}
else
AlertDialog.Builder(this)
.setTitle("Ошибка http-запроса")
.setMessage(error)
.setPositiveButton("OK", null)
.create()
.show()
}
}
HTTP.requestPOST(
"http://s4a.kolei.ru/login",
JSONObject().put("username", username).put("password", password),
mapOf(
"Content-Type" to "application/json"
)
){result, error, code ->
runOnUiThread{
if(result!=null){
}
else
AlertDialog.Builder(this)
.setTitle("Ошибка http-запроса")
.setMessage(error)
.setPositiveButton("OK", null)
.create()
.show()
}
}
HTTP.getImage("https://openweathermap.org/img/w/${icoName}.png") { bitmap, error ->
runOnUiThread {
if (bitmap != null) {
var imageView = findViewById(R.id.ico)
imageView.setImageBitmap(bitmap)
}
}
}
*/
object HTTP
{
private const val GET : String = "GET"
private const val POST : String = "POST"
private fun getCharSet(url: String): String{
val obj = URL(url)
var con: HttpURLConnection = if(url.startsWith("https:", true))
obj.openConnection() as HttpsURLConnection
else
obj.openConnection() as HttpURLConnection
con.requestMethod = "HEAD"
val contentType = con.contentType
return if(contentType!=null && contentType.contains("Windows-1251", true))
"Windows-1251"
else
"UTF-8"
}
/**
* Метод для отправки POST-запросов
*
* Запросы отправляются в отдельном потоке
* Автоматически поддерживает http/httpS
* Можно задать заголовки запроса
* По-умолчанию отправляет данные в формате application/x-www-form-urlencoded
* при задании заголовка Content-type: application/json автоматически переключается на это тип
*
* @param url Полный URL сайта (протокол + домен + путь)
* @param postData Даные для отправки
* @param headers Ассоциативный массив заголовков запроса
* @param callback Лямбда-функция обратного вызова
*/
fun requestPOST(
url: String,
postData: JSONObject? = null,
headers: Map?,
callback: (result: String?, error: String, code: Int)->Unit
) {
Thread( Runnable {
var error = ""
var result: String? = null
var code: Int = -1
try {
val charset = getCharSet(url)
val urlURL = URL(url)
val conn: HttpURLConnection = if (url.startsWith("https:", true))
urlURL.openConnection() as HttpsURLConnection
else
urlURL.openConnection() as HttpURLConnection
// если задан тип контента application/json, то на выход пишу как есть
var contentTypeJson = false
if(headers!=null){
for((key, value) in headers){
if(key.lowercase()=="content-type" && value.startsWith("application/json"))
contentTypeJson = true
conn.setRequestProperty(key, value)
}
}
conn.readTimeout = 10000
conn.connectTimeout = 10000
conn.requestMethod = POST
conn.doInput = true
conn.doOutput = true
val os: OutputStream = conn.outputStream
if (postData != null) {
val writer = BufferedWriter(OutputStreamWriter(os, "UTF-8"))
var content = ""
content = if(contentTypeJson)
postData.toString()
else
encodeParams(postData)?:""
writer.write(content)
writer.flush()
writer.close()
}
os.close()
code = conn.responseCode // To Check for 200
if (code == HttpsURLConnection.HTTP_OK) {
val `in` = BufferedReader(InputStreamReader(conn.inputStream, charset))
val sb = StringBuffer("")
var line: String? = ""
while (`in`.readLine().also { line = it } != null) {
sb.append(line)
break
}
`in`.close()
result = sb.toString()
}
else {
error = "Response code ${code}"
}
}
catch (e: Exception) {
error = e.message.toString()
}
callback.invoke(result, error, code)
}).start()
}
fun getImage(url: String, callback: (result: Bitmap?, error: String)->Unit){
Thread( Runnable {
var image: Bitmap? = null
var error = ""
try {
val `in` = URL(url).openStream()
image = BitmapFactory.decodeStream(`in`)
}
catch (e: Exception) {
error = e.message.toString()
}
callback.invoke(image, error)
}).start()
}
fun requestGET(
r_url: String,
headers: Map?,
callback: (result: String?, error: String, code: Int)->Unit
) {
Thread( Runnable {
var error = ""
var result: String? = null
var code: Int = -1
try {
val charset = getCharSet(r_url)
val obj = URL(r_url)
val con: HttpURLConnection = if(r_url.startsWith("https:", true))
obj.openConnection() as HttpsURLConnection
else
obj.openConnection() as HttpURLConnection
if(headers!=null){
for((key, value) in headers){
con.setRequestProperty(key, value)
}
}
con.requestMethod = GET
code = con.responseCode
result = if (code == HttpURLConnection.HTTP_OK) { // connection ok
val `in` =
BufferedReader(InputStreamReader(con.inputStream, charset))
var inputLine: String?
val response = StringBuffer()
while (`in`.readLine().also { inputLine = it } != null) {
response.append(inputLine)
}
`in`.close()
response.toString()
} else {
null
}
}
catch (e: Exception){
error = e.message.toString()
}
callback.invoke(result, error, code)
}).start()
}
@Throws(IOException::class)
private fun encodeParams(params: JSONObject): String? {
val result = StringBuilder()
var first = true
val itr = params.keys()
while (itr.hasNext()) {
val key = itr.next()
val value = params[key]
if (first) first = false else result.append("&")
result.append(URLEncoder.encode(key, "UTF-8"))
result.append("=")
result.append(URLEncoder.encode(value.toString(), "UTF-8"))
}
return result.toString()
}
}