ꡬν λ¬Έμ
μ‘Έμ νλ‘μ νΈλ₯Ό μ§ννλ©΄μ μλ²μμ νΉμ ν μ΄λ²€νΈλ₯Ό μμ νλ©΄ μ΄λ²€νΈ μ’ λ₯μ λ°λΌ μλ‘ λ€λ₯Έ 2κ°μ μλ¦Όμ λμ΄μ£Όλ κΈ°λ₯μ ꡬνν΄μΌ νλ€. μμΌ ν΅μ μΌλ‘ μ΄λ²€νΈλ₯Ό μμ νλλ° Activity μ΄λμ΄λ Fragment μ΄λμ κ΄κ³ μμ΄ μλ²μ μ°κ²° κ°λ₯ν μμΌ ν΅μ μ΄ νμνλ€.
ν΄κ²° λ°©λ²
MVVMκ³Ό λ¨μΌ Activityλ₯Ό μ¬μ©νκΈ°μ Activityλ MainActivity ν κ° λΏμ΄μκ³ MainActivity μμ μμΌ ν΅μ μ ꡬννλ©΄ λλ λ¬Έμ μλ€. νμ§λ§ μ±μ μ¬μ©νμ§ μλ μν©μμλ μλ¦Όμ μμ ν΄μΌ ν νμκ° μμκ³ μ΄λ₯Ό μν΄ Serviceλ₯Ό μ¬μ©νλ€. λ¬Όλ‘ MainActivity μμ ν΄λΉ κΈ°λ₯μ ꡬνν μ μλ€. νμ§λ§ μμΌ ν΅μ μ΄ MainActivity μ체μ μ’ μλλ μν©μ΄ λ°μνκΈ°μ Service λ₯Ό μ¬μ©ν΄μ λ‘μ§μ λΆλ¦¬νλ€.
μ½λ
- MainActivity
μ°μ MainActivity λΆν° μ΄ν΄λ³΄μ. κΈ°λ₯κ³Ό κ΄λ ¨ μλ μ½λλ€μ μ§μλ²λ Έλ€.
class MainActivity(override val ACTIVITY_TAG: String = "MAIN_ACTIVITY") :
BaseActivity<ActivityMainBinding>(R.layout.activity_main) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initViews()
}
override fun onDestroy() {
super.onDestroy()
val intent = Intent(this@MainActivity, ReceiverService::class.java)
baseContext.stopService(intent)
}
private fun initViews() {
val intent = Intent(this@MainActivity, ReceiverService::class.java)
baseContext.startService(intent)
}
}
MainActivityκ° onCreate λμ λ Serviceλ₯Ό μ€νμν¨λ€. onDestory λμ λλ Serviceλ₯Ό μ€μ§νμ¬ λ©λͺ¨λ¦¬λ¦μ λ°©μ§νλ€.
- ReceiverService
λ€μμ Service λ₯Ό μ΄ν΄λ³΄μ. Service λ₯Ό μμνλ ReceiverService λ₯Ό ꡬννμκ³ μ΄ λ onBind λ₯Ό μ€λ²λΌμ΄λ© ν΄μΌ νλ€. μ°Ύμ보λ onBind μ κ²½μ° λ€λ₯Έ μ΄ν리μΌμ΄μ κ³Ό μ°κ²°ν λ μ¬μ©νλ€κ³ νλ€. μ΄ νλ‘μ νΈμμλ μ¬μ©νμ§ μμ λ― μΆλ€. μλλ‘μ΄λ 26 (Android Oreo) μ΄μλΆν°λ λ°±κ·ΈλΌμ΄λμμ μ±μ μ€νν κ²½μ° μ¬μ©μμκ² λ°±κ·ΈλΌμ΄λμμ μλ¦Όμ λμ΄μ€μΌ νλ€.
class ReceiverService : Service() {
override fun onBind(intent: Intent?): IBinder? {
TODO("Not yet implemented")
}
override fun onCreate() {
super.onCreate()
receiveEvent()
}
// μ΄λ²€νΈ μμ μ μν΄ λ°±κ·ΈλΌμ΄λμμ μλ
private fun receiveEvent() {
val builder = NotificationCompat.Builder(this@ReceiverService, NOTIFICATION_CHANNEL[0])
.setSmallIcon(R.drawable.ic_baseline_poop_solid_icon)
.setContentTitle("μ΄λ²€νΈ μμ μ€")
.setContentText("μ΄λ²€νΈ μμ μ μν΄ λ°±κ·ΈλΌμ΄λμμ μλ μ€μ
λλ€.")
.setPriority(NotificationCompat.FOREGROUND_SERVICE_DEFAULT)
// Android 26 μ΄μλΆν°λ NotificationChannel λ±λ‘ νμ
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel =
NotificationChannel(
NOTIFICATION_CHANNEL[0],
"λ°±κ·ΈλΌμ΄λμμ μ€ν",
NotificationManager.IMPORTANCE_DEFAULT
)
val manager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(channel)
}
startForeground(NOTIFICATION_RECEIVE_MODE, builder.build())
}
}β
κ²°κ³Όμ μΌλ‘ λ°±κ·ΈλΌμ΄λμμ μλνμ§λ§ μ¬μ©μμκ² μ΄λ₯Ό μλ € ν¬κ·ΈλΌμ΄λλ‘ μ€ννλ λλμ΄λ€. λν μλ¦Όμ ꡬνν λ μλ¦Ό μ±λμ λ±λ‘ν΄μΌνλ€.
μλ¦Ό μ±λμ λ±λ‘νλ©΄ μ μ¬μ§μ²λΌ μ± μ€μ μμ μ±λ μ΄λ¦μ νμΈν μ μλ€.
μ¬μ©μμκ² λ°±κ·ΈλΌμ΄λ μλΉμ€κ° μ€νλκ³ μλ κ²μ μλ ΈμΌλ μ΄μ λ°±κ·ΈλΌμ΄λμμ μμΌ ν΅μ μ μ§ννλ©΄ λλ€. μμ λ§ν κ²μ²λΌ μμΌ ν΅μ μ ν΅ν΄ μλ²λ‘λΆν° μ΄λ²€νΈλ₯Ό μμ νκ³ μ΄λ²€νΈμ μ’ λ₯μ λ°λΌ κ°κΈ° λ€λ₯Έ μλ¦Όμ λμμΌνλ€. μ°μ κ°λ¨νκ² μλ²μμ 1μ μ μ‘νλ©΄ μ΄λ²€νΈ λ°μ μλ¦Ό, 2λ₯Ό μ μ‘νλ©΄ μ΄λ―Έμ§ μ νμ΄λΌλ μλ¦Όμ λμμ£Όλλ‘ κ΅¬ννλ€.
private fun connectSocket() {
var socket: Socket? = null
var inputStream: InputStream?
CoroutineScope(Dispatchers.IO).launch {
try {
socket = Socket(IP_ADDRESS, PORT_NUMBER)
do {
inputStream = socket?.getInputStream()
inputStream?.read().let { data ->
when (data) {
1 -> occurEventNotification()
2 -> selectImageNotification()
}
}
delay(DELAY_TIME)
} while (true)
} catch (e: Exception) {
e.printStackTrace()
} finally {
socket?.close()
}
}
}
μμ²μ λ°λ₯Έ μμ μ μ§ννκ³ delay λ₯Ό ν΅ν΄ μΌμ μκ° λκΈ°νλ€.
μ΄λ²€νΈ λ°μ μλ¦Όκ³Ό μ΄λ―Έμ§ μ νμ λν λ©μλλ μλμ κ°λ€. μ 체μ μΈ μ½λλ μμμ λ΄€λ λ°±κ·ΈλΌμ΄λ μ€νμ μν΄ μλ¦Όμ λμ΄μ£Όλ κ²κ³Ό μ μ¬νλ€. bulider λ‘ μλ¦Όμ λν μ΅μ μ μ€μ νκ³ μλ¦Ό μ±λμ λ±λ‘νλ€.
// μ΄λ²€νΈλ₯Ό μμ νμ κ²½μ° μ¬μ©μμκ² μλ¦Ό μ μ‘
private fun occurEventNotification() {
val bitmap = BitmapFactory.decodeStream(URL(IMAGE_URL).openConnection().getInputStream())
val intent = Intent(this@ReceiverService, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
putExtra("Fragment", "eventDetailFragment")
}
val pendingIntent: PendingIntent =
PendingIntent.getActivity(this@ReceiverService, 0, intent, 0)
val builder = NotificationCompat.Builder(this@ReceiverService, NOTIFICATION_CHANNEL[1])
.setSmallIcon(R.drawable.ic_baseline_poop_solid_icon)
.setContentTitle("λ°°λ³ μ΄λ²€νΈ μμ ")
.setContentText("Device 1μμ λ°°λ³ μ΄λ²€νΈκ° μμ λμμ΅λλ€.")
.setLargeIcon(bitmap)
.setStyle(
NotificationCompat.BigPictureStyle()
.bigPicture(bitmap)
.bigLargeIcon(null)
)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
// Android 26 μ΄μλΆν°λ NotificationChannel λ±λ‘ νμ
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel =
NotificationChannel(
NOTIFICATION_CHANNEL[1],
"μ΄λ²€νΈ λ°μ",
NotificationManager.IMPORTANCE_HIGH
)
val manager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(channel)
}
NotificationManagerCompat.from(this@ReceiverService)
.notify(NOTIFICATION_OCCUR_EVENT, builder.build())
wakeUp()
}
private fun selectImageNotification() {
val intent = Intent(this@ReceiverService, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
putExtra("Fragment", "deviceDetailFragment")
}
val pendingIntent: PendingIntent =
PendingIntent.getActivity(this@ReceiverService, 1, intent, 0)
val builder = NotificationCompat.Builder(this@ReceiverService, NOTIFICATION_CHANNEL[2])
.setSmallIcon(R.drawable.ic_baseline_image_search_24)
.setContentTitle("νμ΅μ© μ΄λ―Έμ§ μ ν")
.setContentText("λͺ¨λΈ μ νλ ν₯μμ μν΄ νμ΅μ© μ΄λ―Έμ§λ₯Ό μ νν΄μ£ΌμΈμ.")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
// Android 26 μ΄μλΆν°λ NotificationChannel λ±λ‘ νμ
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel =
NotificationChannel(
NOTIFICATION_CHANNEL[2],
"νμ΅μ© μ΄λ―Έμ§ μ ν",
NotificationManager.IMPORTANCE_HIGH
)
val manager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(channel)
}
NotificationManagerCompat.from(this@ReceiverService)
.notify(NOTIFICATION_SELECT_IMAGE, builder.build())
wakeUp()
}
μλ²λ Python μ μ¬μ©νλ€. μ€μ λ‘ μλ²μμ νμ΄μ¬μ μ¬μ©νκ³ μμ΄μ λ‘컬μμ ν μ€νΈλ₯Ό μ§ννκΈ° μν μλ² μμ Python μΌλ‘ ꡬννλ€. ν΄λΉ μ½λλ λ€λ₯Έ λΈλ‘κ·Έμ μλ μ½λλ₯Ό μ°Έκ³ νλ€.
import socket
from _thread import *
client_sockets = [] # μλ²μ μ μν ν΄λΌμ΄μΈνΈ λͺ©λ‘
# μ°λ λμμ μ€νλλ μ½λμ
λλ€.
# μ μν ν΄λΌμ΄μΈνΈλ§λ€ μλ‘μ΄ μ°λ λκ° μμ±λμ΄ ν΅μ μ νκ² λ©λλ€.
def threaded(client_socket, addr):
print('>> Connected by :', addr[0], ':', addr[1])
# ν΄λΌμ΄μΈνΈκ° μ μμ λμ λ κΉμ§ λ°λ³΅ν©λλ€.
try:
while True:
print("1 : μ΄λ²€νΈ λ°μ\n2 : μ΄λ―Έμ§ μμ ")
command = int(input()).to_bytes(1, byteorder="little", signed=True)
client_socket.send(command)
except EOFError:
print(">> λͺ
λ Ήμ μ’
λ£ν©λλ€.")
client_socket.close()
# μλ² IP λ° μ΄μ΄μ€ ν¬νΈ
HOST = '127.0.0.1'
PORT = 9999
# μλ² μμΌ μμ±
print('>> Server Start')
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen()
# ν΄λΌμ΄μΈνΈκ° μ μνλ©΄ accept ν¨μμμ μλ‘μ΄ μμΌμ 리ν΄ν©λλ€.
# μλ‘μ΄ μ°λ λμμ ν΄λΉ μμΌμ μ¬μ©νμ¬ ν΅μ μ νκ² λ©λλ€.
try:
while True:
print('>> Wait')
client_socket, addr = server_socket.accept()
client_sockets.append(client_socket)
start_new_thread(threaded, (client_socket, addr))
print("μ°Έκ°μ μ : ", len(client_sockets))
except Exception as e:
print('μλ¬λ? : ', e)
finally:
server_socket.close()
κ²°κ³Ό
μ μμ μΌλ‘ μλνλ κ²μ λ³Ό μ μλ€.
λλ μ
μ μμ μΌλ‘ μλνκΈ΄ νμ§λ§ μλ°ν λ°μ§λ©΄ μλ²½ν ꡬνμ μλλ€. μΉ΄μΉ΄μ€ν‘μ΄λ λ€λ₯Έ μ΄νμ²λΌ μ±μ΄ μ€νλκ³ μμ§ μμ μν©μμλ μλ¦Όμ μμ ν΄μΌνμ§λ§ μ§κΈμ μ±μ΄ μ€νλκ³ μλ μν(onDestoryλ₯Ό μ μΈν μν)μμλ§ μλ¦Όμ΄ λ°μνλ€. FCMμ μ¬μ©νκ±°λ onDestoryμμ Serviceλ₯Ό ν΄μ νμ§ μλ λ°©λ²λ μμ§λ§ λ΄κ° μνλ λ°©λ²μ΄ μλλ€. μ°Ύμ보λ WorkManagerλ₯Ό μ¬μ©νλ©΄ ꡬνμ΄ κ°λ₯ν λ― μΆλ€. μΌλ¨μ μ΄λ κ² κ΅¬νν΄λκ³ λμ€μ Migration ν΄μΌκ² λ€.
'π» κ°λ° > Android' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Android] μλ¦Ό ν΄λ¦μ Activity, Fragmentλ‘ μ΄λ (0) | 2022.06.08 |
---|---|
[Android] MVVM ν¨ν΄ μ μ©κΈ° - 2 (0) | 2022.05.14 |
[Android] MVVM ν¨ν΄ μ μ©κΈ° - 1 (0) | 2022.04.11 |
[Android] μΉ΄λ©λΌ λλ κ°€λ¬λ¦¬μμ μ΄λ―Έμ§ κ°μ Έμ€κΈ° (0) | 2022.02.06 |
[Android] λ€κ΅μ΄ μ§μ (0) | 2022.01.13 |