본문 바로가기

ANDROID의 속삭임

[android][SQLite]ContentProvider


* CitizenContentProvider.java

package com.example.sqlex4;


import java.util.HashMap;


import android.content.ContentProvider;

import android.content.ContentUris;

import android.content.ContentValues;

import android.content.Context;

import android.content.UriMatcher;

import android.database.Cursor;

import android.database.SQLException;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteOpenHelper;

import android.database.sqlite.SQLiteQueryBuilder;

import android.net.Uri;

import android.util.Log;


public class CitizenContentProvider extends ContentProvider {


private static final String DATABASE_NAME = "citizens.db";

private static final int DATABASE_VERSION = 1;

public static final String AUTHORITY = "com.example.sqlex4.CitizenContentProvider";

private DataBaseHelper dbHelper;

private static final UriMatcher sUriMatcher;

private static HashMap<String, String> projectionMap;

// 일반적인 국민 쿼리에 대한 URI 매치

private static final int CITIZENS = 1;

// 특정한 국민 쿼리에 대한 URI 매치

private static final int SSID = 2;

@Override

public int delete(Uri uri, String where, String[] whereArgs) {

// TODO Auto-generated method stub

SQLiteDatabase db = dbHelper.getWritableDatabase();

int count;

switch(sUriMatcher.match(uri)){

case CITIZENS:

// 일반적인 삭제 수행

count = db.delete(CitizenTable.TABLE_NAME, where, whereArgs);

break;

case SSID:

//URI를 통해 SSID 가져오기.

String ssid = uri.getPathSegments().get(CitizenTable.SSID_PATH_POSITION);

//사용자는 특정한 국민을 삭제하기를 원한다.

String finalWhere = CitizenTable.ID + " = " + ssid;

// 사용자가 WHERE 필터를 지정했다면 추가한다.

if( where != null ){

finalWhere = finalWhere + " AND " + where;

}

count = db.delete(CitizenTable.TABLE_NAME, finalWhere, whereArgs);

break;

default : 

throw new IllegalArgumentException("delete, Unknown URI[ " + sUriMatcher.match(uri) + " ]" + uri);


}

getContext().getContentResolver().notifyChange(uri, null);

return count;

}


@Override

public String getType(Uri uri) {

// TODO Auto-generated method stub

switch (sUriMatcher.match(uri)){

case CITIZENS:

return CitizenTable.CONTENT_TYPE;

case SSID:

return CitizenTable.CONTENT_ITEM_TYPE;

default :

throw new IllegalArgumentException("getType, Unknown URI[ " + sUriMatcher.match(uri) + " ]" + uri);

}

}


@Override

public Uri insert(Uri uri, ContentValues initialValues) {

// 일반적인 국민 URI만 입력이 허용된다.

// 당일 행만 입력 되지 않는다.

if(sUriMatcher.match(uri) != CITIZENS){

throw new IllegalArgumentException("insert, Unknown URI[ " + sUriMatcher.match(uri) + " ] " + uri);

}

ContentValues values;

if(initialValues != null){

values = new ContentValues(initialValues);

} else {

values = new ContentValues();

}

SQLiteDatabase db = dbHelper.getWritableDatabase();

long rowId = db.insert(CitizenTable.TABLE_NAME, CitizenTable.NAME, values);

if(rowId > 0){

Uri citizenUri = ContentUris.withAppendedId(CitizenTable.CONTENT_URI, rowId);

// 변경 Context를 통지한다.

getContext().getContentResolver().notifyChange(citizenUri, null);

return citizenUri;

}

throw new SQLException("Failed to insert row into " + uri);

}


@Override

public boolean onCreate() {

// DatabaseHelper 초기화

dbHelper = new DataBaseHelper(getContext());

return true;

}


@Override

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,

String sortOrder) {

// TODO Auto-generated method stub

SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

switch(sUriMatcher.match(uri)){

case CITIZENS: 

qb.setTables(CitizenTable.TABLE_NAME);

qb.setProjectionMap(projectionMap);

break;

case SSID:

String ssid = uri.getPathSegments().get(CitizenTable.SSID_PATH_POSITION);

qb.setTables(CitizenTable.TABLE_NAME);

qb.setProjectionMap(projectionMap);

//특정한 SSID로 쿼리하기 위해

qb.appendWhere(CitizenTable.ID + " = " + ssid);

break;

default:

throw new IllegalArgumentException("query, Unknown URI [ " + sUriMatcher.match(uri) + " ] " + uri);

}

SQLiteDatabase db = dbHelper.getReadableDatabase();

Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);

