안드로이드 개발 DB 변경 결과 이후 작업을 위한 옵져버 ContentObserver 활용하는 방법 |
환경: Android Studio 3.0.0 |
Content Provider 은 공동으로 관리할 수 있는 저장소 입니다. 간단한 데이터들은 이곳에 저장하거나 꺼내서 사용합니다. 이렇게 공동으로 사용하다 보니 다른 곳에 영향을 주는 값들이 있습니다. 이런 경우 값이 변경되면 통보를 받을 수 있도록 감시 기능을 설정할 수 있습니다. 그것이 바로 ContentObserver 입니다. 또한, SQLite DB 저장 값이 변경되어도 알림을 받을 수 있습니다.
▼ ContentObserver 클래스를 상속받아 사용자 정의 Observer 클래스를 만들었습니다. 생성자 함수와 onChange() 만 Override 해서 작성합니다.
private class Observer extends ContentObserver { public Observer() { super(null); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); if (!selfChange) { // do stuff // never called when a thread is deleted Log.d("GON", "onChange call"); } } }
▼ ContentObserver 상속받아 만든 클래스를 등록하는 과정은 다음과 같습니다. registerContentObserver() 함수로 URI 와 ContentObserver 를 등록합니다.
private Observer mObserver; private ContentResolver mCr; private void registerObserver(){ Uri URI = Uri.parse("content://sms"); mCr = getContentResolver(); mObserver = new Observer(); mCr.registerContentObserver( URI, true, mObserver ); }
▼ 해제는 간단합니다. Observer 의 unregisterContentObserver() 함수를 이용합니다.
@Override protected void onDestroy() { super.onDestroy(); mCr.unregisterContentObserver(mObserver); }
▼ ContentObserver 의 onChange() 함수를 호출하는 경우는 다음과 같습니다. 주의할 것은 마지막에 getContentResolver().notifyChange() 함수를 실행해야 합니다.
// 버튼 클릭 protected void onSendSMS(View v){ Uri URI = Uri.parse("content://sms"); String[] columns = {"_id", "date"}; Cursor cursor = getContentResolver().query( URI, columns, "type=?", new String[]{"1"}, "_id DESC"); getContentResolver().notifyChange(URI, null); }
▼ 전체 Activity 소스 입니다. 여기에는 퍼미션을 얻는 과정이 있어서 조금 복잡합니다.
import android.Manifest; import android.app.Activity; import android.content.ContentResolver; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Toast; /** * Created by gon on 2017-12-12. * * DB 변경 사항을 알아챌 수 있는 Observer 구현 */ public class ObserverActivity extends Activity { private static final int PERMISSIONS_REQUEST_READ_SMS = 100; private Observer mObserver; private ContentResolver mCr; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_observer); callPermission(); } @Override protected void onDestroy() { super.onDestroy(); mCr.unregisterContentObserver(mObserver); } private void registerObserver(){ Uri URI = Uri.parse("content://sms"); mCr = getContentResolver(); mObserver = new Observer(); mCr.registerContentObserver( URI, true, mObserver ); } // 버튼 클릭 protected void onSendSMS(View v){ Uri URI = Uri.parse("content://sms"); String[] columns = {"_id", "date"}; Cursor cursor = getContentResolver().query( URI, columns, "type=?", new String[]{"1"}, "_id DESC"); getContentResolver().notifyChange(URI, null); } private class Observer extends ContentObserver { public Observer() { super(null); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); if (!selfChange) { // do stuff // never called when a thread is deleted Log.d("GON", "onChange call"); } } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == PERMISSIONS_REQUEST_READ_SMS) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission is granted registerObserver(); } else { Toast.makeText(this, "Until you grant the permission, we canot display the names", Toast.LENGTH_LONG).show(); } } } private void callPermission() { // Check the SDK version and whether the permission is already granted or not. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) { requestPermissions( new String[]{Manifest.permission.READ_SMS}, PERMISSIONS_REQUEST_READ_SMS); } else { // 해당 로직으로 이동 registerObserver(); } } }
▼ Activity 에서 쓰인 레이아웃 XML 입니다.
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btn_sms" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="onSendSMS" android:text="Observer Check"/> </android.support.constraint.ConstraintLayout>
▼ 실행 결과는 Console 에서 확인할 수 있습니다. onChange() 함수를 호출해서 로그를 찍었습니다.
'안드로이드 개발' 카테고리의 다른 글
안드로이드 개발 에뮬레이터 앱 db 조회 하는 방법 (0) | 2018.04.11 |
---|---|
안드로이드 개발 Android GPS 정보 알아오기 (63) | 2018.04.07 |
안드로이드 콘솔에서 adb shell 에러 해결하는 방법 (0) | 2018.03.30 |
안드로이드 개발 자료 관리를 위한 SharedPreferences 사용하는 방법 (0) | 2018.03.24 |
안드로이드 개발 전화번호 조회 퍼미션 에러 해결하는 방법 (0) | 2018.03.12 |
안드로이드 개발 SMS 조회 퍼미션 에러 해결하는 방법 (0) | 2018.03.07 |
안드로이드(Android) Debug 모드 상태 체크하는 방법 (0) | 2018.03.01 |
안드로이드 개발 Vibration 이용해서 스마트폰 진동 설정하는 방법 (0) | 2018.02.22 |