From 3d7d5974e19e1ee0d663894eddd853166eee216f Mon Sep 17 00:00:00 2001 From: Lyla Date: Mon, 9 Feb 2015 16:54:34 -0800 Subject: [PATCH 1/2] 4.17 Bulkinserts with the ContentProvider --- .../sunshine/app/data/TestProvider.java | 126 +++++++++--------- .../sunshine/app/FetchWeatherTask.java | 28 ++-- 2 files changed, 78 insertions(+), 76 deletions(-) diff --git a/app/src/androidTest/java/com/example/android/sunshine/app/data/TestProvider.java b/app/src/androidTest/java/com/example/android/sunshine/app/data/TestProvider.java index 55f0b65ea..5864d85f0 100644 --- a/app/src/androidTest/java/com/example/android/sunshine/app/data/TestProvider.java +++ b/app/src/androidTest/java/com/example/android/sunshine/app/data/TestProvider.java @@ -449,67 +449,67 @@ static ContentValues[] createBulkInsertWeatherValues(long locationRowId) { // in your provider. Note that this test will work with the built-in (default) provider // implementation, which just inserts records one-at-a-time, so really do implement the // BulkInsert ContentProvider function. -// public void testBulkInsert() { -// // first, let's create a location value -// ContentValues testValues = TestUtilities.createNorthPoleLocationValues(); -// Uri locationUri = mContext.getContentResolver().insert(LocationEntry.CONTENT_URI, testValues); -// long locationRowId = ContentUris.parseId(locationUri); -// -// // Verify we got a row back. -// assertTrue(locationRowId != -1); -// -// // Data's inserted. IN THEORY. Now pull some out to stare at it and verify it made -// // the round trip. -// -// // A cursor is your primary interface to the query results. -// Cursor cursor = mContext.getContentResolver().query( -// LocationEntry.CONTENT_URI, -// null, // leaving "columns" null just returns all the columns. -// null, // cols for "where" clause -// null, // values for "where" clause -// null // sort order -// ); -// -// TestUtilities.validateCursor("testBulkInsert. Error validating LocationEntry.", -// cursor, testValues); -// -// // Now we can bulkInsert some weather. In fact, we only implement BulkInsert for weather -// // entries. With ContentProviders, you really only have to implement the features you -// // use, after all. -// ContentValues[] bulkInsertContentValues = createBulkInsertWeatherValues(locationRowId); -// -// // Register a content observer for our bulk insert. -// TestUtilities.TestContentObserver weatherObserver = TestUtilities.getTestContentObserver(); -// mContext.getContentResolver().registerContentObserver(WeatherEntry.CONTENT_URI, true, weatherObserver); -// -// int insertCount = mContext.getContentResolver().bulkInsert(WeatherEntry.CONTENT_URI, bulkInsertContentValues); -// -// // Students: If this fails, it means that you most-likely are not calling the -// // getContext().getContentResolver().notifyChange(uri, null); in your BulkInsert -// // ContentProvider method. -// weatherObserver.waitForNotificationOrFail(); -// mContext.getContentResolver().unregisterContentObserver(weatherObserver); -// -// assertEquals(insertCount, BULK_INSERT_RECORDS_TO_INSERT); -// -// // A cursor is your primary interface to the query results. -// cursor = mContext.getContentResolver().query( -// WeatherEntry.CONTENT_URI, -// null, // leaving "columns" null just returns all the columns. -// null, // cols for "where" clause -// null, // values for "where" clause -// WeatherEntry.COLUMN_DATE + " ASC" // sort order == by DATE ASCENDING -// ); -// -// // we should have as many records in the database as we've inserted -// assertEquals(cursor.getCount(), BULK_INSERT_RECORDS_TO_INSERT); -// -// // and let's make sure they match the ones we created -// cursor.moveToFirst(); -// for ( int i = 0; i < BULK_INSERT_RECORDS_TO_INSERT; i++, cursor.moveToNext() ) { -// TestUtilities.validateCurrentRecord("testBulkInsert. Error validating WeatherEntry " + i, -// cursor, bulkInsertContentValues[i]); -// } -// cursor.close(); -// } + public void testBulkInsert() { + // first, let's create a location value + ContentValues testValues = TestUtilities.createNorthPoleLocationValues(); + Uri locationUri = mContext.getContentResolver().insert(LocationEntry.CONTENT_URI, testValues); + long locationRowId = ContentUris.parseId(locationUri); + + // Verify we got a row back. + assertTrue(locationRowId != -1); + + // Data's inserted. IN THEORY. Now pull some out to stare at it and verify it made + // the round trip. + + // A cursor is your primary interface to the query results. + Cursor cursor = mContext.getContentResolver().query( + LocationEntry.CONTENT_URI, + null, // leaving "columns" null just returns all the columns. + null, // cols for "where" clause + null, // values for "where" clause + null // sort order + ); + + TestUtilities.validateCursor("testBulkInsert. Error validating LocationEntry.", + cursor, testValues); + + // Now we can bulkInsert some weather. In fact, we only implement BulkInsert for weather + // entries. With ContentProviders, you really only have to implement the features you + // use, after all. + ContentValues[] bulkInsertContentValues = createBulkInsertWeatherValues(locationRowId); + + // Register a content observer for our bulk insert. + TestUtilities.TestContentObserver weatherObserver = TestUtilities.getTestContentObserver(); + mContext.getContentResolver().registerContentObserver(WeatherEntry.CONTENT_URI, true, weatherObserver); + + int insertCount = mContext.getContentResolver().bulkInsert(WeatherEntry.CONTENT_URI, bulkInsertContentValues); + + // Students: If this fails, it means that you most-likely are not calling the + // getContext().getContentResolver().notifyChange(uri, null); in your BulkInsert + // ContentProvider method. + weatherObserver.waitForNotificationOrFail(); + mContext.getContentResolver().unregisterContentObserver(weatherObserver); + + assertEquals(insertCount, BULK_INSERT_RECORDS_TO_INSERT); + + // A cursor is your primary interface to the query results. + cursor = mContext.getContentResolver().query( + WeatherEntry.CONTENT_URI, + null, // leaving "columns" null just returns all the columns. + null, // cols for "where" clause + null, // values for "where" clause + WeatherEntry.COLUMN_DATE + " ASC" // sort order == by DATE ASCENDING + ); + + // we should have as many records in the database as we've inserted + assertEquals(cursor.getCount(), BULK_INSERT_RECORDS_TO_INSERT); + + // and let's make sure they match the ones we created + cursor.moveToFirst(); + for ( int i = 0; i < BULK_INSERT_RECORDS_TO_INSERT; i++, cursor.moveToNext() ) { + TestUtilities.validateCurrentRecord("testBulkInsert. Error validating WeatherEntry " + i, + cursor, bulkInsertContentValues[i]); + } + cursor.close(); + } } diff --git a/app/src/main/java/com/example/android/sunshine/app/FetchWeatherTask.java b/app/src/main/java/com/example/android/sunshine/app/FetchWeatherTask.java index 498d7f139..4dc93f2e7 100644 --- a/app/src/main/java/com/example/android/sunshine/app/FetchWeatherTask.java +++ b/app/src/main/java/com/example/android/sunshine/app/FetchWeatherTask.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; +import android.database.DatabaseUtils; import android.net.Uri; import android.os.AsyncTask; import android.preference.PreferenceManager; @@ -302,7 +303,9 @@ private String[] getWeatherDataFromJson(String forecastJsonStr, // add to database if ( cVVector.size() > 0 ) { - // Student: call bulkInsert to add the weatherEntries to the database here + ContentValues[] cvArray = new ContentValues[cVVector.size()]; + cVVector.toArray(cvArray); + mContext.getContentResolver().bulkInsert(WeatherEntry.CONTENT_URI, cvArray); } // Sort order: Ascending, by date. @@ -311,18 +314,17 @@ private String[] getWeatherDataFromJson(String forecastJsonStr, locationSetting, System.currentTimeMillis()); // Students: Uncomment the next lines to display what what you stored in the bulkInsert - -// Cursor cur = mContext.getContentResolver().query(weatherForLocationUri, -// null, null, null, sortOrder); -// -// cVVector = new Vector(cur.getCount()); -// if ( cur.moveToFirst() ) { -// do { -// ContentValues cv = new ContentValues(); -// DatabaseUtils.cursorRowToContentValues(cur, cv); -// cVVector.add(cv); -// } while (cur.moveToNext()); -// } + Cursor cur = mContext.getContentResolver().query(weatherForLocationUri, + null, null, null, sortOrder); + + cVVector = new Vector(cur.getCount()); + if ( cur.moveToFirst() ) { + do { + ContentValues cv = new ContentValues(); + DatabaseUtils.cursorRowToContentValues(cur, cv); + cVVector.add(cv); + } while (cur.moveToNext()); + } Log.d(LOG_TAG, "FetchWeatherTask Complete. " + cVVector.size() + " Inserted"); From 898f4355c4bb257055f9f0eb2ac51e0412674cbf Mon Sep 17 00:00:00 2001 From: Chris Lei Date: Thu, 15 Oct 2015 21:28:04 -0700 Subject: [PATCH 2/2] Add API Key Parameter to OpenWeatherMap API Call --- app/build.gradle | 3 +++ .../com/example/android/sunshine/app/FetchWeatherTask.java | 2 ++ 2 files changed, 5 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index 19167f951..f7ffae8fd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,6 +17,9 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + buildTypes.each { + it.buildConfigField 'String', 'OPEN_WEATHER_MAP_API_KEY', MyOpenWeatherMapApiKey + } } dependencies { diff --git a/app/src/main/java/com/example/android/sunshine/app/FetchWeatherTask.java b/app/src/main/java/com/example/android/sunshine/app/FetchWeatherTask.java index 4dc93f2e7..4681a0089 100644 --- a/app/src/main/java/com/example/android/sunshine/app/FetchWeatherTask.java +++ b/app/src/main/java/com/example/android/sunshine/app/FetchWeatherTask.java @@ -369,12 +369,14 @@ protected String[] doInBackground(String... params) { final String FORMAT_PARAM = "mode"; final String UNITS_PARAM = "units"; final String DAYS_PARAM = "cnt"; + final String APPID_PARAM = "APPID"; Uri builtUri = Uri.parse(FORECAST_BASE_URL).buildUpon() .appendQueryParameter(QUERY_PARAM, params[0]) .appendQueryParameter(FORMAT_PARAM, format) .appendQueryParameter(UNITS_PARAM, units) .appendQueryParameter(DAYS_PARAM, Integer.toString(numDays)) + .appendQueryParameter(APPID_PARAM, BuildConfig.OPEN_WEATHER_MAP_API_KEY) .build(); URL url = new URL(builtUri.toString());