// 주어진 커서로 NOFITICATION 리스너를 등록한다.

// 커서가 기반 데이의 변경을 알 수 있게 허용한다.

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

return c;

}


@Override

public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {

// TODO Auto-generated method stub

SQLiteDatabase db = dbHelper.getWritableDatabase();

int count;

switch(sUriMatcher.match(uri)){

case CITIZENS :

// 모든 국민에 대한 일반적인 업데이트 

count = db.update(CitizenTable.TABLE_NAME, values, where, whereArgs);

break;

case SSID:

// URI를 통해 SSID 가져오기

String ssid = uri.getPathSegments().get(CitizenTable.SSID_PATH_POSITION);

// 사용자는 특정한 국민을 업데이트하기를 원한다.

String finalWhere = CitizenTable.ID + " = " + ssid;

if (where != null){

finalWhere = finalWhere + " AND " + where;

}

// 특정 국민에 대해 업데이트를 수행한다.

count = db.update(CitizenTable.TABLE_NAME, values, finalWhere, whereArgs);

break;

default:

throw new IllegalArgumentException("update, Unknown URI [ " + sUriMatcher.match(uri) + " ] " + uri);

}

getContext().getContentResolver().notifyChange(uri, null);

return count;

}

private static class DataBaseHelper extends SQLiteOpenHelper{

public DataBaseHelper(Context context){

super(context, DATABASE_NAME, null, DATABASE_VERSION);

}


@Override

public void onCreate(SQLiteDatabase db) {

// TODO Auto-generated method stub

/**

* Create Init Table -S-

*/

            db.execSQL("CREATE TABLE " + CitizenTable.TABLE_NAME + " (" + CitizenTable.ID

                    + " INTEGER PRIMARY KEY AUTOINCREMENT," + CitizenTable.NAME + " TEXT," + CitizenTable.STATE

                    + " TEXT," + CitizenTable.INCOME + " INTEGER);");

            

            /**

      * Create Init Table -E-

      */


}


@Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

// TODO Auto-generated method stub

Log.w(this.getClass().getName(), "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data");

// 업그레이드 되면 이전 테이블을 제거 한다.

db.execSQL("DROP TABLE IF EXISTS " + CitizenTable.TABLE_NAME);

// 스킴의 새로운 인스턴스를 생성한다.

onCreate(db);

}

}

// 정적 변수 블록을 초기화한다.

static {

sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

sUriMatcher.addURI(AUTHORITY, CitizenTable.TABLE_NAME, CITIZENS);

sUriMatcher.addURI(AUTHORITY, CitizenTable.TABLE_NAME + "/" + SSID, SSID);

//행의 별칭 (Alias)를 위해 사용된 프로젝션 맵

projectionMap = new HashMap<String, String>();

projectionMap.put(CitizenTable.ID, CitizenTable.ID);

projectionMap.put(CitizenTable.NAME, CitizenTable.NAME);

projectionMap.put(CitizenTable.STATE, CitizenTable.STATE);

projectionMap.put(CitizenTable.INCOME, CitizenTable.INCOME);

}


}



* CitizenTable.java

package com.example.sqlex4;


import android.net.Uri;


