Content Provider




Content Provides facilities to access database thru "content://" URI, database wrapper, (database) Cursor, and receives notification on Cursor records when there is a change. e.g. Android native content providers: Calendar Provider and the Contacts Provider.

Note: A provider is NOT NEEDED to use an SQLite database if the use is entirely within your own application.

Functionality Overview diagram shows ContentProvider WeatherProvider along with surrounding component modules.

"src\main\...\app\data"
# Sunshine\app\src\main\java\com\example\shreekant\sunshine\app\data

  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.shreekant.sunshine.app" >
    :
    <application
    :
        <provider
            android:authorities="com.example.shreekant.sunshine.app"

            android:name=".data.WeatherProvider" />



public class WeatherProvider extends ContentProvider {
    // Define Uri patterns that are supported along with corresponding representative ID:
    static UriMatcher buildUriMatcher() {
        // Includes just <location>, and (optional) date query param "<location>?date=<date>". Both are (list) CONTENT_TYPE.
        uriMatcher.addURI(authority, WeatherContract.PATH_WEATHER + "/*", WEATHER_WITH_LOCATION);

        // <location>/<date> for (single) CONTENT_ITEM_TYPE:
        uriMatcher.addURI(authority, WeatherContract.PATH_WEATHER + "/*/#", WEATHER_WITH_LOCATION_AND_DATE);
    }


    public boolean onCreate() {
        mOpenHelper = new WeatherDbHelper(getContext());
    }

    // Use the Uri Matcher to determine what kind of URI this is.
    public String getType(Uri uri) {
        final int match = sUriMatcher.match(uri);
        switch (match) {
            // Student: Uncomment and fill out these two cases
            case WEATHER_WITH_LOCATION_AND_DATE:
                return WeatherContract.WeatherEntry.CONTENT_ITEM_TYPE;
            case WEATHER_WITH_LOCATION:
                return WeatherContract.WeatherEntry.CONTENT_TYPE;
        :
        }
    }


    // Determine the kind of Uri request and query the database accordingly.
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                        String sortOrder) {
        Cursor retCursor;
        switch (sUriMatcher.match(uri)) {
            // "weather/*/#"
            case WEATHER_WITH_LOCATION_AND_DATE:
            {
                retCursor = getWeatherByLocationSettingAndDate(uri, projection, sortOrder);
                break;
            }
            // "weather/*": Note this includes "weather/location" and "weather/location?date=<date>"
            case WEATHER_WITH_LOCATION: {
                retCursor = getWeatherByLocationSetting(uri, projection, sortOrder);
                break;
            }
            // "weather"
            case WEATHER: {
                retCursor = mOpenHelper.getReadableDatabase().query(
                        WeatherContract.WeatherEntry.TABLE_NAME,
                        projection,
                        selection,
                        selectionArgs,
                        null,
                        null,
                        sortOrder);
                break;
            }
        }
        retCursor.setNotificationUri(getContext().getContentResolver(), uri);
    }


    public Uri insert(Uri uri, ContentValues values) {
        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        final int match = sUriMatcher.match(uri);
        switch (match) {
            case WEATHER: {
                normalizeDate(values);
                long _id = db.insert(WeatherContract.WeatherEntry.TABLE_NAME, null, values);
            }
        }
        getContext().getContentResolver().notifyChange(uri, null);
        db.close();
        :
    }

delete() & update() are implemented on similar lines, with calls to notifyChange() & db.close().

    public int delete(Uri uri, String selection, String[] selectionArgs) {}
    public int update(
            Uri uri, ContentValues values, String selection, String[] selectionArgs) {}



    public int bulkInsert(Uri uri, ContentValues[] values) {
        db.beginTransaction();
        try {
            for (ContentValues value : values) {
                long _id = db.insert(WeatherContract.WeatherEntry.TABLE_NAME, null, value);
                if (_id != -1) returnCount++;
            }
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return returnCount;
    }


    static{
        sWeatherByLocationSettingQueryBuilder = new SQLiteQueryBuilder();

        //This is an inner join which looks like
        //weather INNER JOIN location ON weather.location_id = location._id
        sWeatherByLocationSettingQueryBuilder.setTables(
                WeatherContract.WeatherEntry.TABLE_NAME + " INNER JOIN " +
                        WeatherContract.LocationEntry.TABLE_NAME +
                        " ON " + WeatherContract.WeatherEntry.TABLE_NAME +
                        "." + WeatherContract.WeatherEntry.COLUMN_LOC_KEY +
                        " = " + WeatherContract.LocationEntry.TABLE_NAME +
                        "." + WeatherContract.LocationEntry._ID);
    }


    private Cursor getWeatherByLocationSettingAndDate(
            Uri uri, String[] projection, String sortOrder) {
        String locationSetting = WeatherContract.WeatherEntry.getLocationSettingFromUri(uri);
        long date = WeatherContract.WeatherEntry.getDateFromUri(uri);

        return sWeatherByLocationSettingQueryBuilder.query(mOpenHelper.getReadableDatabase(),
                projection,
                sLocationSettingAndDaySelection,
                new String[]{locationSetting, Long.toString(date)},
                null,
                null,
                sortOrder
        );
    }

} // ContentProvider

public class WeatherDbHelper extends SQLiteOpenHelper {
    onCreate() // should do execSQL() to create tables
    onUpgrade() // should handle data migration as db schema (version) changes.

    // parent supports getReadableDatabase(), getWritableDatabase(), etc.
}






No comments:

Post a Comment