HttpHelper.kt 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. import android.graphics.Bitmap
  2. import android.graphics.BitmapFactory
  3. import org.json.JSONObject
  4. import java.io.*
  5. import java.net.HttpURLConnection
  6. import java.net.URL
  7. import java.net.URLEncoder
  8. import javax.net.ssl.HttpsURLConnection
  9. /*
  10. Перед использованием не забудьте добавить в манифест
  11. разрешение
  12. <uses-permission android:name="android.permission.INTERNET" />
  13. И атрибут в тег application
  14. android:usesCleartextTraffic="true"
  15. Использование:
  16. HTTP.requestGET(
  17. "http://s4a.kolei.ru/Product",
  18. mapOf(
  19. "token" to token
  20. )
  21. ){result, error, code ->
  22. runOnUiThread{
  23. if(result!=null){
  24. resultTextView.text = result
  25. }
  26. else
  27. AlertDialog.Builder(this)
  28. .setTitle("Ошибка http-запроса")
  29. .setMessage(error)
  30. .setPositiveButton("OK", null)
  31. .create()
  32. .show()
  33. }
  34. }
  35. HTTP.requestPOST(
  36. "http://s4a.kolei.ru/login",
  37. JSONObject().put("username", username).put("password", password),
  38. mapOf(
  39. "Content-Type" to "application/json"
  40. )
  41. ){result, error, code ->
  42. runOnUiThread{
  43. if(result!=null){
  44. }
  45. else
  46. AlertDialog.Builder(this)
  47. .setTitle("Ошибка http-запроса")
  48. .setMessage(error)
  49. .setPositiveButton("OK", null)
  50. .create()
  51. .show()
  52. }
  53. }
  54. HTTP.getImage("https://openweathermap.org/img/w/${icoName}.png") { bitmap, error ->
  55. runOnUiThread {
  56. if (bitmap != null) {
  57. var imageView = findViewById<ImageView>(R.id.ico)
  58. imageView.setImageBitmap(bitmap)
  59. }
  60. }
  61. }
  62. */
  63. object HTTP
  64. {
  65. private const val GET : String = "GET"
  66. private const val POST : String = "POST"
  67. private fun getCharSet(url: String): String{
  68. val obj = URL(url)
  69. var con: HttpURLConnection = if(url.startsWith("https:", true))
  70. obj.openConnection() as HttpsURLConnection
  71. else
  72. obj.openConnection() as HttpURLConnection
  73. con.requestMethod = "HEAD"
  74. val contentType = con.contentType
  75. return if(contentType.contains("Windows-1251", true))
  76. "Windows-1251"
  77. else
  78. "UTF-8"
  79. }
  80. /**
  81. * Метод для отправки POST-запросов
  82. *
  83. * Запросы отправляются в отдельном потоке
  84. * Автоматически поддерживает http/httpS
  85. * Можно задать заголовки запроса
  86. * По-умолчанию отправляет данные в формате application/x-www-form-urlencoded
  87. * при задании заголовка Content-type: application/json автоматически переключается на это тип
  88. *
  89. * @param url Полный URL сайта (протокол + домен + путь)
  90. * @param postData Даные для отправки
  91. * @param headers Ассоциативный массив заголовков запроса
  92. * @param callback Лямбда-функция обратного вызова
  93. */
  94. fun requestPOST(
  95. url: String,
  96. postData: JSONObject? = null,
  97. headers: Map<String, String>?,
  98. callback: (result: String?, error: String, code: Int)->Unit
  99. ) {
  100. Thread( Runnable {
  101. var error = ""
  102. var result: String? = null
  103. var code: Int = -1
  104. try {
  105. val charset = getCharSet(url)
  106. val urlURL = URL(url)
  107. val conn: HttpURLConnection = if (url.startsWith("https:", true))
  108. urlURL.openConnection() as HttpsURLConnection
  109. else
  110. urlURL.openConnection() as HttpURLConnection
  111. // если задан тип контента application/json, то на выход пишу как есть
  112. var contentTypeJson = false
  113. if(headers!=null){
  114. for((key, value) in headers){
  115. if(key.lowercase()=="content-type" && value.startsWith("application/json"))
  116. contentTypeJson = true
  117. conn.setRequestProperty(key, value)
  118. }
  119. }
  120. conn.readTimeout = 10000
  121. conn.connectTimeout = 10000
  122. conn.requestMethod = POST
  123. conn.doInput = true
  124. conn.doOutput = true
  125. val os: OutputStream = conn.outputStream
  126. if (postData != null) {
  127. val writer = BufferedWriter(OutputStreamWriter(os, "UTF-8"))
  128. var content = ""
  129. content = if(contentTypeJson)
  130. postData.toString()
  131. else
  132. encodeParams(postData)?:""
  133. writer.write(content)
  134. writer.flush()
  135. writer.close()
  136. }
  137. os.close()
  138. code = conn.responseCode // To Check for 200
  139. if (code == HttpsURLConnection.HTTP_OK) {
  140. val `in` = BufferedReader(InputStreamReader(conn.inputStream, charset))
  141. val sb = StringBuffer("")
  142. var line: String? = ""
  143. while (`in`.readLine().also { line = it } != null) {
  144. sb.append(line)
  145. break
  146. }
  147. `in`.close()
  148. result = sb.toString()
  149. }
  150. else {
  151. error = "Response code ${code}"
  152. }
  153. }
  154. catch (e: Exception) {
  155. error = e.message.toString()
  156. }
  157. callback.invoke(result, error, code)
  158. }).start()
  159. }
  160. fun getImage(url: String, callback: (result: Bitmap?, error: String)->Unit){
  161. Thread( Runnable {
  162. var image: Bitmap? = null
  163. var error = ""
  164. try {
  165. val `in` = URL(url).openStream()
  166. image = BitmapFactory.decodeStream(`in`)
  167. }
  168. catch (e: Exception) {
  169. error = e.message.toString()
  170. }
  171. callback.invoke(image, error)
  172. }).start()
  173. }
  174. fun requestGET(
  175. r_url: String,
  176. headers: Map<String, String>?,
  177. callback: (result: String?, error: String, code: Int)->Unit
  178. ) {
  179. Thread( Runnable {
  180. var error = ""
  181. var result: String? = null
  182. var code: Int = -1
  183. try {
  184. val charset = getCharSet(r_url)
  185. val obj = URL(r_url)
  186. val con: HttpURLConnection = if(r_url.startsWith("https:", true))
  187. obj.openConnection() as HttpsURLConnection
  188. else
  189. obj.openConnection() as HttpURLConnection
  190. if(headers!=null){
  191. for((key, value) in headers){
  192. con.setRequestProperty(key, value)
  193. }
  194. }
  195. con.requestMethod = GET
  196. code = con.responseCode
  197. result = if (code == HttpURLConnection.HTTP_OK) { // connection ok
  198. val `in` =
  199. BufferedReader(InputStreamReader(con.inputStream, charset))
  200. var inputLine: String?
  201. val response = StringBuffer()
  202. while (`in`.readLine().also { inputLine = it } != null) {
  203. response.append(inputLine)
  204. }
  205. `in`.close()
  206. response.toString()
  207. } else {
  208. null
  209. }
  210. }
  211. catch (e: Exception){
  212. error = e.message.toString()
  213. }
  214. callback.invoke(result, error, code)
  215. }).start()
  216. }
  217. @Throws(IOException::class)
  218. private fun encodeParams(params: JSONObject): String? {
  219. val result = StringBuilder()
  220. var first = true
  221. val itr = params.keys()
  222. while (itr.hasNext()) {
  223. val key = itr.next()
  224. val value = params[key]
  225. if (first) first = false else result.append("&")
  226. result.append(URLEncoder.encode(key, "UTF-8"))
  227. result.append("=")
  228. result.append(URLEncoder.encode(value.toString(), "UTF-8"))
  229. }
  230. return result.toString()
  231. }
  232. }