진짜 개발자
본문 바로가기

App/Android

Android - Content Resolver

728x90

CP(Content Provider) - 안드로이드에서 응용프로그램간에 데이터를 공유하는 유일한 방법

(안드로이드는 보안 정책상 응용프로그램에서 만든 데이터는 해당 응용프로그램만이 사용가능)

        - 대부분의 응용프로그램에서는 자신의 데이터베이스에 접근을 허용하기위한 ContentProvider를 구현하고 있다

*CP구현도

=====A어플===== =====B어플=====

       (제공)     (반환)

|DB|  ------> |CP|  -------------> |CR|

       <------       <-------------

       (접근)     (요청)

*사용법

     ===데이터를 제공하는 앱에서 구현해야하는 CP===

1. ContentProvider 를 구현하는 클래스 생성

2. 필요한 메소드들 오버라이딩

3. ContentProvider의 authority 정의 (보통 패키지명 사용 <= 중복방지)

  ex) public static final String AUTHORITY = "com.example.galid.hello.UserProvider";

4. 상수(int)로 code들을 정의해 놓는다 (URI 매치시 가독서을 위해)

5. static 블록안에서 UriMatcher객체를 생성하고(uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);)

6. uriMatcher.addURI() 메소드를 이용하여 제공할 URI들을 매칭시켜 놓는다

  ex) uriMatcher.addURI(AUTHORITY , "users/name" , ALLNAME); <= 경로의 전체 정보를 지칭(복수)

       uriMatcher.addURI(AUTHORITY , "users/name/*" , NAME);  <= 경로의 특정 정보를 지칭(단수) , '/*' 를 붙혀준다.

7. 제공할 메소드에서 uriMatcher.match(uri) 를 이용하여 분기한다음 제공한다.

*주의 : 분기시 "where = '" + id + "'";   (') 싱글 코테이션으로 id를 감싼다.

         또 id를 uri.getSegmentPath().get(번호) 을 이용하여 가져올때  path 와 id를 구분하여 가져오지 않으므로

uri.getSegmentPath()메소드를 통해 리턴되는 list<> 에 무엇이 들어있는지 확인한다.!!

8. 마지막으로 Manifest에 <provider> 태그를 이용하여 CP를 등록한다

       ex) <provider>

            android:name=".UserProvider"

            android:authorities="com.example.galid.hello.UserProvider"   <= authorities 는 CP를 구현한 클래스에서 선언한 AUTHORITY와 같아야한다 !

            android:exported="true"/>

   ===데이터를 제공받는 앱에서 구현해야하는 CR===

1. CR 객체를 생성

ex) ContentResolver cr = getContentResolver();

2. 제공받을 앱에서 제공하는 AUTHORITY를 선언

ex) public static final String AUTHORITY = "content:// com.example.galid.hello.UserProvider"

3. 필요한 메소드를 구현 (일단 데이터를 제공받는 select)

     ㄱ. 더 상세한 정보를 원할시 AUTHORITY에 필요정보 PATH(경로)를 더한다음 Uri 로 파싱한다

ex) String url = AUTHORITY + "users/name/galid";

     String uri = Uri.parse(url);

     ㄴ. CR 객체를 이용하여 구현한다

ex) Cursor cursor = cr.query( uri , null , null , null , null );     

*URI클래스

*URI - 정보의 위치를 나타내는 고유한 명칭이다

ex) content://   com.example.galid.UserProvider   /users/name/   gag

                 ======  |  ==================== | ======= | ==

       1.CP              2. authority                         3. path     4.id

1. content:// : 컨텐트프로바이더를 사용함을 나타내는 고유 명칭

2. authority : CP의 명칭으로 CP가 중복되는것을 방지한다(보통 패키지의 이름)

3. path : 정보가 위치한 경로

4. id : 구체적으로 어떤 정보를 원하는지 명시할 때 사용 (전체정보를 읽을 때에는 생략)

*단수 복수

1. 단수 : 하나의 특정 정보만을 지칭 (path이후 id 부분을 추가로 적어준다)

ex) content:// com.example.galid.UserProvider/users /name/*

          -- id부분

2. 복수 : 경로의 정보 전체를 불러온다 (path이후 id 부분을 생략한다)

ex) content:// com.example.galid.UserProvider/users/ name

*메소드

1. Uri Uri.parse(String uristring) : 매개변수로 받은 문자열을 Uri로 변환하여 반환

2. List<String> getPathSegments() : URI의 Path정보를 문자열 목록으로 조사하는 메소드

=> 위의 예에서는 반환값으로 { 0 : users , 1 : id , 2 : gag } 가 전달된다

*URIMatcher클래스

- URI와 code(int)를 매칭시켜 맵핑시켜 놓고 들어오는 URI와 맵에 있는 URI와 비교하여 해당 code를 리턴시켜 준다.

*메소드

1. void addUri(String authority , String path , int code) : authority 와 path를 결합하여 code로 맵핑시킨다.

2. int match(Uri uri) : 매개변수 uri와 맵에 있는 uri들을 비교하여 code(int)를 리턴한다.

*ContentProvider클래스

- 추상클래스로 제공해야하는 데이터가 있는 앱에서 구현해야한다

- 데이터베이스를 제공하기위한 여러메소드들을 오버라이딩 한다 모두 할 필요는 없고 필요한

  메소드들만을 재정의하여 제공한다 (query , getType , insert , delete , update)

  재정의하는 것이므로 매개변수를 모두 사용할 필요없이 자기가 원하는대로 만들어 반환 해주면 된다

  ex) Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){

Cursor cursor = db.rawQuery("select * from user" , null);

return cursor;

       }

**주의점

1. uri.getSegmentPath().get( 번호 ); : 이 메소드는 path 와 id를 구분하지 않고 Authority 이후의 모든 문자들을

          '/' 문자로 구분하여 배열에 담는다 id를 가져오고 싶다면  번호를 잘 입력해야한다.

2. where절 'uri.getSegmentPath().get(2)' : sql문에 where절을 추가할 경우 꼭 ' ' (싱글 코테이션) 을 붙혀준다.

*ContentResolver클래스

- 다른 앱으로부터 제공받아야 하는 데이터가 있는 앱에서 구현해야 한다

- 외부앱의 CP를 사용하기위해 사용하는 클래스이다

*메소드

1. ContentResolver getContentResolver() : 컨텐트 리졸버 객체를 반환하는 메소드이다.

2. contentResolver은 외부 앱의 CP에 접근하는 다양한 메소드를 지원