1. 알람
1) 알람 추가 다이얼로그
mainFbtnAddalarm.setOnClickListener {
val builder = AlertDialog.Builder(this@MainActivity)
builder.setTitle("알림 추가")
builder.setIcon(R.mipmap.ic_launcher)
val bindingDialog = DialogAlarmBinding.inflate(layoutInflater)
val items = arrayOf("없음","5분","15분","30분")
val adapter = ArrayAdapter(this@MainActivity,android.R.layout.simple_spinner_dropdown_item,items)
bindingDialog.dialongSpinnerTime.adapter=adapter
builder.setView(bindingDialog.root)
val listener = DialogInterface.OnClickListener { _,_->
val selected=bindingDialog.dialongSpinnerTime.selectedItemPosition
val time=when(selected){
0 -> 0
1 -> 5
2 -> 15
else -> 30
}
showNotification(bindingDialog.dialogEtName.text.toString(), time)
}
builder.setPositiveButton("확인",listener)
builder.setNegativeButton("취소",null)
builder.show()
}
2)알람 채널 생성- 이부분은 onCreate()에서 메소드 실행
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Android 8.0
val channel = NotificationChannel(
channelID, "default channel",
NotificationManager.IMPORTANCE_DEFAULT
)
channel.description = "call alarm"
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
3)알람 띄우기
private fun showNotification(str:String, time:Int) {
val builder = NotificationCompat.Builder(this, channelID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("연락처 알림")
.setContentText(str+"에게 연락할 시간입니다.")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.POST_NOTIFICATIONS
) != PackageManager.PERMISSION_GRANTED
) {
getPermission()
return
}
Thread{
Thread.sleep((60*1000*time).toLong())
NotificationManagerCompat.from(this).notify(myNotificationID, builder.build())
}.start()
}
-알람띄우기까지 시간을 기다리는걸 Thread.sleep을 이용
2. 권한 부여
1)AndroidManifest에 권한 추가
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
2)권한 체크 후 권한 받아오기- 권한을 모두 받은 상태일 경우 뷰 초기화 시작
fun getPermission(){
if(Build.VERSION.SDK_INT < 33){
val permissions = arrayOf(android.Manifest.permission.READ_CONTACTS, android.Manifest.permission.CALL_PHONE,
android.Manifest.permission.SEND_SMS,
android.Manifest.permission.INTERNET, android.Manifest.permission.READ_CALL_LOG)
var flag=false
for(i in permissions){
if(checkSelfPermission(i) == PackageManager.PERMISSION_DENIED){
flag=true
}
}
if(flag) requestPermissions(permissions,0)
else initView()
}else{
val permissions = arrayOf(android.Manifest.permission.READ_CONTACTS, android.Manifest.permission.CALL_PHONE,
android.Manifest.permission.POST_NOTIFICATIONS,android.Manifest.permission.SEND_SMS,
android.Manifest.permission.INTERNET, android.Manifest.permission.READ_CALL_LOG)
var flag=false
for(i in permissions){
if(checkSelfPermission(i) == PackageManager.PERMISSION_DENIED){
flag=true
}
}
if(flag) requestPermissions(permissions,0)
else initView()
}
-알림 권한은 SDK 버전 33부터 받아야 하므로 if문으로 나눠서 다르게 받음
3)권한 받아왔을때 모든 권한을 받았으면 뷰 초기화 시작
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode ==0){
var flag=true
for(i in grantResults){
if(i==PackageManager.PERMISSION_DENIED) flag=false
}
if(flag) initView()
}
}
3. 애니메이션 상태 체크해서 변수 설정하기
listLlGridlist.setOnClickListener{
mainViewWhitebtn.callOnClick()
listMlGridlist.setTransitionListener(object :MotionLayout.TransitionListener{
override fun onTransitionStarted(
motionLayout: MotionLayout?,
startId: Int,
endId: Int
) {
return
}
override fun onTransitionChange(
motionLayout: MotionLayout?,
startId: Int,
endId: Int,
progress: Float
) {
return
}
override fun onTransitionCompleted(
motionLayout: MotionLayout?,
currentId: Int
) {
isGrid = motionLayout!!.currentState==motionLayout!!.startState
println(isGrid)
}
override fun onTransitionTrigger(
motionLayout: MotionLayout?,
triggerId: Int,
positive: Boolean,
progress: Float
) {
return
}
})
}
-애니메이션이 동작 완료되었을때 체크해서 어느상태인지 확인 후 변수 설정
4. 착발신 기록 가져오기
1)착발신 기록 데이터 구조
data class CallLogEntity(
var name: String?,
val type: String,
val number: String,
val date: String,
val Duration: Int
)
2)착발신 기록 가져오기
fun callHistory(context: Context):ArrayList<CallLogEntity>{
val logs=ArrayList<CallLogEntity>()
val callSet= arrayOf(CallLog.Calls.TYPE, CallLog.Calls.NUMBER, CallLog.Calls.DATE, CallLog.Calls.DURATION)
val cursor = context.contentResolver.query(CallLog.Calls.CONTENT_URI,callSet,null,null,null)
?: return logs
while(cursor.moveToNext()){
val typeidx=cursor.getColumnIndex(callSet[0])
val numberidx=cursor.getColumnIndex(callSet[1])
val dateidx=cursor.getColumnIndex(callSet[2])
val durationidx=cursor.getColumnIndex(callSet[3])
val type=if(cursor.getInt(typeidx)==CallLog.Calls.INCOMING_TYPE) "착신" else "발신"
val number = cursor.getString(numberidx)
val date=SimpleDateFormat("yyyy-MM-dd").format(Date(cursor.getLong(dateidx)))
val duration =cursor.getDouble(durationidx).toInt()
logs+=CallLogEntity(null,type,number,date,duration)
}
return logs
}
3)ContactDataSource에서 by lazy로 변수 선언
val CallLogEntities by lazy { callHistory(application) }
4)ContactRepositoryImpl에서 전화기록에 저장된 연락처를 가지고 이름 데이터 붙여 가져오기
override fun getCallLogs(): ArrayList<CallLogEntity> {
val map=contactDataSource.ContactEntities.associate { it.num to it.name }
val callLogs=contactDataSource.CallLogEntities
for(i in callLogs){
i.name = map.getOrDefault(i.number,i.number)
}
return callLogs
}
'코틀린 팀플3-연락처 어플 만들기' 카테고리의 다른 글
서비스 로케이터를 MVVM으로 변경, 알람 기능 확장 (0) | 2024.07.26 |
---|---|
연락처 가져오기-레포지토리 패턴&서비스 로케이터 패턴, 권한 부여 (0) | 2024.07.23 |