|
안드로이드 개발 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 |

