From 1578a360189e9e929004894ed3e8f2210b7db8a7 Mon Sep 17 00:00:00 2001 From: Lyla Date: Wed, 4 Mar 2015 15:54:47 -0800 Subject: [PATCH] Starter code for 4B, the Content Provider Lesson --- ...hWeatherTask.java => FetchWeatherTask.java | 0 LICENSE | 201 ---------- ...therTask.java => TestFetchWeatherTask.java | 0 .../TestProvider.java => TestProvider.java | 0 ...TestUriMatcher.java => TestUriMatcher.java | 0 ...rContract.java => TestWeatherContract.java | 0 ...atherProvider.java => WeatherProvider.java | 0 app/.gitignore | 1 - app/build.gradle | 25 -- app/proguard-rules.pro | 17 - .../android/sunshine/app/FullTestSuite.java | 32 -- .../android/sunshine/app/data/TestDb.java | 237 ------------ .../sunshine/app/data/TestUtilities.java | 151 -------- .../sunshine/app/utils/PollingCheck.java | 73 ---- app/src/main/AndroidManifest.xml | 40 -- .../android/sunshine/app/DetailActivity.java | 132 ------- .../sunshine/app/ForecastFragment.java | 356 ------------------ .../android/sunshine/app/MainActivity.java | 93 ----- .../sunshine/app/SettingsActivity.java | 83 ---- .../sunshine/app/data/WeatherContract.java | 168 --------- .../sunshine/app/data/WeatherDbHelper.java | 98 ----- .../main/res/drawable-hdpi/ic_launcher.png | Bin 4125 -> 0 bytes .../main/res/drawable-mdpi/ic_launcher.png | Bin 2350 -> 0 bytes .../main/res/drawable-xhdpi/ic_launcher.png | Bin 5797 -> 0 bytes .../main/res/drawable-xxhdpi/ic_launcher.png | Bin 10132 -> 0 bytes app/src/main/res/layout/activity_detail.xml | 5 - app/src/main/res/layout/activity_main.xml | 4 - app/src/main/res/layout/fragment_detail.xml | 13 - app/src/main/res/layout/fragment_main.xml | 17 - .../main/res/layout/list_item_forecast.xml | 8 - app/src/main/res/menu/detail.xml | 9 - app/src/main/res/menu/detailfragment.xml | 9 - app/src/main/res/menu/forecastfragment.xml | 8 - app/src/main/res/menu/main.xml | 11 - app/src/main/res/values-w820dp/dimens.xml | 6 - app/src/main/res/values/arrays.xml | 13 - app/src/main/res/values/dimens.xml | 5 - app/src/main/res/values/strings.xml | 51 --- app/src/main/res/values/styles.xml | 8 - app/src/main/res/xml/pref_general.xml | 20 - build.gradle | 19 - gradle.properties | 18 - gradle/wrapper/gradle-wrapper.jar | Bin 49896 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 6 - gradlew | 164 -------- gradlew.bat | 90 ----- settings.gradle | 1 - 47 files changed, 2192 deletions(-) rename app/src/main/java/com/example/android/sunshine/app/FetchWeatherTask.java => FetchWeatherTask.java (100%) delete mode 100644 LICENSE rename app/src/androidTest/java/com/example/android/sunshine/app/TestFetchWeatherTask.java => TestFetchWeatherTask.java (100%) rename app/src/androidTest/java/com/example/android/sunshine/app/data/TestProvider.java => TestProvider.java (100%) rename app/src/androidTest/java/com/example/android/sunshine/app/data/TestUriMatcher.java => TestUriMatcher.java (100%) rename app/src/androidTest/java/com/example/android/sunshine/app/data/TestWeatherContract.java => TestWeatherContract.java (100%) rename app/src/main/java/com/example/android/sunshine/app/data/WeatherProvider.java => WeatherProvider.java (100%) delete mode 100644 app/.gitignore delete mode 100644 app/build.gradle delete mode 100644 app/proguard-rules.pro delete mode 100644 app/src/androidTest/java/com/example/android/sunshine/app/FullTestSuite.java delete mode 100644 app/src/androidTest/java/com/example/android/sunshine/app/data/TestDb.java delete mode 100644 app/src/androidTest/java/com/example/android/sunshine/app/data/TestUtilities.java delete mode 100644 app/src/androidTest/java/com/example/android/sunshine/app/utils/PollingCheck.java delete mode 100644 app/src/main/AndroidManifest.xml delete mode 100644 app/src/main/java/com/example/android/sunshine/app/DetailActivity.java delete mode 100644 app/src/main/java/com/example/android/sunshine/app/ForecastFragment.java delete mode 100644 app/src/main/java/com/example/android/sunshine/app/MainActivity.java delete mode 100644 app/src/main/java/com/example/android/sunshine/app/SettingsActivity.java delete mode 100644 app/src/main/java/com/example/android/sunshine/app/data/WeatherContract.java delete mode 100644 app/src/main/java/com/example/android/sunshine/app/data/WeatherDbHelper.java delete mode 100644 app/src/main/res/drawable-hdpi/ic_launcher.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_launcher.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_launcher.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_launcher.png delete mode 100644 app/src/main/res/layout/activity_detail.xml delete mode 100644 app/src/main/res/layout/activity_main.xml delete mode 100644 app/src/main/res/layout/fragment_detail.xml delete mode 100644 app/src/main/res/layout/fragment_main.xml delete mode 100644 app/src/main/res/layout/list_item_forecast.xml delete mode 100644 app/src/main/res/menu/detail.xml delete mode 100644 app/src/main/res/menu/detailfragment.xml delete mode 100644 app/src/main/res/menu/forecastfragment.xml delete mode 100644 app/src/main/res/menu/main.xml delete mode 100644 app/src/main/res/values-w820dp/dimens.xml delete mode 100644 app/src/main/res/values/arrays.xml delete mode 100644 app/src/main/res/values/dimens.xml delete mode 100644 app/src/main/res/values/strings.xml delete mode 100644 app/src/main/res/values/styles.xml delete mode 100644 app/src/main/res/xml/pref_general.xml delete mode 100644 build.gradle delete mode 100644 gradle.properties delete mode 100644 gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle/wrapper/gradle-wrapper.properties delete mode 100755 gradlew delete mode 100644 gradlew.bat delete mode 100644 settings.gradle diff --git a/app/src/main/java/com/example/android/sunshine/app/FetchWeatherTask.java b/FetchWeatherTask.java similarity index 100% rename from app/src/main/java/com/example/android/sunshine/app/FetchWeatherTask.java rename to FetchWeatherTask.java diff --git a/LICENSE b/LICENSE deleted file mode 100644 index c02ca2f7a..000000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2014 Google Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/app/src/androidTest/java/com/example/android/sunshine/app/TestFetchWeatherTask.java b/TestFetchWeatherTask.java similarity index 100% rename from app/src/androidTest/java/com/example/android/sunshine/app/TestFetchWeatherTask.java rename to TestFetchWeatherTask.java diff --git a/app/src/androidTest/java/com/example/android/sunshine/app/data/TestProvider.java b/TestProvider.java similarity index 100% rename from app/src/androidTest/java/com/example/android/sunshine/app/data/TestProvider.java rename to TestProvider.java diff --git a/app/src/androidTest/java/com/example/android/sunshine/app/data/TestUriMatcher.java b/TestUriMatcher.java similarity index 100% rename from app/src/androidTest/java/com/example/android/sunshine/app/data/TestUriMatcher.java rename to TestUriMatcher.java diff --git a/app/src/androidTest/java/com/example/android/sunshine/app/data/TestWeatherContract.java b/TestWeatherContract.java similarity index 100% rename from app/src/androidTest/java/com/example/android/sunshine/app/data/TestWeatherContract.java rename to TestWeatherContract.java diff --git a/app/src/main/java/com/example/android/sunshine/app/data/WeatherProvider.java b/WeatherProvider.java similarity index 100% rename from app/src/main/java/com/example/android/sunshine/app/data/WeatherProvider.java rename to WeatherProvider.java diff --git a/app/.gitignore b/app/.gitignore deleted file mode 100644 index 796b96d1c..000000000 --- a/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index 19167f951..000000000 --- a/app/build.gradle +++ /dev/null @@ -1,25 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 21 - buildToolsVersion "21.1.2" - - defaultConfig { - applicationId "com.example.android.sunshine.app" - minSdkVersion 10 - targetSdkVersion 21 - versionCode 1 - versionName "1.0" - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:21.0.2' -} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro deleted file mode 100644 index eba3bbfce..000000000 --- a/app/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /Users/lyla/Library/Android/sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/app/src/androidTest/java/com/example/android/sunshine/app/FullTestSuite.java b/app/src/androidTest/java/com/example/android/sunshine/app/FullTestSuite.java deleted file mode 100644 index 0c037a1a2..000000000 --- a/app/src/androidTest/java/com/example/android/sunshine/app/FullTestSuite.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.example.android.sunshine.app; - -import android.test.suitebuilder.TestSuiteBuilder; - -import junit.framework.Test; -import junit.framework.TestSuite; - -public class FullTestSuite extends TestSuite { - public static Test suite() { - return new TestSuiteBuilder(FullTestSuite.class) - .includeAllPackagesUnderHere().build(); - } - - public FullTestSuite() { - super(); - } -} diff --git a/app/src/androidTest/java/com/example/android/sunshine/app/data/TestDb.java b/app/src/androidTest/java/com/example/android/sunshine/app/data/TestDb.java deleted file mode 100644 index c1cd6510d..000000000 --- a/app/src/androidTest/java/com/example/android/sunshine/app/data/TestDb.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.example.android.sunshine.app.data; - -import android.content.ContentValues; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.test.AndroidTestCase; - -import java.util.HashSet; - -public class TestDb extends AndroidTestCase { - - public static final String LOG_TAG = TestDb.class.getSimpleName(); - - // Since we want each test to start with a clean slate - void deleteTheDatabase() { - mContext.deleteDatabase(WeatherDbHelper.DATABASE_NAME); - } - - /* - This function gets called before each test is executed to delete the database. This makes - sure that we always have a clean test. - */ - public void setUp() { - deleteTheDatabase(); - } - - /* - Students: Uncomment this test once you've written the code to create the Location - table. Note that you will have to have chosen the same column names that I did in - my solution for this test to compile, so if you haven't yet done that, this is - a good time to change your column names to match mine. - - Note that this only tests that the Location table has the correct columns, since we - give you the code for the weather table. This test does not look at the - */ - public void testCreateDb() throws Throwable { - // build a HashSet of all of the table names we wish to look for - // Note that there will be another table in the DB that stores the - // Android metadata (db version information) - final HashSet tableNameHashSet = new HashSet(); - tableNameHashSet.add(WeatherContract.LocationEntry.TABLE_NAME); - tableNameHashSet.add(WeatherContract.WeatherEntry.TABLE_NAME); - - mContext.deleteDatabase(WeatherDbHelper.DATABASE_NAME); - SQLiteDatabase db = new WeatherDbHelper( - this.mContext).getWritableDatabase(); - assertEquals(true, db.isOpen()); - - // have we created the tables we want? - Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null); - - assertTrue("Error: This means that the database has not been created correctly", - c.moveToFirst()); - - // verify that the tables have been created - do { - tableNameHashSet.remove(c.getString(0)); - } while( c.moveToNext() ); - - // if this fails, it means that your database doesn't contain both the location entry - // and weather entry tables - assertTrue("Error: Your database was created without both the location entry and weather entry tables", - tableNameHashSet.isEmpty()); - - // now, do our tables contain the correct columns? - c = db.rawQuery("PRAGMA table_info(" + WeatherContract.LocationEntry.TABLE_NAME + ")", - null); - - assertTrue("Error: This means that we were unable to query the database for table information.", - c.moveToFirst()); - - // Build a HashSet of all of the column names we want to look for - final HashSet locationColumnHashSet = new HashSet(); - locationColumnHashSet.add(WeatherContract.LocationEntry._ID); - locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_CITY_NAME); - locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_COORD_LAT); - locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_COORD_LONG); - locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING); - - int columnNameIndex = c.getColumnIndex("name"); - do { - String columnName = c.getString(columnNameIndex); - locationColumnHashSet.remove(columnName); - } while(c.moveToNext()); - - // if this fails, it means that your database doesn't contain all of the required location - // entry columns - assertTrue("Error: The database doesn't contain all of the required location entry columns", - locationColumnHashSet.isEmpty()); - db.close(); - } - - /* - Students: Here is where you will build code to test that we can insert and query the - location database. We've done a lot of work for you. You'll want to look in TestUtilities - where you can uncomment out the "createNorthPoleLocationValues" function. You can - also make use of the ValidateCurrentRecord function from within TestUtilities. - */ - public void testLocationTable() { - insertLocation(); - } - - /* - Students: Here is where you will build code to test that we can insert and query the - database. We've done a lot of work for you. You'll want to look in TestUtilities - where you can use the "createWeatherValues" function. You can - also make use of the validateCurrentRecord function from within TestUtilities. - */ - public void testWeatherTable() { - // First insert the location, and then use the locationRowId to insert - // the weather. Make sure to cover as many failure cases as you can. - - // Instead of rewriting all of the code we've already written in testLocationTable - // we can move this code to insertLocation and then call insertLocation from both - // tests. Why move it? We need the code to return the ID of the inserted location - // and our testLocationTable can only return void because it's a test. - - long locationRowId = insertLocation(); - - // Make sure we have a valid row ID. - assertFalse("Error: Location Not Inserted Correctly", locationRowId == -1L); - - // First step: Get reference to writable database - // If there's an error in those massive SQL table creation Strings, - // errors will be thrown here when you try to get a writable database. - WeatherDbHelper dbHelper = new WeatherDbHelper(mContext); - SQLiteDatabase db = dbHelper.getWritableDatabase(); - - // Second Step (Weather): Create weather values - ContentValues weatherValues = TestUtilities.createWeatherValues(locationRowId); - - // Third Step (Weather): Insert ContentValues into database and get a row ID back - long weatherRowId = db.insert(WeatherContract.WeatherEntry.TABLE_NAME, null, weatherValues); - assertTrue(weatherRowId != -1); - - // Fourth Step: Query the database and receive a Cursor back - // A cursor is your primary interface to the query results. - Cursor weatherCursor = db.query( - WeatherContract.WeatherEntry.TABLE_NAME, // Table to Query - null, // leaving "columns" null just returns all the columns. - null, // cols for "where" clause - null, // values for "where" clause - null, // columns to group by - null, // columns to filter by row groups - null // sort order - ); - - // Move the cursor to the first valid database row and check to see if we have any rows - assertTrue( "Error: No Records returned from location query", weatherCursor.moveToFirst() ); - - // Fifth Step: Validate the location Query - TestUtilities.validateCurrentRecord("testInsertReadDb weatherEntry failed to validate", - weatherCursor, weatherValues); - - // Move the cursor to demonstrate that there is only one record in the database - assertFalse( "Error: More than one record returned from weather query", - weatherCursor.moveToNext() ); - - // Sixth Step: Close cursor and database - weatherCursor.close(); - dbHelper.close(); - } - - - /* - Students: This is a helper method for the testWeatherTable quiz. You can move your - code from testLocationTable to here so that you can call this code from both - testWeatherTable and testLocationTable. - */ - public long insertLocation() { - // First step: Get reference to writable database - // If there's an error in those massive SQL table creation Strings, - // errors will be thrown here when you try to get a writable database. - WeatherDbHelper dbHelper = new WeatherDbHelper(mContext); - SQLiteDatabase db = dbHelper.getWritableDatabase(); - - // Second Step: Create ContentValues of what you want to insert - // (you can use the createNorthPoleLocationValues if you wish) - ContentValues testValues = TestUtilities.createNorthPoleLocationValues(); - - // Third Step: Insert ContentValues into database and get a row ID back - long locationRowId; - locationRowId = db.insert(WeatherContract.LocationEntry.TABLE_NAME, null, testValues); - - // 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. - - // Fourth Step: Query the database and receive a Cursor back - // A cursor is your primary interface to the query results. - Cursor cursor = db.query( - WeatherContract.LocationEntry.TABLE_NAME, // Table to Query - null, // all columns - null, // Columns for the "where" clause - null, // Values for the "where" clause - null, // columns to group by - null, // columns to filter by row groups - null // sort order - ); - - // Move the cursor to a valid database row and check to see if we got any records back - // from the query - assertTrue( "Error: No Records returned from location query", cursor.moveToFirst() ); - - // Fifth Step: Validate data in resulting Cursor with the original ContentValues - // (you can use the validateCurrentRecord function in TestUtilities to validate the - // query if you like) - TestUtilities.validateCurrentRecord("Error: Location Query Validation Failed", - cursor, testValues); - - // Move the cursor to demonstrate that there is only one record in the database - assertFalse( "Error: More than one record returned from location query", - cursor.moveToNext() ); - - // Sixth Step: Close Cursor and Database - cursor.close(); - db.close(); - return locationRowId; - } -} diff --git a/app/src/androidTest/java/com/example/android/sunshine/app/data/TestUtilities.java b/app/src/androidTest/java/com/example/android/sunshine/app/data/TestUtilities.java deleted file mode 100644 index 593957231..000000000 --- a/app/src/androidTest/java/com/example/android/sunshine/app/data/TestUtilities.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.example.android.sunshine.app.data; - -import android.content.ContentValues; -import android.content.Context; -import android.database.ContentObserver; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.net.Uri; -import android.os.Handler; -import android.os.HandlerThread; -import android.test.AndroidTestCase; - -import com.example.android.sunshine.app.utils.PollingCheck; - -import java.util.Map; -import java.util.Set; - -/* - Students: These are functions and some test data to make it easier to test your database and - Content Provider. Note that you'll want your WeatherContract class to exactly match the one - in our solution to use these as-given. - */ -public class TestUtilities extends AndroidTestCase { - static final String TEST_LOCATION = "99705"; - static final long TEST_DATE = 1419033600L; // December 20th, 2014 - - static void validateCursor(String error, Cursor valueCursor, ContentValues expectedValues) { - assertTrue("Empty cursor returned. " + error, valueCursor.moveToFirst()); - validateCurrentRecord(error, valueCursor, expectedValues); - valueCursor.close(); - } - - static void validateCurrentRecord(String error, Cursor valueCursor, ContentValues expectedValues) { - Set> valueSet = expectedValues.valueSet(); - for (Map.Entry entry : valueSet) { - String columnName = entry.getKey(); - int idx = valueCursor.getColumnIndex(columnName); - assertFalse("Column '" + columnName + "' not found. " + error, idx == -1); - String expectedValue = entry.getValue().toString(); - assertEquals("Value '" + entry.getValue().toString() + - "' did not match the expected value '" + - expectedValue + "'. " + error, expectedValue, valueCursor.getString(idx)); - } - } - - /* - Students: Use this to create some default weather values for your database tests. - */ - static ContentValues createWeatherValues(long locationRowId) { - ContentValues weatherValues = new ContentValues(); - weatherValues.put(WeatherContract.WeatherEntry.COLUMN_LOC_KEY, locationRowId); - weatherValues.put(WeatherContract.WeatherEntry.COLUMN_DATE, TEST_DATE); - weatherValues.put(WeatherContract.WeatherEntry.COLUMN_DEGREES, 1.1); - weatherValues.put(WeatherContract.WeatherEntry.COLUMN_HUMIDITY, 1.2); - weatherValues.put(WeatherContract.WeatherEntry.COLUMN_PRESSURE, 1.3); - weatherValues.put(WeatherContract.WeatherEntry.COLUMN_MAX_TEMP, 75); - weatherValues.put(WeatherContract.WeatherEntry.COLUMN_MIN_TEMP, 65); - weatherValues.put(WeatherContract.WeatherEntry.COLUMN_SHORT_DESC, "Asteroids"); - weatherValues.put(WeatherContract.WeatherEntry.COLUMN_WIND_SPEED, 5.5); - weatherValues.put(WeatherContract.WeatherEntry.COLUMN_WEATHER_ID, 321); - - return weatherValues; - } - - /* - Students: You can uncomment this helper function once you have finished creating the - LocationEntry part of the WeatherContract. - */ - static ContentValues createNorthPoleLocationValues() { - // Create a new map of values, where column names are the keys - ContentValues testValues = new ContentValues(); - testValues.put(WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING, TEST_LOCATION); - testValues.put(WeatherContract.LocationEntry.COLUMN_CITY_NAME, "North Pole"); - testValues.put(WeatherContract.LocationEntry.COLUMN_COORD_LAT, 64.7488); - testValues.put(WeatherContract.LocationEntry.COLUMN_COORD_LONG, -147.353); - - return testValues; - } - - /* - Students: You can uncomment this function once you have finished creating the - LocationEntry part of the WeatherContract as well as the WeatherDbHelper. - */ - static long insertNorthPoleLocationValues(Context context) { - // insert our test records into the database - WeatherDbHelper dbHelper = new WeatherDbHelper(context); - SQLiteDatabase db = dbHelper.getWritableDatabase(); - ContentValues testValues = TestUtilities.createNorthPoleLocationValues(); - - long locationRowId; - locationRowId = db.insert(WeatherContract.LocationEntry.TABLE_NAME, null, testValues); - - // Verify we got a row back. - assertTrue("Error: Failure to insert North Pole Location Values", locationRowId != -1); - - return locationRowId; - } - - /* - Students: The functions we provide inside of TestProvider use this utility class to test - the ContentObserver callbacks using the PollingCheck class that we grabbed from the Android - CTS tests. - - Note that this only tests that the onChange function is called; it does not test that the - correct Uri is returned. - */ - static class TestContentObserver extends ContentObserver { - final HandlerThread mHT; - boolean mContentChanged; - - static TestContentObserver getTestContentObserver() { - HandlerThread ht = new HandlerThread("ContentObserverThread"); - ht.start(); - return new TestContentObserver(ht); - } - - private TestContentObserver(HandlerThread ht) { - super(new Handler(ht.getLooper())); - mHT = ht; - } - - // On earlier versions of Android, this onChange method is called - @Override - public void onChange(boolean selfChange) { - onChange(selfChange, null); - } - - @Override - public void onChange(boolean selfChange, Uri uri) { - mContentChanged = true; - } - - public void waitForNotificationOrFail() { - // Note: The PollingCheck class is taken from the Android CTS (Compatibility Test Suite). - // It's useful to look at the Android CTS source for ideas on how to test your Android - // applications. The reason that PollingCheck works is that, by default, the JUnit - // testing framework is not running on the main Android application thread. - new PollingCheck(5000) { - @Override - protected boolean check() { - return mContentChanged; - } - }.run(); - mHT.quit(); - } - } - - static TestContentObserver getTestContentObserver() { - return TestContentObserver.getTestContentObserver(); - } -} diff --git a/app/src/androidTest/java/com/example/android/sunshine/app/utils/PollingCheck.java b/app/src/androidTest/java/com/example/android/sunshine/app/utils/PollingCheck.java deleted file mode 100644 index 733d503d0..000000000 --- a/app/src/androidTest/java/com/example/android/sunshine/app/utils/PollingCheck.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Note: This file copied from the Android CTS Tests - */ -package com.example.android.sunshine.app.utils; - -import junit.framework.Assert; - -import java.util.concurrent.Callable; - -public abstract class PollingCheck { - private static final long TIME_SLICE = 50; - private long mTimeout = 3000; - - public PollingCheck() { - } - - public PollingCheck(long timeout) { - mTimeout = timeout; - } - - protected abstract boolean check(); - - public void run() { - if (check()) { - return; - } - - long timeout = mTimeout; - while (timeout > 0) { - try { - Thread.sleep(TIME_SLICE); - } catch (InterruptedException e) { - Assert.fail("unexpected InterruptedException"); - } - - if (check()) { - return; - } - - timeout -= TIME_SLICE; - } - - Assert.fail("unexpected timeout"); - } - - public static void check(CharSequence message, long timeout, Callable condition) - throws Exception { - while (timeout > 0) { - if (condition.call()) { - return; - } - - Thread.sleep(TIME_SLICE); - timeout -= TIME_SLICE; - } - - Assert.fail(message.toString()); - } -} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml deleted file mode 100644 index 99c059290..000000000 --- a/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/java/com/example/android/sunshine/app/DetailActivity.java b/app/src/main/java/com/example/android/sunshine/app/DetailActivity.java deleted file mode 100644 index 08b9116b2..000000000 --- a/app/src/main/java/com/example/android/sunshine/app/DetailActivity.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.example.android.sunshine.app; - -import android.support.v7.app.ActionBarActivity; -import android.content.Intent; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v4.view.MenuItemCompat; -import android.support.v7.widget.ShareActionProvider; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -public class DetailActivity extends ActionBarActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_detail); - if (savedInstanceState == null) { - getSupportFragmentManager().beginTransaction() - .add(R.id.container, new DetailFragment()) - .commit(); - } - } - - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.detail, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - - //noinspection SimplifiableIfStatement - if (id == R.id.action_settings) { - startActivity(new Intent(this, SettingsActivity.class)); - return true; - } - - return super.onOptionsItemSelected(item); - } - - /** - * A placeholder fragment containing a simple view. - */ - public static class DetailFragment extends Fragment { - - private static final String LOG_TAG = DetailFragment.class.getSimpleName(); - - private static final String FORECAST_SHARE_HASHTAG = " #SunshineApp"; - private String mForecastStr; - - public DetailFragment() { - setHasOptionsMenu(true); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - - View rootView = inflater.inflate(R.layout.fragment_detail, container, false); - - // The detail Activity called via intent. Inspect the intent for forecast data. - Intent intent = getActivity().getIntent(); - if (intent != null && intent.hasExtra(Intent.EXTRA_TEXT)) { - mForecastStr = intent.getStringExtra(Intent.EXTRA_TEXT); - ((TextView) rootView.findViewById(R.id.detail_text)) - .setText(mForecastStr); - } - - return rootView; - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - // Inflate the menu; this adds items to the action bar if it is present. - inflater.inflate(R.menu.detailfragment, menu); - - // Retrieve the share menu item - MenuItem menuItem = menu.findItem(R.id.action_share); - - // Get the provider and hold onto it to set/change the share intent. - ShareActionProvider mShareActionProvider = - (ShareActionProvider) MenuItemCompat.getActionProvider(menuItem); - - // Attach an intent to this ShareActionProvider. You can update this at any time, - // like when the user selects a new piece of data they might like to share. - if (mShareActionProvider != null ) { - mShareActionProvider.setShareIntent(createShareForecastIntent()); - } else { - Log.d(LOG_TAG, "Share Action Provider is null?"); - } - } - - private Intent createShareForecastIntent() { - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); - shareIntent.setType("text/plain"); - shareIntent.putExtra(Intent.EXTRA_TEXT, - mForecastStr + FORECAST_SHARE_HASHTAG); - return shareIntent; - } - } -} diff --git a/app/src/main/java/com/example/android/sunshine/app/ForecastFragment.java b/app/src/main/java/com/example/android/sunshine/app/ForecastFragment.java deleted file mode 100644 index 7b5ada34d..000000000 --- a/app/src/main/java/com/example/android/sunshine/app/ForecastFragment.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.example.android.sunshine.app; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; -import android.text.format.Time; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.ListView; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.text.SimpleDateFormat; -import java.util.ArrayList; - -/** - * Encapsulates fetching the forecast and displaying it as a {@link ListView} layout. - */ -public class ForecastFragment extends Fragment { - - private ArrayAdapter mForecastAdapter; - - public ForecastFragment() { - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Add this line in order for this fragment to handle menu events. - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - inflater.inflate(R.menu.forecastfragment, menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - if (id == R.id.action_refresh) { - updateWeather(); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - - // The ArrayAdapter will take data from a source and - // use it to populate the ListView it's attached to. - mForecastAdapter = - new ArrayAdapter( - getActivity(), // The current context (this activity) - R.layout.list_item_forecast, // The name of the layout ID. - R.id.list_item_forecast_textview, // The ID of the textview to populate. - new ArrayList()); - - View rootView = inflater.inflate(R.layout.fragment_main, container, false); - - // Get a reference to the ListView, and attach this adapter to it. - ListView listView = (ListView) rootView.findViewById(R.id.listview_forecast); - listView.setAdapter(mForecastAdapter); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - - @Override - public void onItemClick(AdapterView adapterView, View view, int position, long l) { - String forecast = mForecastAdapter.getItem(position); - Intent intent = new Intent(getActivity(), DetailActivity.class) - .putExtra(Intent.EXTRA_TEXT, forecast); - startActivity(intent); - } - }); - - return rootView; - } - - private void updateWeather() { - FetchWeatherTask weatherTask = new FetchWeatherTask(); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); - String location = prefs.getString(getString(R.string.pref_location_key), - getString(R.string.pref_location_default)); - weatherTask.execute(location); - } - - @Override - public void onStart() { - super.onStart(); - updateWeather(); - } - - public class FetchWeatherTask extends AsyncTask { - - private final String LOG_TAG = FetchWeatherTask.class.getSimpleName(); - - /* The date/time conversion code is going to be moved outside the asynctask later, - * so for convenience we're breaking it out into its own method now. - */ - private String getReadableDateString(long time){ - // Because the API returns a unix timestamp (measured in seconds), - // it must be converted to milliseconds in order to be converted to valid date. - SimpleDateFormat shortenedDateFormat = new SimpleDateFormat("EEE MMM dd"); - return shortenedDateFormat.format(time); - } - - /** - * Prepare the weather high/lows for presentation. - */ - private String formatHighLows(double high, double low, String unitType) { - - if (unitType.equals(getString(R.string.pref_units_imperial))) { - high = (high * 1.8) + 32; - low = (low * 1.8) + 32; - } else if (!unitType.equals(getString(R.string.pref_units_metric))) { - Log.d(LOG_TAG, "Unit type not found: " + unitType); - } - - // For presentation, assume the user doesn't care about tenths of a degree. - long roundedHigh = Math.round(high); - long roundedLow = Math.round(low); - - String highLowStr = roundedHigh + "/" + roundedLow; - return highLowStr; - } - - /** - * Take the String representing the complete forecast in JSON Format and - * pull out the data we need to construct the Strings needed for the wireframes. - * - * Fortunately parsing is easy: constructor takes the JSON string and converts it - * into an Object hierarchy for us. - */ - private String[] getWeatherDataFromJson(String forecastJsonStr, int numDays) - throws JSONException { - - // These are the names of the JSON objects that need to be extracted. - final String OWM_LIST = "list"; - final String OWM_WEATHER = "weather"; - final String OWM_TEMPERATURE = "temp"; - final String OWM_MAX = "max"; - final String OWM_MIN = "min"; - final String OWM_DESCRIPTION = "main"; - - JSONObject forecastJson = new JSONObject(forecastJsonStr); - JSONArray weatherArray = forecastJson.getJSONArray(OWM_LIST); - - // OWM returns daily forecasts based upon the local time of the city that is being - // asked for, which means that we need to know the GMT offset to translate this data - // properly. - - // Since this data is also sent in-order and the first day is always the - // current day, we're going to take advantage of that to get a nice - // normalized UTC date for all of our weather. - - Time dayTime = new Time(); - dayTime.setToNow(); - - // we start at the day returned by local time. Otherwise this is a mess. - int julianStartDay = Time.getJulianDay(System.currentTimeMillis(), dayTime.gmtoff); - - // now we work exclusively in UTC - dayTime = new Time(); - - String[] resultStrs = new String[numDays]; - - // Data is fetched in Celsius by default. - // If user prefers to see in Fahrenheit, convert the values here. - // We do this rather than fetching in Fahrenheit so that the user can - // change this option without us having to re-fetch the data once - // we start storing the values in a database. - SharedPreferences sharedPrefs = - PreferenceManager.getDefaultSharedPreferences(getActivity()); - String unitType = sharedPrefs.getString( - getString(R.string.pref_units_key), - getString(R.string.pref_units_metric)); - - for(int i = 0; i < weatherArray.length(); i++) { - // For now, using the format "Day, description, hi/low" - String day; - String description; - String highAndLow; - - // Get the JSON object representing the day - JSONObject dayForecast = weatherArray.getJSONObject(i); - - // The date/time is returned as a long. We need to convert that - // into something human-readable, since most people won't read "1400356800" as - // "this saturday". - long dateTime; - // Cheating to convert this to UTC time, which is what we want anyhow - dateTime = dayTime.setJulianDay(julianStartDay+i); - day = getReadableDateString(dateTime); - - // description is in a child array called "weather", which is 1 element long. - JSONObject weatherObject = dayForecast.getJSONArray(OWM_WEATHER).getJSONObject(0); - description = weatherObject.getString(OWM_DESCRIPTION); - - // Temperatures are in a child object called "temp". Try not to name variables - // "temp" when working with temperature. It confuses everybody. - JSONObject temperatureObject = dayForecast.getJSONObject(OWM_TEMPERATURE); - double high = temperatureObject.getDouble(OWM_MAX); - double low = temperatureObject.getDouble(OWM_MIN); - - highAndLow = formatHighLows(high, low, unitType); - resultStrs[i] = day + " - " + description + " - " + highAndLow; - } - return resultStrs; - - } - @Override - protected String[] doInBackground(String... params) { - - // If there's no zip code, there's nothing to look up. Verify size of params. - if (params.length == 0) { - return null; - } - - // These two need to be declared outside the try/catch - // so that they can be closed in the finally block. - HttpURLConnection urlConnection = null; - BufferedReader reader = null; - - // Will contain the raw JSON response as a string. - String forecastJsonStr = null; - - String format = "json"; - String units = "metric"; - int numDays = 7; - - try { - // Construct the URL for the OpenWeatherMap query - // Possible parameters are avaiable at OWM's forecast API page, at - // http://openweathermap.org/API#forecast - final String FORECAST_BASE_URL = - "http://api.openweathermap.org/data/2.5/forecast/daily?"; - final String QUERY_PARAM = "q"; - final String FORMAT_PARAM = "mode"; - final String UNITS_PARAM = "units"; - final String DAYS_PARAM = "cnt"; - - 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)) - .build(); - - URL url = new URL(builtUri.toString()); - - // Create the request to OpenWeatherMap, and open the connection - urlConnection = (HttpURLConnection) url.openConnection(); - urlConnection.setRequestMethod("GET"); - urlConnection.connect(); - - // Read the input stream into a String - InputStream inputStream = urlConnection.getInputStream(); - StringBuffer buffer = new StringBuffer(); - if (inputStream == null) { - // Nothing to do. - return null; - } - reader = new BufferedReader(new InputStreamReader(inputStream)); - - String line; - while ((line = reader.readLine()) != null) { - // Since it's JSON, adding a newline isn't necessary (it won't affect parsing) - // But it does make debugging a *lot* easier if you print out the completed - // buffer for debugging. - buffer.append(line + "\n"); - } - - if (buffer.length() == 0) { - // Stream was empty. No point in parsing. - return null; - } - forecastJsonStr = buffer.toString(); - } catch (IOException e) { - Log.e(LOG_TAG, "Error ", e); - // If the code didn't successfully get the weather data, there's no point in attemping - // to parse it. - return null; - } finally { - if (urlConnection != null) { - urlConnection.disconnect(); - } - if (reader != null) { - try { - reader.close(); - } catch (final IOException e) { - Log.e(LOG_TAG, "Error closing stream", e); - } - } - } - - try { - return getWeatherDataFromJson(forecastJsonStr, numDays); - } catch (JSONException e) { - Log.e(LOG_TAG, e.getMessage(), e); - e.printStackTrace(); - } - - // This will only happen if there was an error getting or parsing the forecast. - return null; - } - - @Override - protected void onPostExecute(String[] result) { - if (result != null) { - mForecastAdapter.clear(); - for(String dayForecastStr : result) { - mForecastAdapter.add(dayForecastStr); - } - // New data is back from the server. Hooray! - } - } - } -} diff --git a/app/src/main/java/com/example/android/sunshine/app/MainActivity.java b/app/src/main/java/com/example/android/sunshine/app/MainActivity.java deleted file mode 100644 index d2e5e50fe..000000000 --- a/app/src/main/java/com/example/android/sunshine/app/MainActivity.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.example.android.sunshine.app; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.Uri; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v7.app.ActionBarActivity; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; - -public class MainActivity extends ActionBarActivity { - - private final String LOG_TAG = MainActivity.class.getSimpleName(); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - if (savedInstanceState == null) { - getSupportFragmentManager().beginTransaction() - .add(R.id.container, new ForecastFragment()) - .commit(); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.main, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - - //noinspection SimplifiableIfStatement - if (id == R.id.action_settings) { - startActivity(new Intent(this, SettingsActivity.class)); - return true; - } - - if (id == R.id.action_map) { - openPreferredLocationInMap(); - return true; - } - return super.onOptionsItemSelected(item); - } - - private void openPreferredLocationInMap() { - SharedPreferences sharedPrefs = - PreferenceManager.getDefaultSharedPreferences(this); - String location = sharedPrefs.getString( - getString(R.string.pref_location_key), - getString(R.string.pref_location_default)); - - // Using the URI scheme for showing a location found on a map. This super-handy - // intent can is detailed in the "Common Intents" page of Android's developer site: - // http://developer.android.com/guide/components/intents-common.html#Maps - Uri geoLocation = Uri.parse("geo:0,0?").buildUpon() - .appendQueryParameter("q", location) - .build(); - - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(geoLocation); - - if (intent.resolveActivity(getPackageManager()) != null) { - startActivity(intent); - } else { - Log.d(LOG_TAG, "Couldn't call " + location + ", no receiving apps installed!"); - } - } -} diff --git a/app/src/main/java/com/example/android/sunshine/app/SettingsActivity.java b/app/src/main/java/com/example/android/sunshine/app/SettingsActivity.java deleted file mode 100644 index 98dac5661..000000000 --- a/app/src/main/java/com/example/android/sunshine/app/SettingsActivity.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.example.android.sunshine.app; - -import android.os.Bundle; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceActivity; -import android.preference.PreferenceManager; - -/** - * A {@link PreferenceActivity} that presents a set of application settings. - *

- * See - * Android Design: Settings for design guidelines and the Settings - * API Guide for more information on developing a Settings UI. - */ -public class SettingsActivity extends PreferenceActivity - implements Preference.OnPreferenceChangeListener { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Add 'general' preferences, defined in the XML file - addPreferencesFromResource(R.xml.pref_general); - - // For all preferences, attach an OnPreferenceChangeListener so the UI summary can be - // updated when the preference changes. - bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_location_key))); - bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_units_key))); - } - - /** - * Attaches a listener so the summary is always updated with the preference value. - * Also fires the listener once, to initialize the summary (so it shows up before the value - * is changed.) - */ - private void bindPreferenceSummaryToValue(Preference preference) { - // Set the listener to watch for value changes. - preference.setOnPreferenceChangeListener(this); - - // Trigger the listener immediately with the preference's - // current value. - onPreferenceChange(preference, - PreferenceManager - .getDefaultSharedPreferences(preference.getContext()) - .getString(preference.getKey(), "")); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - String stringValue = value.toString(); - - if (preference instanceof ListPreference) { - // For list preferences, look up the correct display value in - // the preference's 'entries' list (since they have separate labels/values). - ListPreference listPreference = (ListPreference) preference; - int prefIndex = listPreference.findIndexOfValue(stringValue); - if (prefIndex >= 0) { - preference.setSummary(listPreference.getEntries()[prefIndex]); - } - } else { - // For other preferences, set the summary to the value's simple string representation. - preference.setSummary(stringValue); - } - return true; - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/android/sunshine/app/data/WeatherContract.java b/app/src/main/java/com/example/android/sunshine/app/data/WeatherContract.java deleted file mode 100644 index 9b003430d..000000000 --- a/app/src/main/java/com/example/android/sunshine/app/data/WeatherContract.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.example.android.sunshine.app.data; - -import android.content.ContentResolver; -import android.content.ContentUris; -import android.net.Uri; -import android.provider.BaseColumns; -import android.text.format.Time; - -/** - * Defines table and column names for the weather database. - */ -public class WeatherContract { - - // The "Content authority" is a name for the entire content provider, similar to the - // relationship between a domain name and its website. A convenient string to use for the - // content authority is the package name for the app, which is guaranteed to be unique on the - // device. - public static final String CONTENT_AUTHORITY = "com.example.android.sunshine.app"; - - // Use CONTENT_AUTHORITY to create the base of all URI's which apps will use to contact - // the content provider. - public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY); - - // Possible paths (appended to base content URI for possible URI's) - // For instance, content://com.example.android.sunshine.app/weather/ is a valid path for - // looking at weather data. content://com.example.android.sunshine.app/givemeroot/ will fail, - // as the ContentProvider hasn't been given any information on what to do with "givemeroot". - // At least, let's hope not. Don't be that dev, reader. Don't be that dev. - public static final String PATH_WEATHER = "weather"; - public static final String PATH_LOCATION = "location"; - - // To make it easy to query for the exact date, we normalize all dates that go into - // the database to the start of the the Julian day at UTC. - public static long normalizeDate(long startDate) { - // normalize the start date to the beginning of the (UTC) day - Time time = new Time(); - time.set(startDate); - int julianDay = Time.getJulianDay(startDate, time.gmtoff); - return time.setJulianDay(julianDay); - } - - /* Inner class that defines the table contents of the location table */ - public static final class LocationEntry implements BaseColumns { - - public static final Uri CONTENT_URI = - BASE_CONTENT_URI.buildUpon().appendPath(PATH_LOCATION).build(); - - public static final String CONTENT_TYPE = - ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_LOCATION; - public static final String CONTENT_ITEM_TYPE = - ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_LOCATION; - - // Table name - public static final String TABLE_NAME = "location"; - - // The location setting string is what will be sent to openweathermap - // as the location query. - public static final String COLUMN_LOCATION_SETTING = "location_setting"; - - // Human readable location string, provided by the API. Because for styling, - // "Mountain View" is more recognizable than 94043. - public static final String COLUMN_CITY_NAME = "city_name"; - - // In order to uniquely pinpoint the location on the map when we launch the - // map intent, we store the latitude and longitude as returned by openweathermap. - public static final String COLUMN_COORD_LAT = "coord_lat"; - public static final String COLUMN_COORD_LONG = "coord_long"; - - public static Uri buildLocationUri(long id) { - return ContentUris.withAppendedId(CONTENT_URI, id); - } - } - - /* Inner class that defines the table contents of the weather table */ - public static final class WeatherEntry implements BaseColumns { - - public static final Uri CONTENT_URI = - BASE_CONTENT_URI.buildUpon().appendPath(PATH_WEATHER).build(); - - public static final String CONTENT_TYPE = - ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_WEATHER; - public static final String CONTENT_ITEM_TYPE = - ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_WEATHER; - - public static final String TABLE_NAME = "weather"; - - // Column with the foreign key into the location table. - public static final String COLUMN_LOC_KEY = "location_id"; - // Date, stored as long in milliseconds since the epoch - public static final String COLUMN_DATE = "date"; - // Weather id as returned by API, to identify the icon to be used - public static final String COLUMN_WEATHER_ID = "weather_id"; - - // Short description and long description of the weather, as provided by API. - // e.g "clear" vs "sky is clear". - public static final String COLUMN_SHORT_DESC = "short_desc"; - - // Min and max temperatures for the day (stored as floats) - public static final String COLUMN_MIN_TEMP = "min"; - public static final String COLUMN_MAX_TEMP = "max"; - - // Humidity is stored as a float representing percentage - public static final String COLUMN_HUMIDITY = "humidity"; - - // Humidity is stored as a float representing percentage - public static final String COLUMN_PRESSURE = "pressure"; - - // Windspeed is stored as a float representing windspeed mph - public static final String COLUMN_WIND_SPEED = "wind"; - - // Degrees are meteorological degrees (e.g, 0 is north, 180 is south). Stored as floats. - public static final String COLUMN_DEGREES = "degrees"; - - public static Uri buildWeatherUri(long id) { - return ContentUris.withAppendedId(CONTENT_URI, id); - } - - /* - Student: Fill in this buildWeatherLocation function - */ - public static Uri buildWeatherLocation(String locationSetting) { - return null; - } - - public static Uri buildWeatherLocationWithStartDate( - String locationSetting, long startDate) { - long normalizedDate = normalizeDate(startDate); - return CONTENT_URI.buildUpon().appendPath(locationSetting) - .appendQueryParameter(COLUMN_DATE, Long.toString(normalizedDate)).build(); - } - - public static Uri buildWeatherLocationWithDate(String locationSetting, long date) { - return CONTENT_URI.buildUpon().appendPath(locationSetting) - .appendPath(Long.toString(normalizeDate(date))).build(); - } - - public static String getLocationSettingFromUri(Uri uri) { - return uri.getPathSegments().get(1); - } - - public static long getDateFromUri(Uri uri) { - return Long.parseLong(uri.getPathSegments().get(2)); - } - - public static long getStartDateFromUri(Uri uri) { - String dateString = uri.getQueryParameter(COLUMN_DATE); - if (null != dateString && dateString.length() > 0) - return Long.parseLong(dateString); - else - return 0; - } - } -} diff --git a/app/src/main/java/com/example/android/sunshine/app/data/WeatherDbHelper.java b/app/src/main/java/com/example/android/sunshine/app/data/WeatherDbHelper.java deleted file mode 100644 index a933c101f..000000000 --- a/app/src/main/java/com/example/android/sunshine/app/data/WeatherDbHelper.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.example.android.sunshine.app.data; - -import android.content.Context; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; - -import com.example.android.sunshine.app.data.WeatherContract.LocationEntry; -import com.example.android.sunshine.app.data.WeatherContract.WeatherEntry; - -/** - * Manages a local database for weather data. - */ -public class WeatherDbHelper extends SQLiteOpenHelper { - - // If you change the database schema, you must increment the database version. - private static final int DATABASE_VERSION = 2; - - static final String DATABASE_NAME = "weather.db"; - - public WeatherDbHelper(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - } - - @Override - public void onCreate(SQLiteDatabase sqLiteDatabase) { - // Create a table to hold locations. A location consists of the string supplied in the - // location setting, the city name, and the latitude and longitude - final String SQL_CREATE_LOCATION_TABLE = "CREATE TABLE " + LocationEntry.TABLE_NAME + " (" + - LocationEntry._ID + " INTEGER PRIMARY KEY," + - LocationEntry.COLUMN_LOCATION_SETTING + " TEXT UNIQUE NOT NULL, " + - LocationEntry.COLUMN_CITY_NAME + " TEXT NOT NULL, " + - LocationEntry.COLUMN_COORD_LAT + " REAL NOT NULL, " + - LocationEntry.COLUMN_COORD_LONG + " REAL NOT NULL " + - " );"; - - final String SQL_CREATE_WEATHER_TABLE = "CREATE TABLE " + WeatherEntry.TABLE_NAME + " (" + - // Why AutoIncrement here, and not above? - // Unique keys will be auto-generated in either case. But for weather - // forecasting, it's reasonable to assume the user will want information - // for a certain date and all dates *following*, so the forecast data - // should be sorted accordingly. - WeatherEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + - - // the ID of the location entry associated with this weather data - WeatherEntry.COLUMN_LOC_KEY + " INTEGER NOT NULL, " + - WeatherEntry.COLUMN_DATE + " INTEGER NOT NULL, " + - WeatherEntry.COLUMN_SHORT_DESC + " TEXT NOT NULL, " + - WeatherEntry.COLUMN_WEATHER_ID + " INTEGER NOT NULL," + - - WeatherEntry.COLUMN_MIN_TEMP + " REAL NOT NULL, " + - WeatherEntry.COLUMN_MAX_TEMP + " REAL NOT NULL, " + - - WeatherEntry.COLUMN_HUMIDITY + " REAL NOT NULL, " + - WeatherEntry.COLUMN_PRESSURE + " REAL NOT NULL, " + - WeatherEntry.COLUMN_WIND_SPEED + " REAL NOT NULL, " + - WeatherEntry.COLUMN_DEGREES + " REAL NOT NULL, " + - - // Set up the location column as a foreign key to location table. - " FOREIGN KEY (" + WeatherEntry.COLUMN_LOC_KEY + ") REFERENCES " + - LocationEntry.TABLE_NAME + " (" + LocationEntry._ID + "), " + - - // To assure the application have just one weather entry per day - // per location, it's created a UNIQUE constraint with REPLACE strategy - " UNIQUE (" + WeatherEntry.COLUMN_DATE + ", " + - WeatherEntry.COLUMN_LOC_KEY + ") ON CONFLICT REPLACE);"; - - sqLiteDatabase.execSQL(SQL_CREATE_LOCATION_TABLE); - sqLiteDatabase.execSQL(SQL_CREATE_WEATHER_TABLE); - } - - @Override - public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) { - // This database is only a cache for online data, so its upgrade policy is - // to simply to discard the data and start over - // Note that this only fires if you change the version number for your database. - // It does NOT depend on the version number for your application. - // If you want to update the schema without wiping data, commenting out the next 2 lines - // should be your top priority before modifying this method. - sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + LocationEntry.TABLE_NAME); - sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + WeatherEntry.TABLE_NAME); - onCreate(sqLiteDatabase); - } -} diff --git a/app/src/main/res/drawable-hdpi/ic_launcher.png b/app/src/main/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index 786258ade37b68d62003460bbd3d851eac1bc951..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4125 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 bci;Fw9!Ch46F6Ci00000NkvXXu0mjfvLoZV diff --git a/app/src/main/res/drawable-mdpi/ic_launcher.png b/app/src/main/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index f415afeb38b128a79e5185c733d88a40907c821a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2350 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 diff --git a/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxhdpi/ic_launcher.png deleted file mode 100644 index b37fe2bfb11da462fa5dd7f671e28d8805427e1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10132 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 - diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index b69c03abf..000000000 --- a/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/app/src/main/res/layout/fragment_detail.xml b/app/src/main/res/layout/fragment_detail.xml deleted file mode 100644 index 70bef316d..000000000 --- a/app/src/main/res/layout/fragment_detail.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml deleted file mode 100644 index 372b60d63..000000000 --- a/app/src/main/res/layout/fragment_main.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/layout/list_item_forecast.xml b/app/src/main/res/layout/list_item_forecast.xml deleted file mode 100644 index 965bd5714..000000000 --- a/app/src/main/res/layout/list_item_forecast.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - \ No newline at end of file diff --git a/app/src/main/res/menu/detail.xml b/app/src/main/res/menu/detail.xml deleted file mode 100644 index 865ac0539..000000000 --- a/app/src/main/res/menu/detail.xml +++ /dev/null @@ -1,9 +0,0 @@ -

- - diff --git a/app/src/main/res/menu/detailfragment.xml b/app/src/main/res/menu/detailfragment.xml deleted file mode 100644 index bfef05f66..000000000 --- a/app/src/main/res/menu/detailfragment.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/app/src/main/res/menu/forecastfragment.xml b/app/src/main/res/menu/forecastfragment.xml deleted file mode 100644 index 50bd1256d..000000000 --- a/app/src/main/res/menu/forecastfragment.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml deleted file mode 100644 index 87d2ed662..000000000 --- a/app/src/main/res/menu/main.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml deleted file mode 100644 index 63fc81644..000000000 --- a/app/src/main/res/values-w820dp/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - 64dp - diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml deleted file mode 100644 index f752cb333..000000000 --- a/app/src/main/res/values/arrays.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - @string/pref_units_label_metric - @string/pref_units_label_imperial - - - - @string/pref_units_metric - @string/pref_units_imperial - - \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml deleted file mode 100644 index 47c822467..000000000 --- a/app/src/main/res/values/dimens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 16dp - 16dp - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml deleted file mode 100644 index 14ae616c2..000000000 --- a/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - Sunshine - - - Settings - Map Location - Share - - - Refresh - Details - Settings - - - Location - - - location - - - 94043 - - - Temperature Units - - - Metric - - - Imperial - - - units - - - metric - - - imperial - - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml deleted file mode 100644 index 766ab9930..000000000 --- a/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml deleted file mode 100644 index 212b70ad3..000000000 --- a/app/src/main/res/xml/pref_general.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 6356aabdc..000000000 --- a/build.gradle +++ /dev/null @@ -1,19 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:1.0.0' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - jcenter() - } -} diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index 1d3591c8a..000000000 --- a/gradle.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 8c0fb64a8698b08ecc4158d828ca593c4928e9dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49896 zcmagFb986H(k`5d^NVfUwr$(C?M#x1ZQHiZiEVpg+jrjgoQrerx!>1o_ul)D>ebz~ zs=Mmxr&>W81QY-S1PKWQ%N-;H^tS;2*XwVA`dej1RRn1z<;3VgfE4~kaG`A%QSPsR z#ovnZe+tS9%1MfeDyz`RirvdjPRK~p(#^q2(^5@O&NM19EHdvN-A&StN>0g6QA^VN z0Gx%Gq#PD$QMRFzmK+utjS^Y1F0e8&u&^=w5K<;4Rz|i3A=o|IKLY+g`iK6vfr9?+ z-`>gmU&i?FGSL5&F?TXFu`&Js6h;15QFkXp2M1H9|Eq~bpov-GU(uz%mH0n55wUl- zv#~ccAz`F5wlQ>e_KlJS3@{)B?^v*EQM=IxLa&76^y51a((wq|2-`qON>+4dLc{Oo z51}}o^Zen(oAjxDK7b++9_Yg`67p$bPo3~BCpGM7uAWmvIhWc5Gi+gQZ|Pwa-Gll@<1xmcPy z|NZmu6m)g5Ftu~BG&Xdxclw7Cij{xbBMBn-LMII#Slp`AElb&2^Hw+w>(3crLH!;I zN+Vk$D+wP1#^!MDCiad@vM>H#6+`Ct#~6VHL4lzmy;lSdk>`z6)=>Wh15Q2)dQtGqvn0vJU@+(B5{MUc*qs4!T+V=q=wy)<6$~ z!G>e_4dN@lGeF_$q9`Ju6Ncb*x?O7=l{anm7Eahuj_6lA{*#Gv*TaJclevPVbbVYu z(NY?5q+xxbO6%g1xF0r@Ix8fJ~u)VRUp`S%&rN$&e!Od`~s+64J z5*)*WSi*i{k%JjMSIN#X;jC{HG$-^iX+5f5BGOIHWAl*%15Z#!xntpk($-EGKCzKa zT7{siZ9;4TICsWQ$pu&wKZQTCvpI$Xvzwxoi+XkkpeE&&kFb!B?h2hi%^YlXt|-@5 zHJ~%AN!g_^tmn1?HSm^|gCE#!GRtK2(L{9pL#hp0xh zME}|DB>(5)`iE7CM)&_+S}-Bslc#@B5W4_+k4Cp$l>iVyg$KP>CN?SVGZ(&02>iZK zB<^HP$g$Lq*L$BWd?2(F?-MUbNWTJVQdW7$#8a|k_30#vHAD1Z{c#p;bETk0VnU5A zBgLe2HFJ3032$G<`m*OB!KM$*sdM20jm)It5OSru@tXpK5LT>#8)N!*skNu1$TpIw zufjjdp#lyH5bZ%|Iuo|iu9vG1HrIVWLH>278xo>aVBkPN3V$~!=KnlXQ4eDqS7%E% zQ!z^$Q$b^6Q)g#cLpwur(|<0gWHo6A6jc;n`t(V9T;LzTAU{IAu*uEQ%Ort1k+Kn+f_N`9|bxYC+~Z1 zCC1UCWv*Orx$_@ydv9mIe(liLfOr7mhbV@tKw{6)q^1DH1nmvZ0cj215R<~&I<4S| zgnr;9Cdjqpz#o8i0CQjtl`}{c*P)aSdH|abxGdrR)-3z+02-eX(k*B)Uqv6~^nh** z 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 \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index aec99730b..000000000 --- a/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index e7b4def49..000000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':app'