public class CitizenTable {

public static final String TABLE_NAME = "citizen_table";

/**

*  테이블 정의

*/

// ID  칼럼은 반드시 다음 처럼 나타나야 한다.

public static final String ID = "_id";

public static final String NAME = "name";

public static final String STATE = "state";

public static final String INCOME = "income";

/**

* 콘텐츠 타입과 URI를 정의 한다.

*/

//프로바이더의 컨텐트 URI

public static final Uri CONTENT_URI = Uri.parse("content://" + CitizenContentProvider.AUTHORITY + "/" + TABLE_NAME);

//국민 그룹을 위한 마임 타입 (MIME TYPE)

public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.jwei512.citizen";

// 단일 국민을 위한 마임 타입

public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.jwei512.citizen";

// URI의 국민 SSID의 상대적 위치

    public static final int SSID_PATH_POSITION = 1;

}



* MainActivity.java

package com.example.sqlex4;


import android.app.Activity;

import android.content.ContentResolver;

import android.content.ContentValues;

import android.database.Cursor;

import android.net.Uri;

import android.os.Bundle;

import android.view.Menu;


public class MainActivity extends Activity {


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

ContentResolver cr = getContentResolver();

// Uri uri = Uri.withAppendedPath(CitizenTable.CONTENT_URI, "1");

ContentValues contentValue = new ContentValues();

contentValue.put(CitizenTable.NAME, "Jason Wei");

contentValue.put(CitizenTable.STATE, "CA");

contentValue.put(CitizenTable.INCOME, 100000);

cr.insert(CitizenTable.CONTENT_URI, contentValue);

// cr.insert(uri, contentValue);

contentValue = new ContentValues();

contentValue.put(CitizenTable.NAME,  "James Lee");

contentValue.put(CitizenTable.STATE, "NY");

contentValue.put(CitizenTable.INCOME, 120000);

cr.insert(CitizenTable.CONTENT_URI, contentValue);

// cr.insert(uri, contentValue);

contentValue = new ContentValues();

contentValue.put(CitizenTable.NAME,  "Deniel Lee");

contentValue.put(CitizenTable.STATE, "NY");

contentValue.put(CitizenTable.INCOME, 80000);

cr.insert(CitizenTable.CONTENT_URI, contentValue);

// cr.insert(uri, contentValue);

// 모든 칼럼과 행을 위한 테이블 쿼리 

Cursor c = cr.query(CitizenTable.CONTENT_URI, null, null, null, CitizenTable.INCOME + " ASC ");

// 액티비티가 커서를 관리하게 한다.

//startManagingCursor(c);

int idCol = c.getColumnIndex(CitizenTable.ID);

int nameCol = c.getColumnIndex(CitizenTable.NAME);

int stateCol = c.getColumnIndex(CitizenTable.STATE);

int incomeCol = c.getColumnIndex(CitizenTable.INCOME);

while( c.moveToNext()){

int id = c.getInt(idCol);

String name = c.getString(nameCol);

String state = c.getString(stateCol);

int income = c.getInt(incomeCol);

System.out.println( "RETRIEVED || " + id + " || " + name + " || " + state + " || " + income );

}

if( c != null ){

c.close();

}

System.out.println("---------------------------------------------------------");

// 특정한 ID로 

Uri myCitizen = Uri.withAppendedPath(CitizenTable.CONTENT_URI, "2");

Cursor c1 = cr.query(myCitizen, null, null, null, null);

// 액티비티가 커서를 관리하게 한다.

//startManagingCursor(c1);

while(c1.moveToNext()){

int id = c1.getInt(idCol);

String name = c1.getString(nameCol);

String state = c1.getString(stateCol);

int income = c1.getInt(incomeCol);

System.out.println( "RETRIEVED || " + id + " || " + name + " || " + state + " || " + income );

}

if( c1 != null ){

c1.close();

}

}


@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true;

}


}



* AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.sqlex4"

    android:versionCode="1"

    android:versionName="1.0" >


    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="17" />


    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name="com.example.sqlex4.MainActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />


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

            </intent-filter>

        </activity>

        <provider android:name="com.example.sqlex4.CitizenContentProvider"

            android:authorities="com.example.sqlex4.CitizenContentProvider" />

        

    </application>


</manifest>