권한 요청 방법 - 기존 방식 먼저 기존에 안드로이드에서 권한을 요청하기 위해 사용한 방법을 알아보자. 1. manifest manifest 파일의 바깥에 을 넣어준다. 2. 권한 요청 fun requestPermissions() { if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { return } ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQUEST_CODE) } checkSelfPermission()을 통해 현재 권한이 허용되었는지 거부되었는지 확인한다. 만..
Bundle Bundle은 데이터를 저장하기 위한 객체다. 키-값 쌍으로 데이터를 저장하기 때문에, Bundle 내부에서는 Map을 사용한다. Intent와의 차이점 Intent에서 putExtra()를 통해서도 키-값 쌍으로 저장하는데, 무슨 차이일까? Intent의 putExtra() 내부에서도 데이터를 저장하기 위해 Bundle을 사용한다 예를 들어 putExtra() 내부 코드는 아래와 같을 것이다. fun putExtra(name: String, value: String?): Intent { if (mExtras == null) { mExtras = Bundle() } mExtras.putString(name, value) return this } 두 객체 모두 Map을 사용하여 데이터를 키-값..
Broadcast와 BroadcastReceiver의 개념 안드로이드에서는 특정 이벤트가 발생할 때 Broadcast가 전송된다. 특정 Broadcast를 수신하도록 BroadcastReceiver를 등록할 수 있다. 간단히 말해서 어떤 이벤트를 구독하고, 그 이벤트가 발생할 때마다 구독자들에게 알리는 옵저버 패턴이라고 할 수 있다. 여기서 '알림'이 Broadcast, '구독자'가 BroadcastReceiver가 된다. 예를 들어 사용자가 휴대폰을 재부팅시키면, 부팅 이벤트를 등록한 BroadcastReceiver에게 Broadcast를 보낸다. 브로드캐스트의 종류는 상수로 표현되어 있는데, 어떠한 종류가 있는지는 아래 링크 공식문서에서 확인할 수 있다. https://developer.android..
Intent 다른 컴포넌트 간 통신하는 역할을 한다. 실행하고자 하는 컴포넌트를 담은 인텐트를 생성하면, 안드로이드 시스템에서 인텐트 정보에 맞는 컴포넌트를 실행한다. 액티비티를 시작하거나, 서비스/브로드캐스트를 시작할 때 Intent에 클래스명을 넣어 사용한다. 명시적 인텐트 val intent = Intent(this, NotificationActivity::class.java) startActivity(intent) 앱의 패키지명이나 클래스명을 인텐트의 인자로 넣는다. 일반적으로 앱 안의 구성 요소를 시작하고자 할 때 명시적 인텐트를 사용한다. 암시적 인텐트 val sendIntent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.E..
PendingIntent PendingIntent를 직역하면, 보류 인텐트다. 말 그대로 Intent를 바로 시작하지 않고 미루어서 특정 시점에 Intent를 시작하게 해주는 클래스다. PendingIntent를 생성할 때 생성자 메서드로 Intent를 넣는다. 사용자가 외부 앱을 사용하고 있을 때, PendingIntent 안에 있는 Intent를 실행하게 해준다. 외부 앱에게 권한을 허가하여, 자신의 앱 자체 프로세스에서 실행하는 것처럼 사용하게 해주는 것이다. 즉, 외부 앱을 사용하고 있을 때 자신의 앱 Intent를 사용해야 할 경우 PendingIntent를 쓴다. PendingIntent 사용 사례 - 앱 Notification 클릭 시 Intent 실행 - 휴대폰 홈 화면에 있는 앱 위젯 클..
fragment에서 Toast 메시지를 띄우거나 부모 액티비티의 함수를 호출할 때, context/activity가 필요한 경우가 있다. 하지만 Fragment 클래스에는 context가 포함되어 있지 않기 때문에 어떻게 해야할지 곤란했다. - context 얻기 class CustomFragment : Fragment() { private lateinit var mContext: Context override fun onAttach(context: Context) { super.onAttach(context) mContext = context } } fragment 생명주기 가장 처음에 호출되는 onAttach의 인자로 context가 들어옴을 발견했다. 이는 부모 액티비티의 context로, 이 co..
API 33 이후부터 onBackPressed()가 deprecated 되었다. onBackPressed()는 사용자가 뒤로가기 버튼을 누를 때 호출되는 함수로, 주로 뒤로가기 버튼으로 액티비티/앱을 빠져나가는 것을 막을 때 사용했다. 이 함수를 대체할 수 있는 onBackPressedCallback을 알아보려고 한다. onBackPressedCallback은 뒤로가기 버튼이 눌렸을 때 호출되는 콜백이다. 이 콜백을 onBackPressedDispatcher에 추가하면, 버튼이 눌릴 때마다 지정해준 onBackPressedCallback이 호출된다. 1. onBackPressedCallback 생성 뒤로 가기 버튼이 눌렸을 때 어떤 작업을 수행할지 작성 val callback = object : OnBa..
Activity와 Fragment 간에 데이터를 전달하는 방법은 여러가지가 있겠지만, 여기서는 리스너를 활용하는 방법을 작성하려고 한다. 프래그먼트에서 생성하거나 받아온 데이터를, 자신을 호출한 액티비티에서 처리해야 할 경우 사용할 수 있겠다. 1. ListenerInterface 생성하기 interface CustomDialogInterface { fun onAddButtonClicked(date: String, contents: String, posted: String) } 리스너가 한개인 인터페이스를 생성했다. 내 경우에는 custom dialog가 fragment가 되고, add button을 클릭하면 액티비티에 데이터를 전송하는 방식이었기 때문에 인터페이스명/함수명을 이런 식으로 작성했다. 매개..