카테고리 보관물: Android

Android ROOM 사용한 Master/Detail 관계 정의

개요

Android ROOM 은 Android Jetpack 에 포함된 컴포넌트 입니다. SQLite DB에 쉽게 접속하고 이용할 수 있게 해 주는 일종의 ORM(Object-relational mapping) 라이브러리 입니다. 이전에는 SQLite DB에 접속하려면 정형화된 별도의 클래스를 사용했습니다. 조금 지루한 작업이라고 할 수 있었습니다. 이것을 줄여주고 쉽게 SQLite DB 연동작업을 할 수 있도록 도와줍니다.

기초적인 연동방법은 좋은 글이 많으므로 그것을 참고하시면 됩니다. 이 글에서는 부모가 되는 테이블과 자식이 되는 테이블을 어떻게 정의하는지 살펴보도록 하겠습니다. 언어는 코틀린(Kotlin)을 기준으로 합니다.

Master/Detail 관계 정의

Master/Detail 관계는 기본적으로 1:N(일대다) 으로 이해하시면 됩니다. 하나의 부모에 자식이 여럿있는 개념입니다. 1:N(일대다) 관련 자료를 찾아보시면 더 자세한 내용을 보실 수 있습니다.

Android ROOM 에서는 클래스 파일에 테이블을 정의합니다. 코드는 다음과 같습니다.

@Entity(tableName = "test_parent")
class TestParent(@PrimaryKey @ColumnInfo(name = "parent_seq") var parentSeq: Int,
          @ColumnInfo(name = "parent_name") var parentName: String?,
.
.
.
)

@Entity(
    tableName = "test_detail",
    indices = [Index("parent_seq")],
    foreignKeys = [ForeignKey(entity = TestParent::class, parentColumns = ["parent_seq"], childColumns = ["parent_seq"], onDelete = ForeignKey.NO_ACTION)]
)

class TestDetail(@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "test_detail_seq") var testDetailSeq: Int,
                @ColumnInfo(name = "parent_seq") var parentSeq: Int,
.
.
.
)

12행이 핵심입니다. 부모 컬럼과 자식 컬럼이 지정된 것을 볼 수 있습니다. onDelete는 부모 테이블의 자료가 삭제되었을때의 동작입니다. 예제에서는 아무런 동작도 하지 않도록 했습니다. 각자의 상황에 맞는 값을 지정하면 됩니다. 사용할 수 있는 값과 의미는 다음의 주소에서 확인할 수 있습니다.

https://developer.android.com/reference/android/arch/persistence/room/ForeignKey.html#CASCADE

결과만 보면 간단한데 Master/Detail 관계를 정의한 예제를 거의 찾아볼 수 없었습니다. 코틀린(Kotlin)으로 된 예제는 없었습니다. 위 코드를 참조하셔서 필요한 부분에 적용하시면 됩니다.

필요한 필드만 업데이트

android ROOM을 이용해서 테이블을 갱신(update)해야 하는 경우가 있습니다. 기본적인 예제를 적용해보면 모든 필드가 갱신되는 것을 알 수 있습니다. 필요한 필드만 갱신하려면 Query 형태로 정의해야 합니다. Data Object Access(DAO) 클래스에 다음과 같이 정의합니다.


    @Query("update test_parent set parent_name = :parentName, photo = :parentPhoto, memo = :parentMemo where parent_seq = :parentSeq")
    fun updateParent(parentSeq:Int, parentName:String?, parentPhoto:String?, parentMemo:String?)

변수로 값을 전달해서 Query 내에 :변수명 형태로 대입해서 필요한 필드만 갱신 되도록 작업하시면 됩니다.

이상 Android ROOM 라이브러리를 사용한 Master/Detail 관계 정의에 대해서 알아보았습니다.

정책 위반으로 Google Play에서 앱이 삭제되었을 때 대처법

개요

가끔 구글 플레이 개발자 화면에서 안드로이드앱 다운로드수와 현재 사용자 정보를 확인합니다. 개발자 이메일로 등록된 메일도 같이 확인합니다. 종종 문의가 오는 경우가 있기 때문입니다. 그러던 어느날 갑자기 메일이 많이왔습니다. 이상한 생각이 들어 확인해 보니 제목이 [앱이름]에 대한 Google Play 알림 이었습니다. 내용을 확인해 보니 다음과 같은 내용이 포함되어 있었습니다.

앱이름(your.package.name) 을(를) 검토한 결과 정책 위반으로 Google Play에서 앱이 삭제되었습니다. 귀하의 앱은 정책을 따르는 업데이트를 제출할 때까지 사용자에게 제공되지 않습니다.

‘이런! 이게 무슨 소리지? 삭제라니!’

개발자 화면을 확인해 보니 상태가 삭제됨 상태로 되어 있었습니다. 크게 당황하였고 무엇이 잘못된 것인지 알 수 없었습니다. 갑자기 모든 앱이 삭제된 것은 납득하기 어려웠습니다. 마음을 가다듬고 차근차근 생각해 보니 공통적으로 광고가 포함되어 있었습니다.

앱이 삭제된 상태

앱이 삭제된 상태

원인

결과적으로 원인은 메일 내용에 설명이 되어 있었습니다. 구글에서 온 메일에 다음과 같은 내용이 있었습니다.

귀하의 앱이 개인정보나 기기정보를 다룬다면 개발자님은 유효한 개인정보 보호정책을 제공해 주셔야 합니다.

개인정보 취급방침 정보가 없어서 문제가 발생한 것이 원인이라는 내용이었습니다. 이상한 것은 필자의 앱은 명시적으로 개인정보나 기기정보를 다루지는 않았습니다. 광고 표시 중 사용자를 식별할 수 있는 정보가 전송된 가능성이 있을 것 같았습니다. 광고 설정 부분에서 찾아보니 사용자 식별 정보와 관련있는 항목이 없었습니다. 광고쪽과 관련된 어떤 것도 설정을 변경할 만한 것이 없었습니다. 그래서 앱을 올릴 때 [지금 개인정보처리방침 URL을 제출하지 않습니다.] 를 선택한 것이 문제가 된 것으로 판단했습니다.

해결방법

다른 앱을 참고해서 개인정보처리방침 초안을 만들었습니다. 그 다음 각 앱마다 온라인 워드프로세서에 내용을 올리고 읽기 전용으로 변경했습니다. 앱 정보에 개인정보처리방침 링크를 입력해서 업데이트 했습니다. 이렇게 해서 복구가 되지 않으면 다른 방법을 강구할 예정이었습니다. 다행히 한 시간 내로 모두 다시 출시됨 상태로 변경되었습니다.

앱이 개인정보나 기기정보를 다루지 않고 광고가 포함되어 있는 경우 이런 방법으로 해결하시면 될 것으로 생각됩니다.