diff --git a/.gitignore b/.gitignore index c35071df..7fa51e9c 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ gen/ # Can explicitly add if we want, but shouldn't do so blindly. Licenses, bloat, etc. /libs - # Build stuff (auto-generated by android update project ...) build.xml ant.properties diff --git a/app/build.gradle b/app/build.gradle index 5db63e02..0dcc58a7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,4 @@ apply plugin: 'com.android.application' -apply plugin: 'com.google.gms.google-services' android { compileSdkVersion 21 @@ -28,5 +27,8 @@ dependencies { compile 'com.github.bumptech.glide:glide:3.5.2' compile 'com.android.support:appcompat-v7:21.0.2' compile 'com.android.support:support-annotations:22.0.0' - compile 'com.google.android.gms:play-services-gcm:8.3.0' -} + compile 'com.google.android.gms:play-services-base:10.0.1' + compile 'com.google.firebase:firebase-core:10.0.1' + compile 'com.google.firebase:firebase-messaging:10.0.1'} + +apply plugin: 'com.google.gms.google-services' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 29929767..24d066c7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -32,13 +32,6 @@ - - - - - - - - - - - - - - + + android:name=".firebase.MyFirebaseMessagingService"> - + + + android:name=".firebase.MyFirebaseInstanceIDService"> - + - - 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 index 776e8925..f573a3a5 100644 --- a/app/src/main/java/com/example/android/sunshine/app/MainActivity.java +++ b/app/src/main/java/com/example/android/sunshine/app/MainActivity.java @@ -16,20 +16,18 @@ 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; -import com.example.android.sunshine.app.gcm.RegistrationIntentService; import com.example.android.sunshine.app.sync.SunshineSyncAdapter; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; + public class MainActivity extends ActionBarActivity implements ForecastFragment.Callback { private final String LOG_TAG = MainActivity.class.getSimpleName(); @@ -43,6 +41,7 @@ public class MainActivity extends ActionBarActivity implements ForecastFragment. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mLocation = Utility.getPreferredLocation(this); setContentView(R.layout.activity_main); @@ -70,22 +69,10 @@ protected void onCreate(Bundle savedInstanceState) { SunshineSyncAdapter.initializeSyncAdapter(this); - // If Google Play Services is up to date, we'll want to register GCM. If it is not, we'll - // skip the registration and this device will not receive any downstream messages from - // our fake server. Because weather alerts are not a core feature of the app, this should - // not affect the behavior of the app, from a user perspective. - if (checkPlayServices()) { - // Because this is the initial creation of the app, we'll want to be certain we have - // a token. If we do not, then we will start the IntentService that will register this - // application with GCM. - SharedPreferences sharedPreferences = - PreferenceManager.getDefaultSharedPreferences(this); - boolean sentToken = sharedPreferences.getBoolean(SENT_TOKEN_TO_SERVER, false); - if (!sentToken) { - Intent intent = new Intent(this, RegistrationIntentService.class); - startService(intent); - } - } + // For informing user of Google Play Services availability + // FCM now auto registers token + checkPlayServices(); + } @Override diff --git a/app/src/main/java/com/example/android/sunshine/app/firebase/MyFirebaseInstanceIDService.java b/app/src/main/java/com/example/android/sunshine/app/firebase/MyFirebaseInstanceIDService.java new file mode 100644 index 00000000..375b57ba --- /dev/null +++ b/app/src/main/java/com/example/android/sunshine/app/firebase/MyFirebaseInstanceIDService.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 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.firebase; + +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; + +import com.example.android.sunshine.app.MainActivity; +import com.google.firebase.iid.FirebaseInstanceId; +import com.google.firebase.iid.FirebaseInstanceIdService; + +public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService{ + private static final String TAG = "FcmInstanceIdService"; + + /** + * Called if InstanceID token is updated. This may occur if the security of + * the previous token had been compromised. Note that this is also called + * when the InstanceID token is initially generated, so this is where + * you retrieve the token. + */ + @Override + public void onTokenRefresh() { + + Log.w(TAG,"onTokenRefresh of instance id service!"); + + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + + String token = FirebaseInstanceId.getInstance().getToken(); + sendRegistrationToServer(token); + + // You should store a boolean that indicates whether the generated token has been + // sent to your server. If the boolean is false, send the token to your server, + // otherwise your server should have already received the token. + sharedPreferences.edit().putBoolean(MainActivity.SENT_TOKEN_TO_SERVER, true).apply(); + } + + /** + * Normally, you would want to persist the registration to third-party servers. Because we do + * not have a server, and are faking it with a website, you'll want to log the token instead. + * That way you can see the value in logcat, and note it for future use in the website. + * + * @param token The new token. + */ + private void sendRegistrationToServer(String token) { + Log.i(TAG, "FCM Registration Token: " + token); + } +} diff --git a/app/src/main/java/com/example/android/sunshine/app/gcm/MyGcmListenerService.java b/app/src/main/java/com/example/android/sunshine/app/firebase/MyFirebaseMessagingService.java similarity index 79% rename from app/src/main/java/com/example/android/sunshine/app/gcm/MyGcmListenerService.java rename to app/src/main/java/com/example/android/sunshine/app/firebase/MyFirebaseMessagingService.java index ff5921ec..3e93da93 100644 --- a/app/src/main/java/com/example/android/sunshine/app/gcm/MyGcmListenerService.java +++ b/app/src/main/java/com/example/android/sunshine/app/firebase/MyFirebaseMessagingService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 The Android Open Source Project + * Copyright (C) 2016 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.example.android.sunshine.app.gcm; +package com.example.android.sunshine.app.firebase; import android.app.NotificationManager; import android.app.PendingIntent; @@ -22,18 +22,19 @@ import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.os.Bundle; import android.support.v4.app.NotificationCompat; import android.util.Log; import android.widget.Toast; import com.example.android.sunshine.app.MainActivity; import com.example.android.sunshine.app.R; -import com.google.android.gms.gcm.GcmListenerService; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; -public class MyGcmListenerService extends GcmListenerService { +import java.util.Map; - private static final String TAG = "MyGcmListenerService"; +public class MyFirebaseMessagingService extends FirebaseMessagingService { + private static final String TAG = "MyFcmMessagingService"; private static final String EXTRA_DATA = "data"; private static final String EXTRA_WEATHER = "weather"; @@ -44,12 +45,16 @@ public class MyGcmListenerService extends GcmListenerService { /** * Called when message is received. * - * @param from SenderID of the sender. - * @param data Data bundle containing message data as key/value pairs. - * For Set of keys use data.keySet(). + * @param message RemoteMessage sent from server - use getData() for key/value pairs + * & getFrom() for sender */ + @Override - public void onMessageReceived(String from, Bundle data) { + public void onMessageReceived(RemoteMessage message) { + Log.w(TAG,"Message Received!"); + Map data = message.getData(); + String from = message.getFrom(); + // Time to unparcel the bundle! if (!data.isEmpty()) { // TODO: gcm_default sender ID comes from the API console @@ -60,13 +65,13 @@ public void onMessageReceived(String from, Bundle data) { // Not a bad idea to check that the message is coming from your server. if ((senderId).equals(from)) { // Process message and then post a notification of the received message. - String weather = data.getString(EXTRA_WEATHER); - String location = data.getString(EXTRA_LOCATION); + String weather = data.get(EXTRA_WEATHER); + String location = data.get(EXTRA_LOCATION); String alert = - String.format(getString(R.string.gcm_weather_alert), weather, location); + String.format(getString(R.string.fcm_weather_alert), weather, location); sendNotification(alert); } - Log.i(TAG, "Received: " + data.toString()); + Log.i(TAG, "Received: " + message.toString()); } } @@ -98,4 +103,4 @@ private void sendNotification(String message) { mBuilder.setContentIntent(contentIntent); mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build()); } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/android/sunshine/app/gcm/MyInstanceIDListenerService.java b/app/src/main/java/com/example/android/sunshine/app/gcm/MyInstanceIDListenerService.java deleted file mode 100644 index 862bc476..00000000 --- a/app/src/main/java/com/example/android/sunshine/app/gcm/MyInstanceIDListenerService.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2015 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.gcm; - -import android.content.Intent; -import com.google.android.gms.iid.InstanceIDListenerService; - -public class MyInstanceIDListenerService extends InstanceIDListenerService { - private static final String TAG = "MyInstanceIDLS"; - - /** - * Called if InstanceID token is updated. This may occur if the security of - * the previous token had been compromised. This call is initiated by the - * InstanceID provider. - */ - @Override - public void onTokenRefresh() { - // Fetch updated Instance ID token. - Intent intent = new Intent(this, RegistrationIntentService.class); - startService(intent); - } -} diff --git a/app/src/main/java/com/example/android/sunshine/app/gcm/RegistrationIntentService.java b/app/src/main/java/com/example/android/sunshine/app/gcm/RegistrationIntentService.java deleted file mode 100644 index fae7157f..00000000 --- a/app/src/main/java/com/example/android/sunshine/app/gcm/RegistrationIntentService.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2015 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.gcm; - -import android.app.IntentService; -import android.content.Intent; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import android.util.Log; -import android.widget.Toast; - -import com.example.android.sunshine.app.MainActivity; -import com.example.android.sunshine.app.R; -import com.google.android.gms.gcm.GoogleCloudMessaging; -import com.google.android.gms.iid.InstanceID; - - -public class RegistrationIntentService extends IntentService { - private static final String TAG = "RegIntentService"; - - public RegistrationIntentService() { - super(TAG); - } - - @Override - protected void onHandleIntent(Intent intent) { - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); - - try { - // In the (unlikely) event that multiple refresh operations occur simultaneously, - // ensure that they are processed sequentially. - synchronized (TAG) { - // Initially this call goes out to the network to retrieve the token, subsequent calls - // are local. - InstanceID instanceID = InstanceID.getInstance(this); - - // TODO: gcm_default sender ID comes from the API console - String senderId = getString(R.string.gcm_defaultSenderId); - if ( senderId.length() != 0 ) { - String token = instanceID.getToken(senderId, - GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); - sendRegistrationToServer(token); - } - - // You should store a boolean that indicates whether the generated token has been - // sent to your server. If the boolean is false, send the token to your server, - // otherwise your server should have already received the token. - sharedPreferences.edit().putBoolean(MainActivity.SENT_TOKEN_TO_SERVER, true).apply(); - } - } catch (Exception e) { - Log.d(TAG, "Failed to complete token refresh", e); - - // If an exception happens while fetching the new token or updating our registration data - // on a third-party server, this ensures that we'll attempt the update at a later time. - sharedPreferences.edit().putBoolean(MainActivity.SENT_TOKEN_TO_SERVER, false).apply(); - } - } - - /** - * Normally, you would want to persist the registration to third-party servers. Because we do - * not have a server, and are faking it with a website, you'll want to log the token instead. - * That way you can see the value in logcat, and note it for future use in the website. - * - * @param token The new token. - */ - private void sendRegistrationToServer(String token) { - Log.i(TAG, "GCM Registration Token: " + token); - } -} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index da211db9..3f853072 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -207,6 +207,6 @@ Unknown (%1$s) - Heads up: %1$s in %2$s! + Heads up: %1$s in %2$s! diff --git a/build.gradle b/build.gradle index 7ed1141a..2a61024f 100644 --- a/build.gradle +++ b/build.gradle @@ -5,8 +5,8 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.0.0' - classpath 'com.google.gms:google-services:1.5.0-beta2' + classpath 'com.android.tools.build:gradle:2.2.2' + classpath 'com.google.gms:google-services:3.0.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0c71e760..c4df1d80 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Apr 10 15:27:10 PDT 2013 +#Wed Nov 30 14:18:46 PST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip