1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.fmradio; 18 19import android.content.ContentProvider; 20import android.content.ContentUris; 21import android.content.ContentValues; 22import android.content.Context; 23import android.content.UriMatcher; 24import android.database.Cursor; 25import android.database.sqlite.SQLiteDatabase; 26import android.database.sqlite.SQLiteOpenHelper; 27import android.database.sqlite.SQLiteQueryBuilder; 28import android.net.Uri; 29import android.text.TextUtils; 30import android.util.Log; 31 32/** 33 * This class provider interface to operator FM database table StationList 34 */ 35public class FmProvider extends ContentProvider { 36 private static final String TAG = "FmProvider"; 37 38 // database instance use to operate the database 39 private SQLiteDatabase mSqlDb = null; 40 // database helper use to get database instance 41 private DatabaseHelper mDbHelper = null; 42 // database name 43 private static final String DATABASE_NAME = "FmRadio.db"; 44 // database version 45 private static final int DATABASE_VERSION = 1; 46 // table name 47 private static final String TABLE_NAME = "StationList"; 48 49 // URI match code 50 private static final int STATION_FREQ = 1; 51 // URI match code 52 private static final int STATION_FREQ_ID = 2; 53 // use to match URI 54 private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); 55 56 // match URI with station frequency or station frequency id 57 static { 58 URI_MATCHER.addURI(FmStation.AUTHORITY, FmStation.STATION, STATION_FREQ); 59 URI_MATCHER.addURI(FmStation.AUTHORITY, FmStation.STATION + "/#", 60 STATION_FREQ_ID); 61 } 62 63 /** 64 * Helper to operate database 65 */ 66 private static class DatabaseHelper extends SQLiteOpenHelper { 67 68 /** 69 * initial database name and database version 70 * 71 * @param context application context 72 */ 73 DatabaseHelper(Context context) { 74 super(context, DATABASE_NAME, null, DATABASE_VERSION); 75 } 76 77 /** 78 * Create database table 79 * 80 * @param db The database 81 */ 82 @Override 83 public void onCreate(SQLiteDatabase db) { 84 // Create the table 85 Log.d(TAG, "onCreate, create the database"); 86 db.execSQL( 87 "CREATE TABLE " + TABLE_NAME + "(" 88 + FmStation.Station._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," 89 + FmStation.Station.FREQUENCY + " INTEGER UNIQUE," 90 + FmStation.Station.IS_FAVORITE + " INTEGER DEFAULT 0," 91 + FmStation.Station.STATION_NAME + " TEXT," 92 + FmStation.Station.PROGRAM_SERVICE + " TEXT," 93 + FmStation.Station.RADIO_TEXT + " TEXT" 94 + ");" 95 ); 96 } 97 98 /** 99 * Upgrade database 100 * 101 * @param db database 102 * @param oldVersion The old database version 103 * @param newVersion The new database version 104 */ 105 @Override 106 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 107 // TODO: reimplement this when dB version changes 108 Log.i(TAG, "onUpgrade, upgrading database from version " + oldVersion + " to " 109 + newVersion + ", which will destroy all old data"); 110 db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); 111 onCreate(db); 112 } 113 } 114 115 /** 116 * Delete database table rows with condition 117 * 118 * @param uri The uri to delete 119 * @param selection The where cause to apply, if null will delete all rows 120 * @param selectionArgs The select value 121 * 122 * @return The rows number has be deleted 123 */ 124 @Override 125 public int delete(Uri uri, String selection, String[] selectionArgs) { 126 int rows = 0; 127 mSqlDb = mDbHelper.getWritableDatabase(); 128 switch (URI_MATCHER.match(uri)) { 129 case STATION_FREQ: 130 rows = mSqlDb.delete(TABLE_NAME, selection, selectionArgs); 131 getContext().getContentResolver().notifyChange(uri, null); 132 break; 133 134 case STATION_FREQ_ID: 135 String stationID = uri.getPathSegments().get(1); 136 rows = mSqlDb.delete(TABLE_NAME, 137 FmStation.Station._ID 138 + "=" 139 + stationID 140 + (TextUtils.isEmpty(selection) ? "" : " AND (" + selection + ")"), 141 selectionArgs); 142 getContext().getContentResolver().notifyChange(uri, null); 143 break; 144 145 default: 146 Log.e(TAG, "delete, unkown URI to delete: " + uri); 147 break; 148 } 149 return rows; 150 } 151 152 /** 153 * Insert values to database with uri 154 * 155 * @param uri The insert uri 156 * @param values The insert values 157 * 158 * @return The uri after inserted 159 */ 160 @Override 161 public Uri insert(Uri uri, ContentValues values) { 162 Uri rowUri = null; 163 mSqlDb = mDbHelper.getWritableDatabase(); 164 ContentValues v = new ContentValues(values); 165 166 long rowId = mSqlDb.insert(TABLE_NAME, null, v); 167 if (rowId <= 0) { 168 Log.e(TAG, "insert, failed to insert row into " + uri); 169 } 170 rowUri = ContentUris.appendId(FmStation.Station.CONTENT_URI.buildUpon(), rowId) 171 .build(); 172 getContext().getContentResolver().notifyChange(rowUri, null); 173 return rowUri; 174 } 175 176 /** 177 * Create database helper 178 * 179 * @return true if create database helper success 180 */ 181 @Override 182 public boolean onCreate() { 183 mDbHelper = new DatabaseHelper(getContext()); 184 return (null == mDbHelper) ? false : true; 185 } 186 187 /** 188 * Query the database with current settings and add information 189 * 190 * @param uri The database uri 191 * @param projection The columns need to query 192 * @param selection The where clause 193 * @param selectionArgs The where value 194 * @param sortOrder The column to sort 195 * 196 * @return The query result cursor 197 */ 198 @Override 199 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 200 String sortOrder) { 201 SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 202 SQLiteDatabase db = mDbHelper.getReadableDatabase(); 203 qb.setTables(TABLE_NAME); 204 205 int match = URI_MATCHER.match(uri); 206 207 if (STATION_FREQ_ID == match) { 208 qb.appendWhere("_id = " + uri.getPathSegments().get(1)); 209 } 210 211 Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); 212 if (null != c) { 213 c.setNotificationUri(getContext().getContentResolver(), uri); 214 } 215 return c; 216 } 217 218 /** 219 * Update the database content use content values with current settings and 220 * add information 221 * 222 * @param uri The database uri 223 * @param values The values need to update 224 * @param selection The where clause 225 * @param selectionArgs The where value 226 * 227 * @return The row numbers have changed 228 */ 229 @Override 230 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 231 int rows = 0; 232 mSqlDb = mDbHelper.getWritableDatabase(); 233 switch (URI_MATCHER.match(uri)) { 234 case STATION_FREQ: 235 rows = mSqlDb.update(TABLE_NAME, values, selection, selectionArgs); 236 getContext().getContentResolver().notifyChange(uri, null); 237 break; 238 case STATION_FREQ_ID: 239 String stationID = uri.getPathSegments().get(1); 240 rows = mSqlDb.update(TABLE_NAME, 241 values, 242 FmStation.Station._ID 243 + "=" 244 + stationID 245 + (TextUtils.isEmpty(selection) ? "" : " AND (" + selection + ")"), 246 selectionArgs); 247 getContext().getContentResolver().notifyChange(uri, null); 248 break; 249 default: 250 Log.e(TAG, "update, unkown URI to update: " + uri); 251 break; 252 } 253 return rows; 254 } 255 256 /** 257 * Get uri type 258 * 259 * @param uri The the uri 260 * 261 * @return The type 262 */ 263 @Override 264 public String getType(Uri uri) { 265 return null; 266 } 267} 268