├── README.md ├── data ├── WeatherContract.java ├── WeatherDbHelper.java └── WeatherProvider.java └── test ├── FullTestSuite.java ├── TestDb.java └── TestProvider.java /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Archival Note 3 | This repository is deprecated; therefore, we are going to archive it. However, learners will be able to fork it to their personal Github account but cannot submit PRs to this repository. If you have any issues or suggestions to make, feel free to: 4 | - Utilize the https://knowledge.udacity.com/ forum to seek help on content-specific issues. 5 | - Submit a support ticket along with the link to your forked repository if (learners are) blocked for other reasons. Here are the links for the [retail consumers](https://udacity.zendesk.com/hc/en-us/requests/new) and [enterprise learners](https://udacityenterprise.zendesk.com/hc/en-us/requests/new?ticket_form_id=360000279131). -------------------------------------------------------------------------------- /data/WeatherContract.java: -------------------------------------------------------------------------------- 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 | package com.example.android.sunshine.app.data; 17 | 18 | import android.content.ContentUris; 19 | import android.net.Uri; 20 | import android.provider.BaseColumns; 21 | import java.text.ParseException; 22 | import java.text.SimpleDateFormat; 23 | import java.util.Date; 24 | 25 | /** 26 | * Defines table and column names for the weather database. 27 | */ 28 | public class WeatherContract { 29 | 30 | // The "Content authority" is a name for the entire content provider, similar to the 31 | // relationship between a domain name and its website. A convenient string to use for the 32 | // content authority is the package name for the app, which is guaranteed to be unique on the 33 | // device. 34 | /* TODO Uncomment for 35 | 4b - Adding ContentProvider to our Contract 36 | https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/m-1637521471 37 | public static final String CONTENT_AUTHORITY = "com.example.android.sunshine.app"; 38 | 39 | // Use CONTENT_AUTHORITY to create the base of all URI's which apps will use to contact 40 | // the content provider. 41 | 42 | public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY); 43 | 44 | // Possible paths (appended to base content URI for possible URI's) 45 | // For instance, content://com.example.android.sunshine.app/weather/ is a valid path for 46 | // looking at weather data. content://com.example.android.sunshine.app/givemeroot/ will fail, 47 | // as the ContentProvider hasn't been given any information on what to do with "givemeroot". 48 | // At least, let's hope not. Don't be that dev, reader. Don't be that dev. 49 | 50 | public static final String PATH_WEATHER = "weather"; 51 | public static final String PATH_LOCATION = "location"; 52 | */ 53 | 54 | /* TODO Uncomment for 55 | 4b - Finishing the FetchWeatherTask 56 | https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/m-1675098569 57 | // Format used for storing dates in the database. ALso used for converting those strings 58 | // back into date objects for comparison/processing. 59 | 60 | public static final String DATE_FORMAT = "yyyyMMdd"; 61 | */ 62 | 63 | /** 64 | * Converts Date class to a string representation, used for easy comparison and database lookup. 65 | * @param date The input date 66 | * @return a DB-friendly representation of the date, using the format defined in DATE_FORMAT. 67 | */ 68 | /* TODO Uncomment for 69 | 4b - Finishing the FetchWeatherTask 70 | https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/m-1675098569 71 | public static String getDbDateString(Date date){ 72 | // Because the API returns a unix timestamp (measured in seconds), 73 | // it must be converted to milliseconds in order to be converted to valid date. 74 | SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); 75 | return sdf.format(date); 76 | } 77 | */ 78 | 79 | /** 80 | * Converts a dateText to a long Unix time representation 81 | * @param dateText the input date string 82 | * @return the Date object 83 | */ 84 | /* TODO Uncomment for 85 | 4b - Finishing the FetchWeatherTask 86 | https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/m-1675098569 87 | public static Date getDateFromDb(String dateText) { 88 | SimpleDateFormat dbDateFormat = new SimpleDateFormat(DATE_FORMAT); 89 | try { 90 | return dbDateFormat.parse(dateText); 91 | } catch ( ParseException e ) { 92 | e.printStackTrace(); 93 | return null; 94 | } 95 | } 96 | */ 97 | 98 | public static final class LocationEntry implements BaseColumns { 99 | /** 100 | * TODO YOUR CODE BELOW HERE FOR QUIZ 101 | * QUIZ - 4a - Columns 102 | * https://www.udacity.com/course/viewer#!/c-ud853/l-1639338560/e-1633698595/m-1633698597 103 | **/ 104 | 105 | /* TODO Uncomment for 106 | 4b - Adding ContentProvider to our Contract 107 | https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/m-1637521471 108 | 109 | public static final Uri CONTENT_URI = 110 | BASE_CONTENT_URI.buildUpon().appendPath(PATH_LOCATION).build(); 111 | 112 | public static final String CONTENT_TYPE = 113 | "vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + PATH_LOCATION; 114 | public static final String CONTENT_ITEM_TYPE = 115 | "vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + PATH_LOCATION; 116 | */ 117 | 118 | /** 119 | * TODO YOUR CODE BELOW HERE FOR QUIZ 120 | * QUIZ - 4b - Adding LocationEntry with ID UriBuilder 121 | * https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/e-1604969848/m-1604969849 122 | **/ 123 | 124 | } 125 | 126 | /* 127 | /* Inner class that defines the table contents of the weather table */ 128 | public static final class WeatherEntry implements BaseColumns { 129 | 130 | public static final String TABLE_NAME = "weather"; 131 | 132 | // Column with the foreign key into the location table. 133 | public static final String COLUMN_LOC_KEY = "location_id"; 134 | // Date, stored as Text with format yyyy-MM-dd 135 | public static final String COLUMN_DATETEXT = "date"; 136 | // Weather id as returned by API, to identify the icon to be used 137 | public static final String COLUMN_WEATHER_ID = "weather_id"; 138 | 139 | // Short description and long description of the weather, as provided by API. 140 | // e.g "clear" vs "sky is clear". 141 | public static final String COLUMN_SHORT_DESC = "short_desc"; 142 | 143 | // Min and max temperatures for the day (stored as floats) 144 | public static final String COLUMN_MIN_TEMP = "min"; 145 | public static final String COLUMN_MAX_TEMP = "max"; 146 | 147 | // Humidity is stored as a float representing percentage 148 | public static final String COLUMN_HUMIDITY = "humidity"; 149 | 150 | // Humidity is stored as a float representing percentage 151 | public static final String COLUMN_PRESSURE = "pressure"; 152 | 153 | // Windspeed is stored as a float representing windspeed mph 154 | public static final String COLUMN_WIND_SPEED = "wind"; 155 | 156 | // Degrees are meteorological degrees (e.g, 0 is north, 180 is south). Stored as floats. 157 | public static final String COLUMN_DEGREES = "degrees"; 158 | 159 | /* TODO Uncomment for 160 | 4b - Adding ContentProvider to our Contract 161 | https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/m-1637521471 162 | public static final Uri CONTENT_URI = 163 | BASE_CONTENT_URI.buildUpon().appendPath(PATH_WEATHER).build(); 164 | 165 | public static final String CONTENT_TYPE = 166 | "vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + PATH_WEATHER; 167 | public static final String CONTENT_ITEM_TYPE = 168 | "vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + PATH_WEATHER; 169 | 170 | public static Uri buildWeatherUri(long id) { 171 | return ContentUris.withAppendedId(CONTENT_URI, id); 172 | } 173 | 174 | public static Uri buildWeatherLocation(String locationSetting) { 175 | return CONTENT_URI.buildUpon().appendPath(locationSetting).build(); 176 | } 177 | 178 | public static Uri buildWeatherLocationWithStartDate( 179 | String locationSetting, String startDate) { 180 | return CONTENT_URI.buildUpon().appendPath(locationSetting) 181 | .appendQueryParameter(COLUMN_DATETEXT, startDate).build(); 182 | } 183 | 184 | public static Uri buildWeatherLocationWithDate(String locationSetting, String date) { 185 | return CONTENT_URI.buildUpon().appendPath(locationSetting).appendPath(date).build(); 186 | } 187 | 188 | public static String getLocationSettingFromUri(Uri uri) { 189 | return uri.getPathSegments().get(1); 190 | } 191 | 192 | public static String getDateFromUri(Uri uri) { 193 | return uri.getPathSegments().get(2); 194 | } 195 | 196 | public static String getStartDateFromUri(Uri uri) { 197 | return uri.getQueryParameter(COLUMN_DATETEXT); 198 | }*/ 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /data/WeatherDbHelper.java: -------------------------------------------------------------------------------- 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 | package com.example.android.sunshine.app.data; 17 | 18 | import android.content.Context; 19 | import android.database.sqlite.SQLiteDatabase; 20 | import android.database.sqlite.SQLiteOpenHelper; 21 | import com.example.android.sunshine.app.data.WeatherContract.LocationEntry; 22 | import com.example.android.sunshine.app.data.WeatherContract.WeatherEntry; 23 | 24 | /** 25 | * Manages a local database for weather data. 26 | */ 27 | public class WeatherDbHelper extends SQLiteOpenHelper { 28 | 29 | // If you change the database schema, you must increment the database version. 30 | private static final int DATABASE_VERSION = 1; 31 | 32 | public static final String DATABASE_NAME = "weather.db"; 33 | 34 | public WeatherDbHelper(Context context) { 35 | super(context, DATABASE_NAME, null, DATABASE_VERSION); 36 | } 37 | 38 | @Override 39 | public void onCreate(SQLiteDatabase sqLiteDatabase) { 40 | /** 41 | * TODO YOUR CODE BELOW HERE FOR QUIZ 42 | * QUIZ - 4a - LocationEntry 43 | * https://www.udacity.com/course/viewer#!/c-ud853/l-1639338560/e-1633698599/m-1633698600 44 | **/ 45 | 46 | final String SQL_CREATE_LOCATION_TABLE = ""; 47 | 48 | /* TODO Uncomment for 49 | 4a - Create a Database for SQLiteOpenHelper 50 | https://www.udacity.com/course/viewer#!/c-ud853/l-1639338560/m-1633698598 51 | final String SQL_CREATE_WEATHER_TABLE = "CREATE TABLE " + WeatherEntry.TABLE_NAME + " (" + 52 | // Why AutoIncrement here, and not above? 53 | // Unique keys will be auto-generated in either case. But for weather 54 | // forecasting, it's reasonable to assume the user will want information 55 | // for a certain date and all dates *following*, so the forecast data 56 | // should be sorted accordingly. 57 | WeatherEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 58 | 59 | // the ID of the location entry associated with this weather data 60 | WeatherEntry.COLUMN_LOC_KEY + " INTEGER NOT NULL, " + 61 | WeatherEntry.COLUMN_DATETEXT + " TEXT NOT NULL, " + 62 | WeatherEntry.COLUMN_SHORT_DESC + " TEXT NOT NULL, " + 63 | WeatherEntry.COLUMN_WEATHER_ID + " INTEGER NOT NULL," + 64 | 65 | WeatherEntry.COLUMN_MIN_TEMP + " REAL NOT NULL, " + 66 | WeatherEntry.COLUMN_MAX_TEMP + " REAL NOT NULL, " + 67 | 68 | WeatherEntry.COLUMN_HUMIDITY + " REAL NOT NULL, " + 69 | WeatherEntry.COLUMN_PRESSURE + " REAL NOT NULL, " + 70 | WeatherEntry.COLUMN_WIND_SPEED + " REAL NOT NULL, " + 71 | WeatherEntry.COLUMN_DEGREES + " REAL NOT NULL, " + 72 | 73 | // Set up the location column as a foreign key to location table. 74 | " FOREIGN KEY (" + WeatherEntry.COLUMN_LOC_KEY + ") REFERENCES " + 75 | LocationEntry.TABLE_NAME + " (" + LocationEntry._ID + "), " + 76 | 77 | // To assure the application have just one weather entry per day 78 | // per location, it's created a UNIQUE constraint with REPLACE strategy 79 | " UNIQUE (" + WeatherEntry.COLUMN_DATETEXT + ", " + 80 | WeatherEntry.COLUMN_LOC_KEY + ") ON CONFLICT REPLACE);"; 81 | 82 | sqLiteDatabase.execSQL(SQL_CREATE_LOCATION_TABLE); 83 | sqLiteDatabase.execSQL(SQL_CREATE_WEATHER_TABLE); 84 | */ 85 | } 86 | 87 | @Override 88 | public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) { 89 | /* TODO Uncomment for 90 | 4a - SQLiteOpenHelper onUpgrade() method 91 | https://www.udacity.com/course/viewer#!/c-ud853/l-1639338560/m-1633698602 92 | // This database is only a cache for online data, so its upgrade policy is 93 | // to simply to discard the data and start over 94 | // Note that this only fires if you change the version number for your database. 95 | // It does NOT depend on the version number for your application. 96 | // If you want to update the schema without wiping data, commenting out the next 2 lines 97 | // should be your top priority before modifying this method. 98 | sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + LocationEntry.TABLE_NAME); 99 | sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + WeatherEntry.TABLE_NAME); 100 | onCreate(sqLiteDatabase); 101 | */ 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /data/WeatherProvider.java: -------------------------------------------------------------------------------- 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 | // package com.example.android.sunshine.app.data; 17 | 18 | // import android.content.ContentProvider; 19 | // import android.content.ContentUris; 20 | // import android.content.ContentValues; 21 | // import android.content.UriMatcher; 22 | // import android.database.Cursor; 23 | // import android.database.sqlite.SQLiteDatabase; 24 | // import android.database.sqlite.SQLiteQueryBuilder; 25 | // import android.net.Uri; 26 | 27 | // public class WeatherProvider extends ContentProvider { 28 | 29 | // // The URI Matcher used by this content provider. 30 | // private static final UriMatcher sUriMatcher = buildUriMatcher(); 31 | // private WeatherDbHelper mOpenHelper; 32 | 33 | // private static final int WEATHER = 100; 34 | // private static final int WEATHER_WITH_LOCATION = 101; 35 | // private static final int WEATHER_WITH_LOCATION_AND_DATE = 102; 36 | // private static final int LOCATION = 300; 37 | // private static final int LOCATION_ID = 301; 38 | 39 | // private static UriMatcher buildUriMatcher() { 40 | // // I know what you're thinking. Why create a UriMatcher when you can use regular 41 | // // expressions instead? Because you're not crazy, that's why. 42 | 43 | // // All paths added to the UriMatcher have a corresponding code to return when a match is 44 | // // found. The code passed into the constructor represents the code to return for the root 45 | // // URI. It's common to use NO_MATCH as the code for this case. 46 | // final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); 47 | // final String authority = WeatherContract.CONTENT_AUTHORITY; 48 | 49 | // // For each type of URI you want to add, create a corresponding code. 50 | // matcher.addURI(authority, WeatherContract.PATH_WEATHER, WEATHER); 51 | // matcher.addURI(authority, WeatherContract.PATH_WEATHER + "/*", WEATHER_WITH_LOCATION); 52 | // matcher.addURI(authority, WeatherContract.PATH_WEATHER + "/*/*", WEATHER_WITH_LOCATION_AND_DATE); 53 | 54 | // matcher.addURI(authority, WeatherContract.PATH_LOCATION, LOCATION); 55 | // matcher.addURI(authority, WeatherContract.PATH_LOCATION + "/#", LOCATION_ID); 56 | 57 | // return matcher; 58 | // } 59 | 60 | // private static final SQLiteQueryBuilder sWeatherByLocationSettingQueryBuilder; 61 | 62 | // static{ 63 | // sWeatherByLocationSettingQueryBuilder = new SQLiteQueryBuilder(); 64 | // sWeatherByLocationSettingQueryBuilder.setTables( 65 | // WeatherContract.WeatherEntry.TABLE_NAME + " INNER JOIN " + 66 | // WeatherContract.LocationEntry.TABLE_NAME + 67 | // " ON " + WeatherContract.WeatherEntry.TABLE_NAME + 68 | // "." + WeatherContract.WeatherEntry.COLUMN_LOC_KEY + 69 | // " = " + WeatherContract.LocationEntry.TABLE_NAME + 70 | // "." + WeatherContract.LocationEntry._ID); 71 | // } 72 | 73 | // private static final String sLocationSettingSelection = 74 | // WeatherContract.LocationEntry.TABLE_NAME+ 75 | // "." + WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING + " = ? "; 76 | // private static final String sLocationSettingWithStartDateSelection = 77 | // WeatherContract.LocationEntry.TABLE_NAME+ 78 | // "." + WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING + " = ? AND " + 79 | // WeatherContract.WeatherEntry.COLUMN_DATETEXT + " >= ? "; 80 | 81 | // private static final String sLocationSettingAndDaySelection = 82 | // WeatherContract.LocationEntry.TABLE_NAME + 83 | // "." + WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING + " = ? AND " + 84 | // WeatherContract.WeatherEntry.COLUMN_DATETEXT + " = ? "; 85 | 86 | // private Cursor getWeatherByLocationSetting(Uri uri, String[] projection, String sortOrder) { 87 | // String locationSetting = WeatherContract.WeatherEntry.getLocationSettingFromUri(uri); 88 | // String startDate = WeatherContract.WeatherEntry.getStartDateFromUri(uri); 89 | 90 | // String[] selectionArgs; 91 | // String selection; 92 | 93 | // if (startDate == null) { 94 | // selection = sLocationSettingSelection; 95 | // selectionArgs = new String[]{locationSetting}; 96 | // } else { 97 | // selectionArgs = new String[]{locationSetting, startDate}; 98 | // selection = sLocationSettingWithStartDateSelection; 99 | // } 100 | 101 | // return sWeatherByLocationSettingQueryBuilder.query(mOpenHelper.getReadableDatabase(), 102 | // projection, 103 | // selection, 104 | // selectionArgs, 105 | // null, 106 | // null, 107 | // sortOrder 108 | // ); 109 | // } 110 | 111 | // private Cursor getWeatherByLocationSettingAndDate( 112 | // Uri uri, String[] projection, String sortOrder) { 113 | // String locationSetting = WeatherContract.WeatherEntry.getLocationSettingFromUri(uri); 114 | // String date = WeatherContract.WeatherEntry.getDateFromUri(uri); 115 | 116 | // return sWeatherByLocationSettingQueryBuilder.query(mOpenHelper.getReadableDatabase(), 117 | // projection, 118 | // sLocationSettingAndDaySelection, 119 | // new String[]{locationSetting, date}, 120 | // null, 121 | // null, 122 | // sortOrder 123 | // ); 124 | // } 125 | 126 | // @Override 127 | // public boolean onCreate() { 128 | // mOpenHelper = new WeatherDbHelper(getContext()); 129 | // return true; 130 | // } 131 | 132 | // @Override 133 | // public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 134 | // String sortOrder) { 135 | // // Here's the switch statement that, given a URI, will determine what kind of request it is, 136 | // // and query the database accordingly. 137 | // Cursor retCursor; 138 | // switch (sUriMatcher.match(uri)) { 139 | // // "weather/*/*" 140 | // case WEATHER_WITH_LOCATION_AND_DATE: 141 | // { 142 | // retCursor = getWeatherByLocationSettingAndDate(uri, projection, sortOrder); 143 | // break; 144 | // } 145 | // // "weather/*" 146 | // case WEATHER_WITH_LOCATION: { 147 | // retCursor = getWeatherByLocationSetting(uri, projection, sortOrder); 148 | // break; 149 | // } 150 | // // "weather" 151 | // case WEATHER: { 152 | // retCursor = mOpenHelper.getReadableDatabase().query( 153 | // WeatherContract.WeatherEntry.TABLE_NAME, 154 | // projection, 155 | // selection, 156 | // selectionArgs, 157 | // null, 158 | // null, 159 | // sortOrder 160 | // ); 161 | // break; 162 | // } 163 | 164 | // /** 165 | // * TODO YOUR CODE BELOW HERE FOR QUIZ 166 | // * QUIZ - 4b - Implement Location_ID queries 167 | // * https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/e-1675098551/m-1675098552 168 | // **/ 169 | 170 | // default: 171 | // throw new UnsupportedOperationException("Unknown uri: " + uri); 172 | // } 173 | // retCursor.setNotificationUri(getContext().getContentResolver(), uri); 174 | // return retCursor; 175 | // } 176 | 177 | // @Override 178 | // public String getType(Uri uri) { 179 | 180 | // // Use the Uri Matcher to determine what kind of URI this is. 181 | // final int match = sUriMatcher.match(uri); 182 | 183 | // switch (match) { 184 | // case WEATHER_WITH_LOCATION_AND_DATE: 185 | // return WeatherContract.WeatherEntry.CONTENT_ITEM_TYPE; 186 | // case WEATHER_WITH_LOCATION: 187 | // return WeatherContract.WeatherEntry.CONTENT_TYPE; 188 | // case WEATHER: 189 | // return WeatherContract.WeatherEntry.CONTENT_TYPE; 190 | 191 | // /** 192 | // * TODO YOUR CODE BELOW HERE FOR QUIZ 193 | // * QUIZ - 4b - Coding the Content Provider : getType 194 | // * https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/e-1675098546/m-1675098547 195 | // **/ 196 | 197 | // default: 198 | // throw new UnsupportedOperationException("Unknown uri: " + uri); 199 | // } 200 | // } 201 | 202 | // @Override 203 | // public Uri insert(Uri uri, ContentValues values) { 204 | // final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 205 | // final int match = sUriMatcher.match(uri); 206 | // Uri returnUri; 207 | 208 | // switch (match) { 209 | // case WEATHER: { 210 | // long _id = db.insert(WeatherContract.WeatherEntry.TABLE_NAME, null, values); 211 | // if ( _id > 0 ) 212 | // returnUri = WeatherContract.WeatherEntry.buildWeatherUri(_id); 213 | // else 214 | // throw new android.database.SQLException("Failed to insert row into " + uri); 215 | // break; 216 | // } 217 | // case LOCATION: { 218 | // long _id = db.insert(WeatherContract.LocationEntry.TABLE_NAME, null, values); 219 | // if ( _id > 0 ) 220 | // returnUri = WeatherContract.LocationEntry.buildLocationUri(_id); 221 | // else 222 | // throw new android.database.SQLException("Failed to insert row into " + uri); 223 | // break; 224 | // } 225 | // default: 226 | // throw new UnsupportedOperationException("Unknown uri: " + uri); 227 | // } 228 | // getContext().getContentResolver().notifyChange(uri, null); 229 | // return returnUri; 230 | // } 231 | 232 | // @Override 233 | // public int delete(Uri uri, String selection, String[] selectionArgs) { 234 | // final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 235 | // final int match = sUriMatcher.match(uri); 236 | // int rowsDeleted; 237 | // switch (match) { 238 | // case WEATHER: 239 | // rowsDeleted = db.delete( 240 | // WeatherContract.WeatherEntry.TABLE_NAME, selection, selectionArgs); 241 | // break; 242 | // case LOCATION: 243 | // rowsDeleted = db.delete( 244 | // WeatherContract.LocationEntry.TABLE_NAME, selection, selectionArgs); 245 | // break; 246 | // default: 247 | // throw new UnsupportedOperationException("Unknown uri: " + uri); 248 | // } 249 | // // Because a null deletes all rows 250 | // if (selection == null || rowsDeleted != 0) { 251 | // getContext().getContentResolver().notifyChange(uri, null); 252 | // } 253 | // return rowsDeleted; 254 | // } 255 | 256 | // @Override 257 | // public int update( 258 | // Uri uri, ContentValues values, String selection, String[] selectionArgs) { 259 | // /** 260 | // * TODO YOUR CODE BELOW HERE FOR QUIZ 261 | // * QUIZ - 4b - Updating and Deleting 262 | // * https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/e-1675098563/m-1675098564 263 | // **/ 264 | // return 0; 265 | // } 266 | 267 | // @Override 268 | // public int bulkInsert(Uri uri, ContentValues[] values) { 269 | // final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 270 | // final int match = sUriMatcher.match(uri); 271 | // switch (match) { 272 | // case WEATHER: 273 | // db.beginTransaction(); 274 | // int returnCount = 0; 275 | // try { 276 | // for (ContentValues value : values) { 277 | // long _id = db.insert(WeatherContract.WeatherEntry.TABLE_NAME, null, value); 278 | // if (_id != -1) { 279 | // returnCount++; 280 | // } 281 | // } 282 | // db.setTransactionSuccessful(); 283 | // } finally { 284 | // db.endTransaction(); 285 | // } 286 | // getContext().getContentResolver().notifyChange(uri, null); 287 | // return returnCount; 288 | // default: 289 | // return super.bulkInsert(uri, values); 290 | // } 291 | // } 292 | // } 293 | -------------------------------------------------------------------------------- /test/FullTestSuite.java: -------------------------------------------------------------------------------- 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 | package com.example.android.sunshine.app.test; 17 | 18 | import android.test.suitebuilder.TestSuiteBuilder; 19 | 20 | import junit.framework.Test; 21 | import junit.framework.TestSuite; 22 | 23 | public class FullTestSuite extends TestSuite { 24 | public static Test suite() { 25 | return new TestSuiteBuilder(FullTestSuite.class) 26 | .includeAllPackagesUnderHere().build(); 27 | } 28 | 29 | public FullTestSuite() { 30 | super(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/TestDb.java: -------------------------------------------------------------------------------- 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 | package com.example.android.sunshine.app.test; 17 | 18 | import android.database.sqlite.SQLiteDatabase; 19 | import android.test.AndroidTestCase; 20 | import com.example.android.sunshine.app.data.WeatherContract.LocationEntry; 21 | import com.example.android.sunshine.app.data.WeatherContract.WeatherEntry; 22 | import com.example.android.sunshine.app.data.WeatherDbHelper; 23 | 24 | public class TestDb extends AndroidTestCase { 25 | 26 | public static final String LOG_TAG = TestDb.class.getSimpleName(); 27 | 28 | public void testCreateDb() throws Throwable { 29 | mContext.deleteDatabase(WeatherDbHelper.DATABASE_NAME); 30 | SQLiteDatabase db = new WeatherDbHelper( 31 | this.mContext).getWritableDatabase(); 32 | assertEquals(true, db.isOpen()); 33 | db.close(); 34 | } 35 | 36 | /* TODO Uncomment for 37 | 4a - JUnit testing 38 | https://www.udacity.com/course/viewer#!/c-ud853/l-1639338560/m-1633698603 39 | public void testInsertReadDb() { 40 | 41 | // Test data we're going to insert into the DB to see if it works. 42 | String testLocationSetting = "99705"; 43 | String testCityName = "North Pole"; 44 | double testLatitude = 64.7488; 45 | double testLongitude = -147.353; 46 | 47 | // If there's an error in those massive SQL table creation Strings, 48 | // errors will be thrown here when you try to get a writable database. 49 | WeatherDbHelper dbHelper = new WeatherDbHelper(mContext); 50 | SQLiteDatabase db = dbHelper.getWritableDatabase(); 51 | 52 | // Create a new map of values, where column names are the keys 53 | ContentValues values = new ContentValues(); 54 | values.put(LocationEntry.COLUMN_LOCATION_SETTING, testLocationSetting); 55 | values.put(LocationEntry.COLUMN_CITY_NAME, testCityName); 56 | values.put(LocationEntry.COLUMN_COORD_LAT, testLatitude); 57 | values.put(LocationEntry.COLUMN_COORD_LONG, testLongitude); 58 | 59 | long locationRowId; 60 | locationRowId = db.insert(LocationEntry.TABLE_NAME, null, values); 61 | 62 | // Verify we got a row back. 63 | assertTrue(locationRowId != -1); 64 | Log.d(LOG_TAG, "New row id: " + locationRowId); 65 | 66 | // Data's inserted. IN THEORY. Now pull some out to stare at it and verify it made 67 | // the round trip. 68 | 69 | // Specify which columns you want. 70 | String[] columns = { 71 | LocationEntry._ID, 72 | LocationEntry.COLUMN_LOCATION_SETTING, 73 | LocationEntry.COLUMN_CITY_NAME, 74 | LocationEntry.COLUMN_COORD_LAT, 75 | LocationEntry.COLUMN_COORD_LONG 76 | }; 77 | 78 | // A cursor is your primary interface to the query results. 79 | Cursor cursor = db.query( 80 | LocationEntry.TABLE_NAME, // Table to Query 81 | columns, 82 | null, // Columns for the "where" clause 83 | null, // Values for the "where" clause 84 | null, // columns to group by 85 | null, // columns to filter by row groups 86 | null // sort order 87 | ); 88 | 89 | // If possible, move to the first row of the query results. 90 | if (cursor.moveToFirst()) { 91 | // Get the value in each column by finding the appropriate column index. 92 | int locationIndex = cursor.getColumnIndex(LocationEntry.COLUMN_LOCATION_SETTING); 93 | String location = cursor.getString(locationIndex); 94 | 95 | int nameIndex = cursor.getColumnIndex((LocationEntry.COLUMN_CITY_NAME)); 96 | String name = cursor.getString(nameIndex); 97 | 98 | int latIndex = cursor.getColumnIndex((LocationEntry.COLUMN_COORD_LAT)); 99 | double latitude = cursor.getDouble(latIndex); 100 | 101 | int longIndex = cursor.getColumnIndex((LocationEntry.COLUMN_COORD_LONG)); 102 | double longitude = cursor.getDouble(longIndex); 103 | 104 | // Hooray, data was returned! Assert that it's the right data, and that the database 105 | // creation code is working as intended. 106 | // Then take a break. We both know that wasn't easy. 107 | assertEquals(testCityName, name); 108 | assertEquals(testLocationSetting, location); 109 | assertEquals(testLatitude, latitude); 110 | assertEquals(testLongitude, longitude); 111 | 112 | // Fantastic. Now that we have a location, add some weather! 113 | } else { 114 | // That's weird, it works on MY machine... 115 | fail("No values returned :("); 116 | } 117 | 118 | // Fantastic. Now that we have a location, add some weather! 119 | ContentValues weatherValues = new ContentValues(); 120 | weatherValues.put(WeatherEntry.COLUMN_LOC_KEY, locationRowId); 121 | weatherValues.put(WeatherEntry.COLUMN_DATETEXT, "20141205"); 122 | weatherValues.put(WeatherEntry.COLUMN_DEGREES, 1.1); 123 | weatherValues.put(WeatherEntry.COLUMN_HUMIDITY, 1.2); 124 | weatherValues.put(WeatherEntry.COLUMN_PRESSURE, 1.3); 125 | weatherValues.put(WeatherEntry.COLUMN_MAX_TEMP, 75); 126 | weatherValues.put(WeatherEntry.COLUMN_MIN_TEMP, 65); 127 | weatherValues.put(WeatherEntry.COLUMN_SHORT_DESC, "Asteroids"); 128 | weatherValues.put(WeatherEntry.COLUMN_WIND_SPEED, 5.5); 129 | weatherValues.put(WeatherEntry.COLUMN_WEATHER_ID, 321); 130 | */ 131 | 132 | /** 133 | * TODO YOUR CODE BELOW HERE FOR QUIZ 134 | * QUIZ - 4a - InsertReadDbTest 135 | * https://www.udacity.com/course/viewer#!/c-ud853/l-1639338560/e-1633698604/m-1633698605 136 | **/ 137 | 138 | /* TODO Uncomment for 139 | 4a - JUnit testing 140 | https://www.udacity.com/course/viewer#!/c-ud853/l-1639338560/m-1633698603 141 | dbHelper.close(); 142 | } 143 | */ 144 | 145 | /* TODO Uncomment for 146 | 4a - Simplify Tests 147 | https://www.udacity.com/course/viewer#!/c-ud853/l-1639338560/e-1633698607/m-1615128666 148 | static ContentValues createWeatherValues(long locationRowId) { 149 | ContentValues weatherValues = new ContentValues(); 150 | weatherValues.put(WeatherEntry.COLUMN_LOC_KEY, locationRowId); 151 | weatherValues.put(WeatherEntry.COLUMN_DATETEXT, "20141205"); 152 | weatherValues.put(WeatherEntry.COLUMN_DEGREES, 1.1); 153 | weatherValues.put(WeatherEntry.COLUMN_HUMIDITY, 1.2); 154 | weatherValues.put(WeatherEntry.COLUMN_PRESSURE, 1.3); 155 | weatherValues.put(WeatherEntry.COLUMN_MAX_TEMP, 75); 156 | weatherValues.put(WeatherEntry.COLUMN_MIN_TEMP, 65); 157 | weatherValues.put(WeatherEntry.COLUMN_SHORT_DESC, "Asteroids"); 158 | weatherValues.put(WeatherEntry.COLUMN_WIND_SPEED, 5.5); 159 | weatherValues.put(WeatherEntry.COLUMN_WEATHER_ID, 321); 160 | 161 | return weatherValues; 162 | } 163 | 164 | static ContentValues createNorthPoleLocationValues() { 165 | // Create a new map of values, where column names are the keys 166 | ContentValues testValues = new ContentValues(); 167 | testValues.put(LocationEntry.COLUMN_LOCATION_SETTING, "99705"); 168 | testValues.put(LocationEntry.COLUMN_CITY_NAME, "North Pole"); 169 | testValues.put(LocationEntry.COLUMN_COORD_LAT, 64.7488); 170 | testValues.put(LocationEntry.COLUMN_COORD_LONG, -147.353); 171 | 172 | return testValues; 173 | } 174 | 175 | static void validateCursor(Cursor valueCursor, ContentValues expectedValues) { 176 | 177 | assertTrue(valueCursor.moveToFirst()); 178 | 179 | Set> valueSet = expectedValues.valueSet(); 180 | for (Map.Entry entry : valueSet) { 181 | String columnName = entry.getKey(); 182 | int idx = valueCursor.getColumnIndex(columnName); 183 | assertFalse(idx == -1); 184 | String expectedValue = entry.getValue().toString(); 185 | assertEquals(expectedValue, valueCursor.getString(idx)); 186 | } 187 | valueCursor.close(); 188 | } 189 | 190 | static final String TEST_LOCATION = "99705"; 191 | static final String TEST_DATE = "20141205"; 192 | */ 193 | } -------------------------------------------------------------------------------- /test/TestProvider.java: -------------------------------------------------------------------------------- 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 | // package com.example.android.sunshine.app.test; 17 | 18 | // import android.annotation.TargetApi; 19 | // import android.content.ContentUris; 20 | // import android.content.ContentValues; 21 | // import android.database.Cursor; 22 | // import android.net.Uri; 23 | // import android.os.Build; 24 | // import android.test.AndroidTestCase; 25 | // import android.util.Log; 26 | // import com.example.android.sunshine.app.data.WeatherContract.LocationEntry; 27 | // import com.example.android.sunshine.app.data.WeatherContract.WeatherEntry; 28 | 29 | // public class TestProvider extends AndroidTestCase { 30 | 31 | // public static final String LOG_TAG = TestProvider.class.getSimpleName(); 32 | 33 | // // brings our database to an empty state 34 | // public void deleteAllRecords() { 35 | // mContext.getContentResolver().delete( 36 | // WeatherEntry.CONTENT_URI, 37 | // null, 38 | // null 39 | // ); 40 | // mContext.getContentResolver().delete( 41 | // LocationEntry.CONTENT_URI, 42 | // null, 43 | // null 44 | // ); 45 | 46 | // Cursor cursor = mContext.getContentResolver().query( 47 | // WeatherEntry.CONTENT_URI, 48 | // null, 49 | // null, 50 | // null, 51 | // null 52 | // ); 53 | // assertEquals(0, cursor.getCount()); 54 | // cursor.close(); 55 | 56 | // /* TODO Uncomment for 57 | // 4b - Implement Location_ID queries 58 | // https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/e-1675098551/m-1675098552 59 | // cursor = mContext.getContentResolver().query( 60 | // LocationEntry.CONTENT_URI, 61 | // null, 62 | // null, 63 | // null, 64 | // null 65 | // ); 66 | // assertEquals(0, cursor.getCount()); 67 | // cursor.close(); 68 | // */ 69 | // } 70 | 71 | // // Since we want each test to start with a clean slate, run deleteAllRecords 72 | // // in setUp (called by the test runner before each test). 73 | // public void setUp() { 74 | // deleteAllRecords(); 75 | // } 76 | 77 | // /* TODO Uncomment for 78 | // 4b - Implement Location_ID queries 79 | // https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/e-1675098551/m-1675098552 80 | 81 | // public void testInsertReadProvider() { 82 | 83 | // ContentValues testValues = TestDb.createNorthPoleLocationValues(); 84 | 85 | // Uri locationUri = mContext.getContentResolver().insert(LocationEntry.CONTENT_URI, testValues); 86 | // long locationRowId = ContentUris.parseId(locationUri); 87 | 88 | // // Verify we got a row back. 89 | // assertTrue(locationRowId != -1); 90 | 91 | // // Data's inserted. IN THEORY. Now pull some out to stare at it and verify it made 92 | // // the round trip. 93 | 94 | // // A cursor is your primary interface to the query results. 95 | // Cursor cursor = mContext.getContentResolver().query( 96 | // LocationEntry.CONTENT_URI, 97 | // null, // leaving "columns" null just returns all the columns. 98 | // null, // cols for "where" clause 99 | // null, // values for "where" clause 100 | // null // sort order 101 | // ); 102 | 103 | // TestDb.validateCursor(cursor, testValues); 104 | 105 | // // Now see if we can successfully query if we include the row id 106 | // cursor = mContext.getContentResolver().query( 107 | // LocationEntry.buildLocationUri(locationRowId), 108 | // null, // leaving "columns" null just returns all the columns. 109 | // null, // cols for "where" clause 110 | // null, // values for "where" clause 111 | // null // sort order 112 | // ); 113 | 114 | // TestDb.validateCursor(cursor, testValues); 115 | 116 | // // Fantastic. Now that we have a location, add some weather! 117 | // ContentValues weatherValues = TestDb.createWeatherValues(locationRowId); 118 | 119 | // Uri weatherInsertUri = mContext.getContentResolver() 120 | // .insert(WeatherEntry.CONTENT_URI, weatherValues); 121 | // assertTrue(weatherInsertUri != null); 122 | 123 | // // A cursor is your primary interface to the query results. 124 | // Cursor weatherCursor = mContext.getContentResolver().query( 125 | // WeatherEntry.CONTENT_URI, // Table to Query 126 | // null, // leaving "columns" null just returns all the columns. 127 | // null, // cols for "where" clause 128 | // null, // values for "where" clause 129 | // null // columns to group by 130 | // ); 131 | 132 | // TestDb.validateCursor(weatherCursor, weatherValues); 133 | 134 | // // Add the location values in with the weather data so that we can make 135 | // // sure that the join worked and we actually get all the values back 136 | // addAllContentValues(weatherValues, testValues); 137 | 138 | // // Get the joined Weather and Location data 139 | // weatherCursor = mContext.getContentResolver().query( 140 | // WeatherEntry.buildWeatherLocation(TestDb.TEST_LOCATION), 141 | // null, // leaving "columns" null just returns all the columns. 142 | // null, // cols for "where" clause 143 | // null, // values for "where" clause 144 | // null // sort order 145 | // ); 146 | // TestDb.validateCursor(weatherCursor, weatherValues); 147 | 148 | // // Get the joined Weather and Location data with a start date 149 | // weatherCursor = mContext.getContentResolver().query( 150 | // WeatherEntry.buildWeatherLocationWithStartDate( 151 | // TestDb.TEST_LOCATION, TestDb.TEST_DATE), 152 | // null, // leaving "columns" null just returns all the columns. 153 | // null, // cols for "where" clause 154 | // null, // values for "where" clause 155 | // null // sort order 156 | // ); 157 | // TestDb.validateCursor(weatherCursor, weatherValues); 158 | 159 | // // Get the joined Weather data for a specific date 160 | // weatherCursor = mContext.getContentResolver().query( 161 | // WeatherEntry.buildWeatherLocationWithDate(TestDb.TEST_LOCATION, TestDb.TEST_DATE), 162 | // null, 163 | // null, 164 | // null, 165 | // null 166 | // ); 167 | // TestDb.validateCursor(weatherCursor, weatherValues); 168 | // } 169 | // */ 170 | 171 | 172 | 173 | // /* TODO Uncomment for 174 | // 4b - Coding the Content Provider : getType() 175 | // https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/e-1675098546/m-1675098547 176 | // public void testGetType() { 177 | // // content://com.example.android.sunshine.app/weather/ 178 | // String type = mContext.getContentResolver().getType(WeatherEntry.CONTENT_URI); 179 | // // vnd.android.cursor.dir/com.example.android.sunshine.app/weather 180 | // assertEquals(WeatherEntry.CONTENT_TYPE, type); 181 | 182 | // String testLocation = "94074"; 183 | // // content://com.example.android.sunshine.app/weather/94074 184 | // type = mContext.getContentResolver().getType( 185 | // WeatherEntry.buildWeatherLocation(testLocation)); 186 | // // vnd.android.cursor.dir/com.example.android.sunshine.app/weather 187 | // assertEquals(WeatherEntry.CONTENT_TYPE, type); 188 | 189 | // String testDate = "20140612"; 190 | // // content://com.example.android.sunshine.app/weather/94074/20140612 191 | // type = mContext.getContentResolver().getType( 192 | // WeatherEntry.buildWeatherLocationWithDate(testLocation, testDate)); 193 | // // vnd.android.cursor.item/com.example.android.sunshine.app/weather 194 | // assertEquals(WeatherEntry.CONTENT_ITEM_TYPE, type); 195 | 196 | // // content://com.example.android.sunshine.app/location/ 197 | // type = mContext.getContentResolver().getType(LocationEntry.CONTENT_URI); 198 | // // vnd.android.cursor.dir/com.example.android.sunshine.app/location 199 | // assertEquals(LocationEntry.CONTENT_TYPE, type); 200 | 201 | // // content://com.example.android.sunshine.app/location/1 202 | // type = mContext.getContentResolver().getType(LocationEntry.buildLocationUri(1L)); 203 | // // vnd.android.cursor.item/com.example.android.sunshine.app/location 204 | // assertEquals(LocationEntry.CONTENT_ITEM_TYPE, type); 205 | // } 206 | // */ 207 | 208 | // /* TODO Uncomment for 209 | // 4b - Updating and Deleting 210 | // https://www.udacity.com/course/viewer#!/c-ud853/l-1576308909/e-1675098563/m-1675098564 211 | // public void testUpdateLocation() { 212 | // // Create a new map of values, where column names are the keys 213 | // ContentValues values = TestDb.createNorthPoleLocationValues(); 214 | 215 | // Uri locationUri = mContext.getContentResolver(). 216 | // insert(LocationEntry.CONTENT_URI, values); 217 | // long locationRowId = ContentUris.parseId(locationUri); 218 | 219 | // // Verify we got a row back. 220 | // assertTrue(locationRowId != -1); 221 | // Log.d(LOG_TAG, "New row id: " + locationRowId); 222 | 223 | // ContentValues updatedValues = new ContentValues(values); 224 | // updatedValues.put(LocationEntry._ID, locationRowId); 225 | // updatedValues.put(LocationEntry.COLUMN_CITY_NAME, "Santa's Village"); 226 | 227 | // int count = mContext.getContentResolver().update( 228 | // LocationEntry.CONTENT_URI, updatedValues, LocationEntry._ID + "= ?", 229 | // new String[] { Long.toString(locationRowId)}); 230 | 231 | // assertEquals(count, 1); 232 | 233 | // // A cursor is your primary interface to the query results. 234 | // Cursor cursor = mContext.getContentResolver().query( 235 | // LocationEntry.buildLocationUri(locationRowId), 236 | // null, 237 | // null, // Columns for the "where" clause 238 | // null, // Values for the "where" clause 239 | // null // sort order 240 | // ); 241 | 242 | // TestDb.validateCursor(cursor, updatedValues); 243 | // } 244 | // */ 245 | 246 | // // Make sure we can still delete after adding/updating stuff 247 | // public void testDeleteRecordsAtEnd() { 248 | // deleteAllRecords(); 249 | // } 250 | 251 | // // Helper Methods 252 | 253 | // // The target api annotation is needed for the call to keySet -- we wouldn't want 254 | // // to use this in our app, but in a test it's fine to assume a higher target. 255 | // @TargetApi(Build.VERSION_CODES.HONEYCOMB) 256 | // void addAllContentValues(ContentValues destination, ContentValues source) { 257 | // for (String key : source.keySet()) { 258 | // destination.put(key, source.getAsString(key)); 259 | // } 260 | // } 261 | 262 | // static final String KALAMAZOO_LOCATION_SETTING = "kalamazoo"; 263 | // static final String KALAMAZOO_WEATHER_START_DATE = "20140625"; 264 | 265 | // long locationRowId; 266 | 267 | // static ContentValues createKalamazooWeatherValues(long locationRowId) { 268 | // ContentValues weatherValues = new ContentValues(); 269 | // weatherValues.put(WeatherEntry.COLUMN_LOC_KEY, locationRowId); 270 | // weatherValues.put(WeatherEntry.COLUMN_DATETEXT, KALAMAZOO_WEATHER_START_DATE); 271 | // weatherValues.put(WeatherEntry.COLUMN_DEGREES, 1.2); 272 | // weatherValues.put(WeatherEntry.COLUMN_HUMIDITY, 1.5); 273 | // weatherValues.put(WeatherEntry.COLUMN_PRESSURE, 1.1); 274 | // weatherValues.put(WeatherEntry.COLUMN_MAX_TEMP, 85); 275 | // weatherValues.put(WeatherEntry.COLUMN_MIN_TEMP, 35); 276 | // weatherValues.put(WeatherEntry.COLUMN_SHORT_DESC, "Cats and Dogs"); 277 | // weatherValues.put(WeatherEntry.COLUMN_WIND_SPEED, 3.4); 278 | // weatherValues.put(WeatherEntry.COLUMN_WEATHER_ID, 42); 279 | 280 | // return weatherValues; 281 | // } 282 | 283 | // static ContentValues createKalamazooLocationValues() { 284 | // // Create a new map of values, where column names are the keys 285 | // ContentValues testValues = new ContentValues(); 286 | // testValues.put(LocationEntry.COLUMN_LOCATION_SETTING, KALAMAZOO_LOCATION_SETTING); 287 | // testValues.put(LocationEntry.COLUMN_CITY_NAME, "Kalamazoo"); 288 | // testValues.put(LocationEntry.COLUMN_COORD_LAT, 42.2917); 289 | // testValues.put(LocationEntry.COLUMN_COORD_LONG, -85.5872); 290 | 291 | // return testValues; 292 | // } 293 | 294 | // // Inserts both the location and weather data for the Kalamazoo data set. 295 | // public void insertKalamazooData() { 296 | // ContentValues kalamazooLocationValues = createKalamazooLocationValues(); 297 | // Uri locationInsertUri = mContext.getContentResolver() 298 | // .insert(LocationEntry.CONTENT_URI, kalamazooLocationValues); 299 | // assertTrue(locationInsertUri != null); 300 | 301 | // locationRowId = ContentUris.parseId(locationInsertUri); 302 | 303 | // ContentValues kalamazooWeatherValues = createKalamazooWeatherValues(locationRowId); 304 | // Uri weatherInsertUri = mContext.getContentResolver() 305 | // .insert(WeatherEntry.CONTENT_URI, kalamazooWeatherValues); 306 | // assertTrue(weatherInsertUri != null); 307 | // } 308 | // } 309 | --------------------------------------------------------------------------------