Intro
시간이 조금 남아서 간단하게라도 안드로이드 앱을 만들어볼 예정이다.
우선 서버로 센서 데이터 Request를 보내고, Response를 받는 것부터 해보자.
언어는 Kotlin을 사용했다. Kotlin에 편한 함수들이 많다.
HTTP 라이브러리로는 Volley를 사용했다.
https://developer.android.com/training/volley?hl=ko
Volley 개요 | Android 개발자 | Android Developers
Volley 개요 Volley는 Android 앱의 네트워킹을 더 쉽고, 무엇보다도 더 빠르게 하는 HTTP 라이브러리입니다. Volley는 GitHub에서 사용할 수 있습니다. Volley를 사용하면 다음과 같은 이점이 있습니다. 네트
developer.android.com
환경설정
우선 Gradle에 Volley를 추가한다.
dependencies {
implementation 'com.android.volley:volley:1.2.1'
}
그리고 HTTP 요청을 보내기 위해 AndroidManifest를 수정해야 한다.
android.permission.INTERNET과 android:useCleartextTraffic='true"를 추가하면 된다.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.devjaewoo.sensormonitoringapp">
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true">
...
</application>
</manifest>
그리고 필요한 상수들을 선언한다.
Any.TAG는 선언해두면 Log.d 사용 시 첫번째 인자로 넣을 수 있다. 있으면 많이 편리하다.
Constants.kt
package com.devjaewoo.sensormonitoringapp
val Any.TAG: String
get() = if(javaClass.simpleName.length <= 23) javaClass.simpleName else javaClass.simpleName.substring(0, 23)
const val CHART_SIZE: Int = 6
const val SERVER_URL: String = "http://192.165.90.32:8080"
Request용 Object 생성
아래의 코드를 복사해 새로운 Object를 만든다.
다른 프로젝트에서 만들어둔 모듈인데 이렇게 사용될줄은 몰랐다.
지금처럼 시간이 얼마 없는 상황에서 복사해올게 있어 참 다행이다.
범용성 좋게 만들길 잘한것 같다.
RequestHandler.kt
package com.devjaewoo.sensormonitoringapp.request
import android.util.Log
import android.widget.Toast
import com.android.volley.*
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley
import com.devjaewoo.sensormonitoringapp.ApplicationManager
import com.devjaewoo.sensormonitoringapp.SERVER_URL
import com.devjaewoo.sensormonitoringapp.TAG
import org.json.JSONObject
object RequestHandler {
var accessToken: String = ""
private val requestQueue = Volley.newRequestQueue(ApplicationManager.applicationContext)
private val defaultErrorListener = Response.ErrorListener { error ->
Log.d(TAG, "error: $error")
val body = JSONObject(String(error.networkResponse.data))
val errorMessage = body.getString("message")
Log.e(TAG, "defaultErrorListener: code: ${error.networkResponse.statusCode} message: $errorMessage")
Toast.makeText(ApplicationManager.applicationContext, errorMessage, Toast.LENGTH_SHORT).show()
}
fun request(url: String, jsonObject: JSONObject?, responseListener: Response.Listener<JSONObject>, errorListener: Response.ErrorListener?, requestWithToken: Boolean, method: Int) {
val requestURL = SERVER_URL + url
Log.d(TAG, "request: $requestURL with data $jsonObject")
val jsonObjectRequest = object : JsonObjectRequest(
method,
requestURL,
jsonObject,
responseListener,
errorListener ?: defaultErrorListener
) {
override fun getHeaders(): MutableMap<String, String> {
return if(requestWithToken) HashMap<String, String>().apply { put("Authorization", "Bearer $accessToken") } else super.getHeaders()
}
}
requestQueue.add(jsonObjectRequest)
}
}
Request 테스트
이제 간단한 버튼을 만들고 JSON 응답을 잘 받아오는지 테스트 해보자.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
package com.devjaewoo.sensormonitoringapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.android.volley.Request
import com.devjaewoo.sensormonitoringapp.databinding.ActivityMainBinding
import com.devjaewoo.sensormonitoringapp.request.RequestHandler
class MainActivity : AppCompatActivity() {
private var _binding: ActivityMainBinding? = null
private val binding: ActivityMainBinding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityMainBinding.inflate(layoutInflater)
binding.button.setOnClickListener {
RequestHandler.request("/api/1/sensor", null, {jsonObject -> Log.d(TAG, "onCreate: $jsonObject")}, null, false, Request.Method.GET)
}
setContentView(binding.root)
}
}
앱을 실행하고 버튼을 누르면 데이터가 잘 들어오는것을 확인할 수 있다.
사진이 잘려서 터미널에서 텍스트를 복사해왔다.
2022-08-19 17:05:11.910 14876-14876/com.devjaewoo.sensormonitoringapp D/RequestHandler: request: http://192.165.90.32:8080/api/1/sensor with data null
2022-08-19 17:05:11.966 14876-14876/com.devjaewoo.sensormonitoringapp D/MainActivity: onCreate: {"sensorData":[{"eco2":436,"tvoc":5,"temp":29.28,"accel":{"x":-1.2977,"y":-0.0168,"z":9.8809},"createdDate":"2022-08-19T16:43:05.297205"},{"eco2":436,"tvoc":5,"temp":29.38,"accel":{"x":-1.3024,"y":-0.0455,"z":9.6989},"createdDate":"2022-08-19T16:43:04.151059"},{"eco2":432,"tvoc":4,"temp":29.33,"accel":{"x":-1.3048,"y":-0.0503,"z":9.7947},"createdDate":"2022-08-19T16:43:03.009536"},{"eco2":442,"tvoc":6,"temp":29.38,"accel":{"x":-1.3551,"y":-0.0311,"z":9.7396},"createdDate":"2022-08-19T16:43:01.872407"},{"eco2":436,"tvoc":5,"temp":29.42,"accel":{"x":-1.3479,"y":-0.0479,"z":9.8114},"createdDate":"2022-08-19T16:43:00.736431"},{"eco2":432,"tvoc":4,"temp":29.42,"accel":{"x":-1.3024,"y":-0.0575,"z":9.7396},"createdDate":"2022-08-19T16:42:59.585145"},{"eco2":436,"tvoc":5,"temp":29.38,"accel":{"x":-1.3982,"y":-0.0144,"z":9.7229},"createdDate":"2022-08-19T16:42:58.447736"},{"eco2":442,"tvoc":6,"temp":29.33,"accel":{"x":-1.3408,"y":0.0263,"z":9.7803},"createdDate":"2022-08-19T16:42:56.228591"},{"eco2":442,"tvoc":6,"temp":29.33,"accel":{"x":-1.3192,"y":-0.067,"z":9.7636},"createdDate":"2022-08-19T16:42:55.090591"},{"eco2":439,"tvoc":5,"temp":29.28,"accel":{"x":-1.2857,"y":-0.0503,"z":9.8162},"createdDate":"2022-08-19T16:42:53.952317"},{"eco2":444,"tvoc":6,"temp":29.42,"accel":{"x":-1.2689,"y":-0.0431,"z":9.7133},"createdDate":"2022-08-19T16:42:51.791102"},{"eco2":439,"tvoc":5,"temp":29.38,"accel":{"x":-1.3216,"y":-0.0838,"z":9.7995},"createdDate":"2022-08-19T16:42:50.62493"},{"eco2":439,"tvoc":5,"temp":29.38,"accel":{"x":-1.3024,"y":-0.012,"z":9.6462},"createdDate":"2022-08-19T16:42:49.488359"},{"eco2":439,"tvoc":5,"temp":29.42,"accel":{"x":-1.3048,"y":-0.012,"z":9.7372},"createdDate":"2022-08-19T16:42:48.344005"},{"eco2":439,"tvoc":5,"temp":29.42,"accel":{"x":-1.2617,"y":-0.0239,"z":9.7636},"createdDate":"2022-08-19T16:42:47.204543"},{"eco2":439,"tvoc":5,"temp":29.38,"accel":{"x":-1.2546,"y":-0.012,"z":9.7372},"createdDate":"2022-08-19T16:42:45.885326"},{"eco2":439,"tvoc":5,"temp":29.33,"accel":{"x":-1.3862,"y":-0.0575,"z":9.7516},"createdDate":"2022-08-19T16:42:44.751449"},{"eco2":439,"tvoc":5,"temp":29.47,"accel":{"x":-1.324,"y":0.0359,"z":9.754},"createdDate":"2022-08-19T16:42:43.403443"},{"eco2":439,"tvoc":5,"temp":29.38,"accel":{"x":-1.391,"y":-0.0479,"z":9.7899},"createdDate":"2022-08-19T16:42:42.268446"},{"eco2":439,"tvoc":133,"temp":29.42,"accel":{"x":-1.3384,"y":-0.0527,"z":9.7803},"createdDate":"2022-08-19T16:42:40.083918"}]}
다음번엔 차트 라이브러리를 이용해 받아온 센서 데이터를 출력해보도록 하겠다.
'Projects > 센서 모니터링 시스템' 카테고리의 다른 글
[센서 모니터링 시스템] 13. Android Chart 구현 (프로젝트 종료) (0) | 2022.08.19 |
---|---|
[센서 모니터링 시스템] 11. Rechart를 사용한 센서 데이터 시각화 (0) | 2022.08.19 |
[센서 모니터링 시스템] 10. React 개발환경 구성 (0) | 2022.08.19 |
[센서 모니터링 시스템] 9. 라즈베리파이 Request 구현 (0) | 2022.08.18 |
[센서 모니터링 시스템] 8. Service, REST Controller 개발 (0) | 2022.08.18 |