Open jeongiin opened 5 years ago
-> 어플이 실행중이 아니더라도 원하는 작업을 할 수 있음
-> 재부팅 & 문자 메세지 수신
재부팅 권한
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Manifest.xml
<receiver
android:name=".TestReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
TestReceiver(BroadCast)
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.widget.Toast
class TestReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// This method is called when the BroadcastReceiver is receiving an Intent broadcast.
when(intent.action){
"android.intent.action.BOOT_COMPLETED"->{
var t1 = Toast(context,"부팅완료",Toast.LENGTH_SHORT)
//maketext 붙여야 함 //context = this
t1.show()
}
}
}
}
- [x] Q2. 왜 또 빨간줄이..
![image](https://user-images.githubusercontent.com/48753785/66249980-dbb8f680-e776-11e9-99ae-e9234a6505d9.png)
서비스 -> 백그라운드 처리를 위해 제공되는 요소 -> 화면을 갖고 있지 않아서 보이지 않는 동안에도 동작함 -> 코드가 처리가 끝날 때까지 백그라운드에서 계속해서 동작함
Main Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
var service_intent : Intent? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//서비스 가동
button.setOnClickListener { view ->
service_intent = Intent(this, ServiceClass1::class.java)
startService(service_intent)
finish()//서비스가 백그라운드에서 제대로 돌아가는지 확인하기 위함
}
//서비스 중지
button2.setOnClickListener { view ->
stopService(service_intent)
}
}
}
- ServiceClass1
import android.app.Service import android.content.Intent import android.os.IBinder import android.os.SystemClock import android.util.Log
class ServiceClass1 : Service() {
override fun onBind(intent: Intent): IBinder {
TODO("Return the communication channel to the service.")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
var thread = ThreadClass()
thread.start()
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
Log.d("test1","서비스 실행 종료")
}
inner class ThreadClass : Thread(){
override fun run(){
var idx = 0
while (idx<10){
SystemClock.sleep(1000)
var time = System.currentTimeMillis()
Log.d("test1","Service Running : ${time}")
idx++
}
}
}
}
- Intent Service
-- onStartCommand -> onHandleIntent
-- onHandleIntent에 쓰레드를 바로 만들면 됨 (쓰레드 클레시 필요 없음)
- Forground Service (안드로이드 8.0부터 권장)
-- 서비스는 기본적으로 백그라운드에서 운영되는 실행요소로써
메모리가 부족해지면 안드로이드 OS에 의해 제거됨
-- 이를 방지하고자 Forground Service 존재
- ServiseClass3
import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager import android.app.Service import android.content.Context import android.content.Intent import android.graphics.Color import android.os.Build import android.os.IBinder import android.os.SystemClock import android.util.Log import androidx.core.app.NotificationCompat
class ServiceClass3 : Service() {
override fun onBind(intent: Intent): IBinder {
TODO("Return the communication channel to the service.")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
//5초 내에 notification massage를 발생하지 않으면 종료됨
var builder : NotificationCompat.Builder? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
var manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
var channel = NotificationChannel("test1", "Service", NotificationManager.IMPORTANCE_HIGH)
channel.enableLights(true)
channel.lightColor = Color.RED
channel.enableVibration(true)
manager.createNotificationChannel(channel)
builder = NotificationCompat.Builder(this, "test1")
}else {
builder = NotificationCompat.Builder(this)
}
//채널 셋팅
//알림 메세지 등록
builder?.setSmallIcon(android.R.drawable.ic_menu_search)
builder?.setContentTitle("서비스 가동")
builder?.setContentText("서비스가 가동 중입니다.")
var notification = builder?.build()
startForeground(10,notification)
var thread = ThreadClass()
thread.start()
return super.onStartCommand(intent, flags, startId)
}
inner class ThreadClass : Thread(){
override fun run(){
var idx = 0
while (idx<10){
SystemClock.sleep(1000)
var time = System.currentTimeMillis()
Log.d("test1", "Forground Service Running : ${time}")
}
}
}
}
-Main Activity에 추가
button3.setOnClickListener { view -> service_intent = Intent(this, ServiceClass3::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(service_intent) } else { startService(service_intent) } finish() //버전 별로 부르는 코드가 상이함 }
-> Android OS 가 어떤 사건이 일어났을 때 원하는 동작을 하기 위해서 작동
Ex> 문자메세지가 수신된다면 sns관련 reciever 재부팅 된다면 boot complete reciever 배터리 용량이 줄었을 대 메세지 띄워줌
-> 다른 어플리케이션도 실행하도록 만들 수 있음 -> 같은 어플리케이션에서 쓰면 별로 의미 없음
MainActivity
[ ] Q1. 어플의 형식을 맞춰야 하기 때문에 내가 임의로 두개의 어플리케이션을 만드는 것이 아니면 의미가 없는 것이 아닌가?