Kotlin Android Studio

1. get websocket kotlin android

 package com.example.alarmcyrpto


import android.os.Bundle
import android.util.Log
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.google.gson.Gson
import com.google.gson.annotations.SerializedName
import okhttp3.*

class MainActivity : AppCompatActivity() {

private lateinit var okHttpClient: OkHttpClient
private lateinit var webSocket: WebSocket
private lateinit var gson: Gson
private lateinit var btcPriceTv: TextView
private lateinit var pilihCoinEditText: EditText
private var currentSymbol: String = "btcusdt"

private lateinit var textViewCurrentPrice: TextView
private lateinit var textViewTargetPrice: TextView
private var currentPrice: Double = 0.0
private var targetPrice: Double = 0.0

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

textViewCurrentPrice = findViewById(R.id.textViewCurrentPrice)
textViewTargetPrice = findViewById(R.id.textViewTargetPrice)

okHttpClient = OkHttpClient()
gson = Gson()
btcPriceTv = findViewById(R.id.textView6)
pilihCoinEditText = findViewById(R.id.pilihCoin)

// setup websocket connection with default symbol
val request = Request.Builder().url("wss://fstream.binance.com/ws/$currentSymbol@ticker").build()
webSocket = okHttpClient.newWebSocket(request, object : WebSocketListener() {
override fun onOpen(webSocket: WebSocket, response: Response) {
Log.d("TAG", "WebSocket opened")
}

override fun onMessage(webSocket: WebSocket, text: String) {
super.onMessage(webSocket, text)
runOnUiThread {
val tickerData = gson.fromJson(text, TickerData::class.java)
btcPriceTv.text = tickerData.lastPrice
Log.d("TAG", text)
}
}

override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
Log.e("TAG", "WebSocket error: ${t.message}")
}
})

pilihCoinEditText.setOnEditorActionListener { _, _, _ ->
currentSymbol = pilihCoinEditText.text.toString()
webSocket.cancel()
val newRequest = Request.Builder().url("wss://fstream.binance.com/ws/$currentSymbol@ticker").build()
webSocket = okHttpClient.newWebSocket(newRequest, object : WebSocketListener() {
override fun onOpen(webSocket: WebSocket, response: Response) {
Log.d("TAG", "WebSocket opened")
}

override fun onMessage(webSocket: WebSocket, text: String) {
super.onMessage(webSocket, text)
runOnUiThread {
val tickerData = gson.fromJson(text, TickerData::class.java)
btcPriceTv.text = tickerData.lastPrice
}
}

override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
Log.e("TAG", "WebSocket error: ${t.message}")
}
})
false
}

private fun updatePrice(currentPrice: Double, targetPrice: Double) {
this.currentPrice = currentPrice
this.targetPrice = targetPrice
textViewCurrentPrice.text = currentPrice.toString()
textViewTargetPrice.text = targetPrice.toString()
}

private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val currentPrice = intent?.getDoubleExtra("current_price", 0.0) ?: 0.0
val targetPrice = intent?.getDoubleExtra("target_price", 0.0) ?: 0.0
updatePrice(currentPrice, targetPrice)
}
}

override fun onResume() {
super.onResume()
val filter = IntentFilter("com.example.alarmcyrpto.UPDATE_PRICE")
registerReceiver(broadcastReceiver, filter)
}

override fun onPause() {
super.onPause()
unregisterReceiver(broadcastReceiver)
}
}

override fun onDestroy() {
super.onDestroy()
webSocket.cancel()
}
}

data class TickerData(
@SerializedName("c")
val lastPrice: String
)
2. alarm main activity jika close tidak aktif



package com.example.alarmcyrpto

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import java.util.*
import android.widget.TextView

class MainActivity : AppCompatActivity() {

private val binanceApiService = BinanceApiService.create()

private val notificationChannelId = "BinanceAlarmNotificationChannel"
private val notificationChannelName = "BinanceAlarmNotification"
private val notificationId = 1

private val symbol = "BTCUSDT"
private val targetPrice = 28033.0

private lateinit var btcPriceTv: TextView

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

createNotificationChannel()

getPrice()
startAlarm()
}

private fun getPrice() {
binanceApiService.getPrice(symbol) { price ->
runOnUiThread {
btcPriceTv = findViewById(R.id.tv_price)
btcPriceTv.text = price
val currentPrice = price.substringAfter(": ").toDoubleOrNull()
if (currentPrice != null && currentPrice >= targetPrice) {
showNotification()
}
}
}
}

private fun startAlarm() {
Timer().scheduleAtFixedRate(object : TimerTask() {
override fun run() {
getPrice()
}
}, 0, 5000)
}

private fun showNotification() {
val notificationBuilder = NotificationCompat.Builder(this, notificationChannelId)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("BinanceAlarm")
.setContentText("$symbol price has reached $targetPrice")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)

with(NotificationManagerCompat.from(this)) {
notify(notificationId, notificationBuilder.build())
}
}

private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
notificationChannelId,
notificationChannelName,
NotificationManager.IMPORTANCE_DEFAULT
)
channel.description = "BinanceAlarm notification channel"
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}

}

3. cara agar runing program tanpa buka aplikasi 
val intent = Intent(this, AlarmService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(intent)
} else {
    startService(intent)
}

4. tampilkan ke xml 
val textView = findViewById<TextView>(R.id.textView)
textView.text = "Current price is: $currentPrice"

5. jika runing background threadui
runOnUiThread { val textView = findViewById<TextView>(R.id.textView) textView.text = "Current price is: $currentPrice" }

6. get api service
import com.google.gson.Gson import okhttp3.* import java.io.IOException class BinanceApiService(private val client: OkHttpClient) { interface BinanceApiService { // ... @GET("/api/v3/ticker/price") fun getPrice(@Query("symbol") symbol: String): Call<String> // ... } companion object { private const val BASE_URL = "https://fapi.binance.com" fun create(): BinanceApiService { val client = OkHttpClient.Builder().build() return BinanceApiService(client) } } private val gson = Gson() fun getPrice(symbol: String, callback: (String) -> Unit) { val url = "$BASE_URL/fapi/v1/ticker/price?symbol=$symbol" val request = Request.Builder().url(url).build() client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { callback("Error: ${e.message}") } override fun onResponse(call: Call, response: Response) { if (response.isSuccessful) { val body = response.body?.string() if (body != null) { val price = gson.fromJson(body, Price::class.java).price callback("$symbol : $price") } else { callback("Error: response body is null") } } else { callback("Error: ${response.message}") } } }) } private data class Price( val price: String ) }


Komentar