티스토리 뷰

자 이제 커스텀한 Content Provider를 만들어보자.


Content Provider를 만들어서 DB에 접근해서 값을 가져올 수 있다.


사실 나의 목적은 다른앱에서 앱의 정보를 주는 것이다.


예를 들면, 과거의 앱 대신 완전히 새로운 앱으로 업데이트 해주고 싶을 경우.

이전 앱의 세팅값을 가져오기 위해, 이전 앱에 Content Provider를 만들어줘서

업데이트하고 싶은 값들을 insert하고,

새로운 앱에서 이전 앱에서 만든 Content Provider의 Contract (계약서)를 가져와서,

Content Provider를 사용함으로 세팅값을 업데이트 칠 수 있단다.




뭐 대충 이런 식이다. 전체적인 그림은.


과거 앱에서 Content Provider와 Contract를 선언하고,


새로운 앱에서는 Contract만 가져와서 과거 앱의 Content Provider를 가져다 쓴다.


이에 대한 자세한 플로우는 아래와 같다.



이 그림과 같은 흐름을 우리는 코드로 짜주면 되는 것이다.


그럼 본격적으로 Content Provider를 만들어보자.


자 순서는 이렇다.


1. Content Provider 상속받는 class 만든다.


2. Manifest 파일에  Content Provider 만든다.


3. URI들을 정의한다.


4. Contract class URI들을 작성한다.


5. URIMatcher URI 패턴을 정수형으로 맞춰진다.


6. CRUD 메소드를 정의한다.



1번 부터 고고. 어렵지 않음 요렇게 상속 받으셈. 참 쉽쥬~ㅋㅋ

public class TestContentProvider extends ContentProvider {


2번 AndroidManifest.xml 파일에 우리가 만든 Content Provider를 선언해주십시다.


<provider 라는 속성을 <application 안에 지정해 주면 됩니다!


근데 여기서 주요사항 한가지!!


바로바로 android:exported= 에 대한 값!!


이것이 false면 외부 앱에서 작성한 앱의 content provider에 접근이 불가하다.


따라서 false로 해주면 우리가 본래하려고 했던 취지와 벗어나게 된다. 즉, 앱 내부에서만 Content Provider를 이용할 때는 false로 선언해주는게 맞단디~

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<provider
android:authorities="com.rimduhui.contentprovidertutorial"
android:name=".TestContentProvider"
android:exported="true"/>

</application>


선언까지 잘해주었으니 3번 계약서 작성합세.


계약서에서 중요한 건 AUTHORITY를 선언하고, 그리고 URI를 만들어주는 스킬 잘보셈~


http://rimduhui.tistory.com/26


Uri 관련해서 잘 모르면 참조해주세요.

public class TestContract {
public static final String AUTHORITY = "com.rimduhui.contentprovidertutorial";
public static final String ID = "#";
public static final String BASE_PATHS = "test";
public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY);
public static final Uri BASE_PATH_URI = BASE_URI.buildUpon().appendPath(BASE_PATHS).build();

public static final int TESTS = 100;
public static final int TEST_BY_ID = 101;
public static final UriMatcher TestUriMatcher = buildUriMatcher();

private static Uri buildIdPath() {
return BASE_PATH_URI.buildUpon().appendPath(ID).build();
}
}


그 담에 4, 5번 UriMatcher를 통해 Uri를 정수화 시켜줍시다.


이것을 통해 원하는 Uri를 Switch문으로 접근하는 그런 코딩을 할꺼임.

public static UriMatcher buildUriMatcher() {
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, BASE_PATHS, TESTS);
uriMatcher.addURI(AUTHORITY, BASE_PATHS + "/" + ID, TEST_BY_ID);
return uriMatcher;
}


마지막으로 CRUD 고고.


일단 요거 할라면,


http://rimduhui.tistory.com/27


요거부터 자세히 보고 오셈. 위에꺼 보면 잘 설명되니 설명 생략.

@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
SQLiteDatabase db = dbHelper.getReadableDatabase();

UriMatcher matcher = buildUriMatcher();
int match = matcher.match(uri);

Cursor retCursor = null;

switch (match) {
case TestContract.TESTS :
retCursor = db.query(TestEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
break;
}

retCursor.setNotificationUri(getContext().getContentResolver(), uri);

return retCursor;
}

@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}

@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
SQLiteDatabase db = dbHelper.getWritableDatabase();

// UriMatcher

long id = db.insert(TestEntry.TABLE_NAME, null, values);
Uri returnUri = null;
if (id > 0) {
returnUri = uri.withAppendedPath(TestContract.BASE_PATH_URI, String.valueOf(id));
} else {
Toast.makeText(getContext(), "ERROR insert", Toast.LENGTH_LONG).show();
}

getContext().getContentResolver().notifyChange(uri, null);
return returnUri;
}

@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();

String deleteItemId = uri.getPath();
String mSelection = "_id=?";
String[] mSelectionArgs = new String[]{deleteItemId};

int returnId = db.delete(TestEntry.TABLE_NAME, mSelection, mSelectionArgs);

getContext().getContentResolver().notifyChange(uri, null);
return returnId;
}

@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}



자, 여기까지 오느라 고생이 많으셨어유~~ 그럼 다음으로 저 만든 저 놈 바로 저 놈 Content Provider를 외부 앱에서 가져다가 쓰는 법을 보여드리겠음.


자 가자.


짱 쉬움. 


Step은 두 단계


1. Contract (계약서) 가져오자.


2. ContentResolver를 통해 계약서 써있는 필요한 Uri로 Cursor를 가져오자.


자 1번, 위랑 똑같은거 복붙해쯤

public class TestContract {
public static final String AUTHORITY = "com.rimduhui.contentprovidertutorial";
public static final String ID = "#";
public static final String BASE_PATHS = "test";
public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY);
public static final Uri BASE_PATH_URI = BASE_URI.buildUpon().appendPath(BASE_PATHS).build();

public static final int TESTS = 100;
public static final int TEST_BY_ID = 101;

public static final String COLUMN_INT = "intager";

private static Uri buildIdPath() {
return BASE_PATH_URI.buildUpon().appendPath(ID).build();
}
}


2번은 그냥 이렇게 원하는 명령어 때리면 됨. 끝나쪄.

Cursor cursor = getContentResolver().query(TestContract.BASE_PATH_URI, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
result.setText(String.valueOf(cursor.getInt(cursor.getColumnIndex(TestContract.COLUMN_INT))));
}


Past App 역할을 하는 앱. (Content Provider 생성)

https://github.com/rimduhui/android-custom-content-provider-tutorial.git


New App 역할을 하는 앱. (생성된 Content Provider 가져다 씀)

https://github.com/rimduhui/android-access-content-provider-tutorial.git


다들 화이팅 하셈요!

'개발 > 안드로이드' 카테고리의 다른 글

Android Context!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  (0) 2017.11.16
Android Different Languages 적용기  (1) 2017.11.15
Android SQLite Database  (3) 2017.10.27
Android Content Provider  (0) 2017.10.26
Android Permissions  (0) 2017.10.25
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31