ContentProvider 만들기 (1)

ContentProvider를 상속 받아 만들면 되겠지 하고 시작하면 뭐 허접한 클래스 하나 나올겁니다.

UriMatcher 도 사용하고 여러 테이블을 한꺼번에 처리하기 위해서는 조금 신경써야 합니다.

조금만 신경쓰면 확장성이 좋은 ContentProvider를 만들 수 있습니다.


public interface baseColumns {

	/**
	 * 아이디
	 */
	final String _ID 		= "_id";
	
	/**
	 * 컬럼 배열을 리턴하는 함수
	 * @return 컬럼 배열 반환 String[]
	 */
	abstract String[] getColumns();
	abstract HashMap getProjection();
	abstract String getTableName();
	abstract String getIdColumnName();
	abstract String[] getRequiredColumns();
	abstract void create(SQLiteDatabase db);
	abstract void drop(SQLiteDatabase db, int oldVersion, int newVersion);
}
이 인터페이스를 베이스로 확장성 있는 Provider 모듈을 만들면 도움이 될것 같습니다.
public class myProvider extends ContentProvider {
	
    private static final String TAG = "myProvider";

    private static final int XXXX		= 1;

	private static final UriMatcher MATCHER;
    
	public static final String URI_STRING = "content://com.sample.Provider/sample";
	public static final String PROVIDER = "com.xxx.Provider";
    public static final Uri CONTENT_URI = Uri.parse(URI_STRING);
    
    private static HashMap MY_PROJECTION;

	static {
		MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		MATCHER.addURI(PROVIDER, "xxx", XXXX);
	
		MY_PROJECTION = new xxx().getProjection();
	}

	private SQLiteDatabase db;

	@Override
	public boolean onCreate() {
		db=(new databaseHelper(getContext())).getWritableDatabase();		
		return (db == null) ? false : true;
	}
	
	@Override
	public Cursor query(Uri url, String[] projection, String selection,
												String[] selectionArgs, String sort) {
		
		final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();	
		final int nUriType = getUriType(url);
	
		qb.setTables(getTableName(nUriType));
		
		if (isCollectionUri(nUriType)) {
			qb.setProjectionMap(getDefaultProjection(nUriType));
		}
		else {
			qb.appendWhere(getIdColumnName(nUriType)+"="+url.getPathSegments().get(1));
		}
		
		String orderBy;
		
		if (TextUtils.isEmpty(sort)) {
			orderBy=getDefaultSortOrder(nUriType);
		} else {
			orderBy=sort;
		}
	
		Cursor c=qb.query(db, projection, selection, selectionArgs,
											null, null, orderBy);
		c.setNotificationUri(getContext().getContentResolver(), url);
		return c;
	}
	
	private boolean isCollectionUri(int nUriType) {
		switch(nUriType) {		
		case XXXX :
			return false;
		}
		
		return false;
	}

	@Override
	public String getType(Uri url) {
		final int nUriType = getUriType(url);
		if (isCollectionUri(nUriType)) {
			return(getCollectionType());
		}
		
		return(getSingleType());
	}
	
    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) 
    									throws FileNotFoundException {
        return openFileHelper(uri, mode);
    }
    
	@Override
	public Uri insert(Uri url, ContentValues initialValues) {
		long rowID = 0;
		ContentValues values = null;
		
		if (initialValues == null) {
			return null;
		}
		
		final int nUriType = getUriType(url);
		values = new ContentValues(initialValues);
        if (values == null) return null;
	
		if (!isCollectionUri(nUriType)) {
			throw new IllegalArgumentException("Unknown URL " + url);
		}
		
		for (String colName : getRequiredColumns(nUriType)) {
			if (values.containsKey(colName) == false) {
				throw new IllegalArgumentException("Missing column: "+colName);
			}
		}
	
		populateDefaultValues(values);

		if (rowID > 0) {			
			final Uri uri=ContentUris.withAppendedId(getContentUri(), rowID);
			getContext().getContentResolver().notifyChange(uri, null);
			return uri;
		}
	
		throw new SQLException("Failed to insert row into " + url);
	}
	
	@Override
	public int delete(Uri url, String where, String[] whereArgs) {
		int count = 0;
		long rowId = 0;
		
		final int nUriType = getUriType(url);
		if (isCollectionUri(nUriType)) {
			count=db.delete(getTableName(nUriType), where, whereArgs);
		}
		else {
			String segment=url.getPathSegments().get(1);
			rowId=Long.parseLong(segment);
			count=db.delete(getTableName(nUriType), getIdColumnName(nUriType)+"="
						+ segment
						+ (!TextUtils.isEmpty(where) ? " AND (" + where
						+ ')' : ""), whereArgs);
		}
	
		getContext().getContentResolver().notifyChange(url, null);
		return count;
	}
	
	@Override
	public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
		int count;
		
		final int nUriType = getUriType(url);
		if (isCollectionUri(nUriType)) {
			Log.d(TAG, String.format("update: %s", url.toString()));
			count = db.update(getTableName(nUriType), values, where, whereArgs);
		}
		else {
			final String segment = url.getPathSegments().get(1);
			count = db
					.update(getTableName(nUriType), values, getIdColumnNameToUpdate(nUriType)+"="
							+ "'" + segment + "'"
							+ (!TextUtils.isEmpty(where) ? " AND (" + where
									+ ')' : ""), whereArgs);
		}
		
		getContext().getContentResolver().notifyChange(url, null);
		return count;
	}
	
	private int getUriType(Uri url) {
		return MATCHER.match(url);
	}

	private HashMap getDefaultProjection(int type) {
		HashMap projection = null;
		return projection;
	}
	
	private String getTableName(int type) {
		String sTableName = "";
		return sTableName;
	}
	
	private String getIdColumnName(int type) {
		return "";
	}
	
	private String getIdColumnNameToUpdate(int type) {
		return "";
	}
	
	private String getDefaultSortOrder(int type) {
		return "";
	}
	
	private String getCollectionType() {
		return("vnd.android.cursor.dir/vnd.xxxx.Provider.xxxx");
	}
	
	private String getSingleType() {
		return("vnd.android.cursor.item/vnd.xxxx.Provider.xxxx");
	}
	
	private String[] getRequiredColumns(int type) {
		return null;
	}
	
	private void populateDefaultValues(ContentValues values) {
		final Long now = Long.valueOf(System.currentTimeMillis());
	}
			
	private String getNullColumnHack() {
		//return ("title");
		return null;
	}
	
	private Uri getContentUri() {
		return(CONTENT_URI);
	}
}


코드를 그대로 올리기는 뭐해서 일부를 조금씩 바꾸서 올립니다.
신고

Trackbacks 0 / Comments 0

티스토리 툴바