From 777dfc36609c0a53ffdd749412138374e4ba2431 Mon Sep 17 00:00:00 2001 From: Matti Jokitulppo Date: Sun, 9 Apr 2017 18:02:51 +0300 Subject: [PATCH 1/9] Add FireBase service, update Google dependancies --- app/build.gradle | 11 +++--- .../achso/browsing/DetailActivity.java | 34 +++++++++++-------- build.gradle | 2 +- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index fcdd59a5..b7f6fc74 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -84,10 +84,13 @@ dependencies { compile 'org.florescu.android.rangeseekbar:rangeseekbar-library:0.3.0' // Google Play Services APIs - compile 'com.google.android.gms:play-services-base:8.1.0' - compile 'com.google.android.gms:play-services-maps:8.1.0' - compile 'com.google.android.gms:play-services-location:8.1.0' - compile 'com.google.android.gms:play-services-analytics:8.1.0' + compile 'com.google.android.gms:play-services-base:10.2.1' + compile 'com.google.android.gms:play-services-maps:10.2.1' + compile 'com.google.android.gms:play-services-location:10.2.1' + compile 'com.google.android.gms:play-services-analytics:10.2.1' + + // Push notifications + compile 'com.google.firebase:firebase-messaging:10.2.1' // OAuth2 library for OpenID Connect compile('com.google.oauth-client:google-oauth-client:1.19.0') { diff --git a/app/src/main/java/fi/aalto/legroup/achso/browsing/DetailActivity.java b/app/src/main/java/fi/aalto/legroup/achso/browsing/DetailActivity.java index d2429494..0817d1b0 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/browsing/DetailActivity.java +++ b/app/src/main/java/fi/aalto/legroup/achso/browsing/DetailActivity.java @@ -25,6 +25,7 @@ import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CircleOptions; @@ -143,27 +144,30 @@ public void onCreate(Bundle savedInstanceState) { SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapFragment); - Location location = video.getLocation(); + final Location location = video.getLocation(); if (location != null) { - LatLng position = new LatLng(location.getLatitude(), location.getLongitude()); - - GoogleMap map = mapFragment.getMap(); + mapFragment.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(GoogleMap googleMap) { + LatLng position = new LatLng(location.getLatitude(), location.getLongitude()); - map.addCircle(new CircleOptions() - .center(position) - .radius(location.getAccuracy()) - .strokeWidth(3.0f) - .strokeColor(Color.WHITE) - .fillColor(Color.parseColor("#80ffffff"))); + googleMap.addCircle(new CircleOptions() + .center(position) + .radius(location.getAccuracy()) + .strokeWidth(3.0f) + .strokeColor(Color.WHITE) + .fillColor(Color.parseColor("#80ffffff"))); - map.addMarker(new MarkerOptions() - .position(position) - .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))); + googleMap.addMarker(new MarkerOptions() + .position(position) + .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))); - map.moveCamera(CameraUpdateFactory.newLatLngZoom(position, 14.5f)); + googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(position, 14.5f)); - findViewById(R.id.unknownLocationText).setVisibility(View.GONE); + findViewById(R.id.unknownLocationText).setVisibility(View.GONE); + } + }); } initializeAddQRButton(); diff --git a/build.gradle b/build.gradle index c6f2f500..072e693a 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.android.tools.build:gradle:2.3.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From 3de9db6430beb353973952b74362e14239e98e0f Mon Sep 17 00:00:00 2001 From: Matti Jokitulppo Date: Sun, 9 Apr 2017 18:46:01 +0300 Subject: [PATCH 2/9] Some initial work on Firebase push notifications --- app/src/main/AndroidManifest.xml | 8 +++- .../java/fi/aalto/legroup/achso/app/App.java | 47 +++++++++++++++++++ .../achso/storage/remote/VideoHost.java | 4 ++ .../remote/strategies/AchRailsStrategy.java | 36 ++++++++++++++ .../AchsoFirebaseInstanceIdService.java | 15 ++++++ 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseInstanceIdService.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c5d66253..fb74350a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -138,7 +138,13 @@ android:label="@string/choose_account" android:parentActivityName=".browsing.BrowserActivity" /> - + + + + + + diff --git a/app/src/main/java/fi/aalto/legroup/achso/app/App.java b/app/src/main/java/fi/aalto/legroup/achso/app/App.java index 88deeff0..a17e2734 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/app/App.java +++ b/app/src/main/java/fi/aalto/legroup/achso/app/App.java @@ -12,11 +12,18 @@ import android.widget.Toast; import com.google.android.gms.analytics.GoogleAnalytics; +import com.google.firebase.FirebaseApp; +import com.google.firebase.iid.FirebaseInstanceId; +import com.google.firebase.iid.FirebaseInstanceIdService; import com.rollbar.android.Rollbar; import com.squareup.okhttp.OkHttpClient; import com.squareup.otto.Bus; +import com.squareup.otto.Subscribe; + +import org.json.JSONException; import java.io.File; +import java.io.IOException; import java.security.GeneralSecurityException; import fi.aalto.legroup.achso.BuildConfig; @@ -24,6 +31,7 @@ import fi.aalto.legroup.achso.authentication.AuthenticatedHttpClient; import fi.aalto.legroup.achso.authentication.LoginManager; import fi.aalto.legroup.achso.authentication.LoginRequestEvent; +import fi.aalto.legroup.achso.authentication.LoginStateEvent; import fi.aalto.legroup.achso.authentication.OIDCConfig; import fi.aalto.legroup.achso.authoring.ExportHelper; import fi.aalto.legroup.achso.authoring.LocationManager; @@ -79,6 +87,7 @@ public void onCreate() { setupPreferences(); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); + layersBoxUrl = readLayersBoxUrl(); usePublicLayersBox = preferences.getBoolean(AppPreferences.USE_PUBLIC_LAYERS_BOX, false); publicLayersBoxUrl = Uri.parse(getString(R.string.publicLayersBoxUrl)); @@ -139,6 +148,7 @@ public void onCreate() { updateOIDCTokens(this); + bus.register(this); bus.post(new LoginRequestEvent(LoginRequestEvent.Type.LOGIN)); // Trim the caches asynchronously @@ -172,6 +182,43 @@ public void tokensRetrieved() { } } + public static void tokenUpdated(String notificationToken) { + if (loginManager.isLoggedIn()) { + App.registerToken(notificationToken); + } + } + + @Subscribe + public static void onLoginStateEvent(LoginStateEvent event) { + String token = FirebaseInstanceId.getInstance().getToken(); + + if (event.getState() == LoginManager.LoginState.LOGGED_IN) { + App.registerToken(token); + } else if (event.getState() == LoginManager.LoginState.LOGGING_OUT) { + App.unregisterToken(token); + } + } + + private static void registerToken(String notificationToken) { + try { + achRails.registerToken(notificationToken); + } catch (JSONException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void unregisterToken(String notificationToken) { + try { + achRails.unregisterToken(notificationToken); + } catch (JSONException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + public static Uri getLayersBoxUrl() { if (usePublicLayersBox) { return publicLayersBoxUrl; diff --git a/app/src/main/java/fi/aalto/legroup/achso/storage/remote/VideoHost.java b/app/src/main/java/fi/aalto/legroup/achso/storage/remote/VideoHost.java index 3d0da60c..12736050 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/storage/remote/VideoHost.java +++ b/app/src/main/java/fi/aalto/legroup/achso/storage/remote/VideoHost.java @@ -57,4 +57,8 @@ public interface VideoHost { * Finds a video by the video source uri. */ public Video findVideoByVideoUri(Uri videoUri) throws IOException; + + public void registerToken(String notificationToken) throws JSONException, IOException; + + public void unregisterToken(String notificationToken) throws JSONException, IOException; } diff --git a/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java b/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java index f523f328..0bacbcfe 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java +++ b/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java @@ -60,6 +60,7 @@ Request.Builder buildVideosRequest() { return new Request.Builder() .url(endpointUrl.buildUpon().appendPath("videos.json").toString()); } + Request.Builder buildVideosRequest(UUID id) { return new Request.Builder() .url(endpointUrl.buildUpon() @@ -161,6 +162,41 @@ public void makeVideoPrivate(UUID videoId) throws IOException, JSONException { Response response = executeRequest(request); } + + @Override + public void registerToken(String notificationToken) throws JSONException, IOException { + JSONObject obj = new JSONObject(); + obj.put("token", notificationToken); + + RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), obj.toString()); + + Request request = new Request.Builder() + .url(endpointUrl.buildUpon() + .appendPath("notifications") + .appendPath("register") + .toString()) + .put(body).build(); + + executeRequest(request); + } + + @Override + public void unregisterToken(String notificationToken) throws JSONException, IOException { + JSONObject obj = new JSONObject(); + obj.put("token", notificationToken); + + RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), obj.toString()); + + Request request = new Request.Builder() + .url(endpointUrl.buildUpon() + .appendPath("notifications") + .appendPath("undelete") + .toString()) + .put(body).build(); + + executeRequest(request); + } + @Override public Video downloadVideoManifest(UUID id) throws IOException { diff --git a/app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseInstanceIdService.java b/app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseInstanceIdService.java new file mode 100644 index 00000000..27233f78 --- /dev/null +++ b/app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseInstanceIdService.java @@ -0,0 +1,15 @@ +package fi.aalto.legroup.achso.utilities; +import com.google.firebase.iid.FirebaseInstanceId; +import com.google.firebase.iid.FirebaseInstanceIdService; + +import fi.aalto.legroup.achso.app.App; + +public class AchsoFirebaseInstanceIdService extends FirebaseInstanceIdService { + + @Override + public void onTokenRefresh() { + String refreshedToken = FirebaseInstanceId.getInstance().getToken(); + + App.tokenUpdated(refreshedToken); + } +} From f5bd383e75d8d7abfe0aa7d9fc234bf3e62416f1 Mon Sep 17 00:00:00 2001 From: Matti Jokitulppo Date: Sun, 9 Apr 2017 19:11:05 +0300 Subject: [PATCH 3/9] Connect project to Firebase --- .gitignore | 1 + app/build.gradle | 6 ++++++ build.gradle | 1 + 3 files changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index f487361a..334e15a9 100644 --- a/.gitignore +++ b/.gitignore @@ -123,3 +123,4 @@ manifest-merger-release-report.txt # Android Studio heap captures captures/ +app/google-services.json diff --git a/app/build.gradle b/app/build.gradle index b7f6fc74..b4601305 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,6 +7,10 @@ android { useLibrary 'org.apache.http.legacy' + configurations { + compile.exclude group: "org.apache.httpcomponents", module: "httpclient" + } + defaultConfig { applicationId 'fi.aalto.legroup.achso' minSdkVersion 16 @@ -132,3 +136,5 @@ dependencies { // Decrypting the Layers Box URL compile 'fi.aalto.legroup:cryptohelper:0.1.0' } + +// apply plugin: 'com.google.gms.google-services' diff --git a/build.gradle b/build.gradle index 072e693a..e118f6a3 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:2.3.1' + 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 From b2447512bfa603da279c61f68cadd005de16fef6 Mon Sep 17 00:00:00 2001 From: Matti Jokitulppo Date: Sun, 9 Apr 2017 19:26:21 +0300 Subject: [PATCH 4/9] More work on push notification registering --- app/build.gradle | 2 +- .../java/fi/aalto/legroup/achso/app/App.java | 2 ++ .../AuthenticatedHttpClient.java | 11 +++++++++ .../remote/strategies/AchRailsStrategy.java | 13 ++++++++--- .../achso/utilities/EmptyCallback.java | 23 +++++++++++++++++++ 5 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/fi/aalto/legroup/achso/utilities/EmptyCallback.java diff --git a/app/build.gradle b/app/build.gradle index b4601305..b3caee18 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -137,4 +137,4 @@ dependencies { compile 'fi.aalto.legroup:cryptohelper:0.1.0' } -// apply plugin: 'com.google.gms.google-services' +apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/app/src/main/java/fi/aalto/legroup/achso/app/App.java b/app/src/main/java/fi/aalto/legroup/achso/app/App.java index a17e2734..5c43cc02 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/app/App.java +++ b/app/src/main/java/fi/aalto/legroup/achso/app/App.java @@ -192,6 +192,8 @@ public static void tokenUpdated(String notificationToken) { public static void onLoginStateEvent(LoginStateEvent event) { String token = FirebaseInstanceId.getInstance().getToken(); + if (token == null) return; + if (event.getState() == LoginManager.LoginState.LOGGED_IN) { App.registerToken(token); } else if (event.getState() == LoginManager.LoginState.LOGGING_OUT) { diff --git a/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java b/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java index e85f88be..d173751b 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java +++ b/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java @@ -5,6 +5,7 @@ import android.content.Context; import android.util.Log; +import com.squareup.okhttp.Callback; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; @@ -67,6 +68,16 @@ public Response execute(Request request, Account account, boolean doRetry) throw return response; } + public void enqueue(Request request, Account account, Callback cb) { + AccountManager accountManager = AccountManager.get(context); + + String token = getBearerToken(account); + + request = request.newBuilder().header("Authorization", "Bearer " + token).build(); + + httpClient.newCall(request).enqueue(cb); + } + public boolean accessDenied(Response response) { int code = response.code(); diff --git a/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java b/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java index 0bacbcfe..f653a30a 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java +++ b/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java @@ -3,6 +3,7 @@ import android.accounts.Account; import android.net.Uri; +import com.squareup.okhttp.Callback; import com.squareup.okhttp.FormEncodingBuilder; import com.squareup.okhttp.MediaType; import com.squareup.okhttp.Request; @@ -27,6 +28,7 @@ import fi.aalto.legroup.achso.entities.serialization.json.JsonSerializable; import fi.aalto.legroup.achso.entities.serialization.json.JsonSerializer; import fi.aalto.legroup.achso.storage.remote.VideoHost; +import fi.aalto.legroup.achso.utilities.EmptyCallback; import okio.BufferedSink; import okio.Okio; @@ -102,6 +104,11 @@ private Response validateResponse(Response response) throws IOException { return response; } + private void executeRequestAsync(Request request, Callback cb) throws IOException { + Account account = App.loginManager.getAccount(); + App.authenticatedHttpClient.enqueue(request, account, cb); + } + private Response executeRequest(Request request) throws IOException { return validateResponse(executeRequestNoFail(request)); } @@ -177,7 +184,7 @@ public void registerToken(String notificationToken) throws JSONException, IOExce .toString()) .put(body).build(); - executeRequest(request); + executeRequestAsync(request, new EmptyCallback()); } @Override @@ -190,11 +197,11 @@ public void unregisterToken(String notificationToken) throws JSONException, IOEx Request request = new Request.Builder() .url(endpointUrl.buildUpon() .appendPath("notifications") - .appendPath("undelete") + .appendPath("unregister") .toString()) .put(body).build(); - executeRequest(request); + executeRequestAsync(request, new EmptyCallback()); } @Override diff --git a/app/src/main/java/fi/aalto/legroup/achso/utilities/EmptyCallback.java b/app/src/main/java/fi/aalto/legroup/achso/utilities/EmptyCallback.java new file mode 100644 index 00000000..b53aa5fb --- /dev/null +++ b/app/src/main/java/fi/aalto/legroup/achso/utilities/EmptyCallback.java @@ -0,0 +1,23 @@ +package fi.aalto.legroup.achso.utilities; + +import com.squareup.okhttp.Callback; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; + +import java.io.IOException; + +/** + * Created by mat on 09/04/2017. + */ + +public class EmptyCallback implements Callback { + @Override + public void onFailure(Request request, IOException e) { + + } + + @Override + public void onResponse(Response response) throws IOException { + // System.out.println(response); + } +} From 8476f74b9708589240a2712a124d42b539fb2007 Mon Sep 17 00:00:00 2001 From: Matti Jokitulppo Date: Tue, 18 Apr 2017 21:34:49 +0300 Subject: [PATCH 5/9] Send LOGGING_OUT event correctly --- .../achso/authentication/AuthenticatedHttpClient.java | 2 -- .../fi/aalto/legroup/achso/authentication/LoginManager.java | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java b/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java index d173751b..e5bb24f9 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java +++ b/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java @@ -69,8 +69,6 @@ public Response execute(Request request, Account account, boolean doRetry) throw } public void enqueue(Request request, Account account, Callback cb) { - AccountManager accountManager = AccountManager.get(context); - String token = getBearerToken(account); request = request.newBuilder().header("Authorization", "Bearer " + token).build(); diff --git a/app/src/main/java/fi/aalto/legroup/achso/authentication/LoginManager.java b/app/src/main/java/fi/aalto/legroup/achso/authentication/LoginManager.java index 59ed3644..91d77878 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/authentication/LoginManager.java +++ b/app/src/main/java/fi/aalto/legroup/achso/authentication/LoginManager.java @@ -92,6 +92,8 @@ public void login(Account account) { * Logs out from the account and disables auto-login. Use this if the user manually logs out. */ public void logoutExplicitly() { + setState(LoginState.LOGGING_OUT, false); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); prefs.edit() @@ -106,6 +108,10 @@ public void logoutExplicitly() { * automatic (e.g. connectivity lost) and not initiated by the user. */ public void logout() { + if (getState() != LoginState.LOGGING_OUT) { + setState(LoginState.LOGGING_OUT, false); + } + setState(LoginState.LOGGED_OUT, true); account = null; user = null; From b99fa7d2f74745b17ca0c6e6ea796518008a24fe Mon Sep 17 00:00:00 2001 From: Matti Jokitulppo Date: Tue, 18 Apr 2017 22:47:49 +0300 Subject: [PATCH 6/9] Enable notifications when the app is turned on --- app/src/main/AndroidManifest.xml | 7 +++ .../AchsoFirebaseMessagingService.java | 57 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseMessagingService.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fb74350a..8cd9e933 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -138,6 +138,13 @@ android:label="@string/choose_account" android:parentActivityName=".browsing.BrowserActivity" /> + + + + + + diff --git a/app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseMessagingService.java b/app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseMessagingService.java new file mode 100644 index 00000000..c159f025 --- /dev/null +++ b/app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseMessagingService.java @@ -0,0 +1,57 @@ +package fi.aalto.legroup.achso.utilities; + +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.media.RingtoneManager; +import android.net.Uri; +import android.support.v4.app.NotificationCompat; + +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; + +import fi.aalto.legroup.achso.R; +import fi.aalto.legroup.achso.browsing.BrowserActivity; + +/** + * Created by mat on 18/04/2017. + */ + +public class AchsoFirebaseMessagingService extends FirebaseMessagingService { + + @Override + public void onMessageReceived(RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + + if (remoteMessage.getNotification() != null) { + RemoteMessage.Notification notification = remoteMessage.getNotification(); + String title = notification.getTitle(); + String body = notification.getBody(); + + sendNotification(body, title); + } + } + + private void sendNotification(String messageBody, String messageTitle) { + Intent intent = new Intent(this, BrowserActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, + PendingIntent.FLAG_ONE_SHOT); + + + Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) + .setSmallIcon(R.drawable.ic_launcher) + .setContentTitle(messageTitle) + .setContentText(messageBody) + .setAutoCancel(true) + .setSound(defaultSoundUri) + .setContentIntent(pendingIntent); + + NotificationManager notificationManager = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + + notificationManager.notify(0 /* ID of notification */, notificationBuilder.build()); + } +} From d02d6ce4fcb426324d6a70a41dea9e2da11fd61f Mon Sep 17 00:00:00 2001 From: Matti Jokitulppo Date: Tue, 18 Apr 2017 23:08:02 +0300 Subject: [PATCH 7/9] Export notification services --- app/src/main/AndroidManifest.xml | 4 ++++ .../achso/utilities/AchsoFirebaseInstanceIdService.java | 2 ++ 2 files changed, 6 insertions(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8cd9e933..f6ac48b2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -139,6 +139,8 @@ android:parentActivityName=".browsing.BrowserActivity" /> @@ -146,6 +148,8 @@ diff --git a/app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseInstanceIdService.java b/app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseInstanceIdService.java index 27233f78..fdfe4e04 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseInstanceIdService.java +++ b/app/src/main/java/fi/aalto/legroup/achso/utilities/AchsoFirebaseInstanceIdService.java @@ -11,5 +11,7 @@ public void onTokenRefresh() { String refreshedToken = FirebaseInstanceId.getInstance().getToken(); App.tokenUpdated(refreshedToken); + + super.onTokenRefresh(); } } From 6296cdde020e492350c676cd9b79c0092a90b708 Mon Sep 17 00:00:00 2001 From: Matti Jokitulppo Date: Wed, 19 Apr 2017 17:25:25 +0300 Subject: [PATCH 8/9] Add functional device token registering --- .../java/fi/aalto/legroup/achso/app/App.java | 49 ++++++++++++++----- .../authentication/AccountLoggedOutEvent.java | 19 +++++++ .../AuthenticatedHttpClient.java | 2 + .../achso/authentication/LoginManager.java | 7 ++- .../achso/storage/remote/VideoHost.java | 3 +- .../remote/strategies/AchRailsStrategy.java | 25 ++++++---- .../achso/utilities/EmptyCallback.java | 4 +- 7 files changed, 81 insertions(+), 28 deletions(-) create mode 100644 app/src/main/java/fi/aalto/legroup/achso/authentication/AccountLoggedOutEvent.java diff --git a/app/src/main/java/fi/aalto/legroup/achso/app/App.java b/app/src/main/java/fi/aalto/legroup/achso/app/App.java index 5c43cc02..c0b4bc32 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/app/App.java +++ b/app/src/main/java/fi/aalto/legroup/achso/app/App.java @@ -1,5 +1,6 @@ package fi.aalto.legroup.achso.app; +import android.accounts.Account; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; @@ -7,14 +8,14 @@ import android.net.NetworkInfo; import android.net.Uri; import android.os.Environment; +import android.os.Handler; import android.preference.PreferenceManager; import android.support.multidex.MultiDexApplication; +import android.util.Log; import android.widget.Toast; import com.google.android.gms.analytics.GoogleAnalytics; -import com.google.firebase.FirebaseApp; import com.google.firebase.iid.FirebaseInstanceId; -import com.google.firebase.iid.FirebaseInstanceIdService; import com.rollbar.android.Rollbar; import com.squareup.okhttp.OkHttpClient; import com.squareup.otto.Bus; @@ -25,9 +26,12 @@ import java.io.File; import java.io.IOException; import java.security.GeneralSecurityException; +import java.util.Timer; +import java.util.TimerTask; import fi.aalto.legroup.achso.BuildConfig; import fi.aalto.legroup.achso.R; +import fi.aalto.legroup.achso.authentication.AccountLoggedOutEvent; import fi.aalto.legroup.achso.authentication.AuthenticatedHttpClient; import fi.aalto.legroup.achso.authentication.LoginManager; import fi.aalto.legroup.achso.authentication.LoginRequestEvent; @@ -189,19 +193,38 @@ public static void tokenUpdated(String notificationToken) { } @Subscribe - public static void onLoginStateEvent(LoginStateEvent event) { - String token = FirebaseInstanceId.getInstance().getToken(); + public static void onLoginStateEvent(final LoginStateEvent event) { + new Timer().schedule(new TimerTask() { + @Override + public void run() { + // this code will be executed after 2 seconds + String token = FirebaseInstanceId.getInstance().getToken(); - if (token == null) return; + if (token == null) return; - if (event.getState() == LoginManager.LoginState.LOGGED_IN) { - App.registerToken(token); - } else if (event.getState() == LoginManager.LoginState.LOGGING_OUT) { - App.unregisterToken(token); - } + if (event.getState() == LoginManager.LoginState.LOGGED_IN) { + App.registerToken(token); + } + } + }, 2000); + } + + @Subscribe + public static void onAccountLoggedOutEvent(final AccountLoggedOutEvent event) { + new Timer().schedule(new TimerTask() { + @Override + public void run() { + // this code will be executed after 2 seconds + String token = FirebaseInstanceId.getInstance().getToken(); + + if (token == null) return; + + App.removeTokenFromAccount(event.getAccount(), token); + } + }, 2000); } - private static void registerToken(String notificationToken) { + private static void registerToken(final String notificationToken) { try { achRails.registerToken(notificationToken); } catch (JSONException e) { @@ -211,9 +234,9 @@ private static void registerToken(String notificationToken) { } } - private static void unregisterToken(String notificationToken) { + private static void removeTokenFromAccount(Account account, String notificationToken) { try { - achRails.unregisterToken(notificationToken); + achRails.unregisterToken(account, notificationToken); } catch (JSONException e) { e.printStackTrace(); } catch (IOException e) { diff --git a/app/src/main/java/fi/aalto/legroup/achso/authentication/AccountLoggedOutEvent.java b/app/src/main/java/fi/aalto/legroup/achso/authentication/AccountLoggedOutEvent.java new file mode 100644 index 00000000..3ca88c4f --- /dev/null +++ b/app/src/main/java/fi/aalto/legroup/achso/authentication/AccountLoggedOutEvent.java @@ -0,0 +1,19 @@ +package fi.aalto.legroup.achso.authentication; + +import android.accounts.Account; + +/** + * Created by mat on 19/04/2017. + */ + +public class AccountLoggedOutEvent { + Account account; + + public AccountLoggedOutEvent(Account account) { + this.account = account; + } + + public Account getAccount() { + return account; + } +} diff --git a/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java b/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java index e5bb24f9..d173751b 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java +++ b/app/src/main/java/fi/aalto/legroup/achso/authentication/AuthenticatedHttpClient.java @@ -69,6 +69,8 @@ public Response execute(Request request, Account account, boolean doRetry) throw } public void enqueue(Request request, Account account, Callback cb) { + AccountManager accountManager = AccountManager.get(context); + String token = getBearerToken(account); request = request.newBuilder().header("Authorization", "Bearer " + token).build(); diff --git a/app/src/main/java/fi/aalto/legroup/achso/authentication/LoginManager.java b/app/src/main/java/fi/aalto/legroup/achso/authentication/LoginManager.java index 91d77878..d2c7f483 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/authentication/LoginManager.java +++ b/app/src/main/java/fi/aalto/legroup/achso/authentication/LoginManager.java @@ -88,6 +88,10 @@ public void login(Account account) { new LoginTask().execute(account); } + private void notifyAcccountLoggedOut(Account account) { + this.bus.post(new AccountLoggedOutEvent(account)); + } + /** * Logs out from the account and disables auto-login. Use this if the user manually logs out. */ @@ -113,6 +117,7 @@ public void logout() { } setState(LoginState.LOGGED_OUT, true); + notifyAcccountLoggedOut(account); account = null; user = null; } @@ -265,7 +270,5 @@ protected void onPostExecute(String error) { setState(LoginState.LOGGED_IN, true); } - } - } diff --git a/app/src/main/java/fi/aalto/legroup/achso/storage/remote/VideoHost.java b/app/src/main/java/fi/aalto/legroup/achso/storage/remote/VideoHost.java index 12736050..75f2a9ba 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/storage/remote/VideoHost.java +++ b/app/src/main/java/fi/aalto/legroup/achso/storage/remote/VideoHost.java @@ -1,5 +1,6 @@ package fi.aalto.legroup.achso.storage.remote; +import android.accounts.Account; import android.net.Uri; import org.json.JSONException; @@ -60,5 +61,5 @@ public interface VideoHost { public void registerToken(String notificationToken) throws JSONException, IOException; - public void unregisterToken(String notificationToken) throws JSONException, IOException; + public void unregisterToken(Account account, String notificationToken) throws JSONException, IOException; } diff --git a/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java b/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java index f653a30a..faddede8 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java +++ b/app/src/main/java/fi/aalto/legroup/achso/storage/remote/strategies/AchRailsStrategy.java @@ -104,9 +104,14 @@ private Response validateResponse(Response response) throws IOException { return response; } - private void executeRequestAsync(Request request, Callback cb) throws IOException { - Account account = App.loginManager.getAccount(); - App.authenticatedHttpClient.enqueue(request, account, cb); + private Response executeRequestWithAccount(Account account, Request request) { + try { + return App.authenticatedHttpClient.execute(request, account); + } catch (IOException e) { + e.printStackTrace(); + } + + return null; } private Response executeRequest(Request request) throws IOException { @@ -173,35 +178,35 @@ public void makeVideoPrivate(UUID videoId) throws IOException, JSONException { @Override public void registerToken(String notificationToken) throws JSONException, IOException { JSONObject obj = new JSONObject(); - obj.put("token", notificationToken); + obj.put("registration_token", notificationToken); RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), obj.toString()); Request request = new Request.Builder() .url(endpointUrl.buildUpon() .appendPath("notifications") - .appendPath("register") + .appendPath("register_token") .toString()) .put(body).build(); - executeRequestAsync(request, new EmptyCallback()); + executeRequest(request); } @Override - public void unregisterToken(String notificationToken) throws JSONException, IOException { + public void unregisterToken(Account account, String notificationToken) throws JSONException, IOException { JSONObject obj = new JSONObject(); - obj.put("token", notificationToken); + obj.put("registration_token", notificationToken); RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), obj.toString()); Request request = new Request.Builder() .url(endpointUrl.buildUpon() .appendPath("notifications") - .appendPath("unregister") + .appendPath("unregister_token") .toString()) .put(body).build(); - executeRequestAsync(request, new EmptyCallback()); + executeRequestWithAccount(account, request); } @Override diff --git a/app/src/main/java/fi/aalto/legroup/achso/utilities/EmptyCallback.java b/app/src/main/java/fi/aalto/legroup/achso/utilities/EmptyCallback.java index b53aa5fb..44ba585d 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/utilities/EmptyCallback.java +++ b/app/src/main/java/fi/aalto/legroup/achso/utilities/EmptyCallback.java @@ -13,11 +13,11 @@ public class EmptyCallback implements Callback { @Override public void onFailure(Request request, IOException e) { - + System.out.println(request); } @Override public void onResponse(Response response) throws IOException { - // System.out.println(response); + System.out.println(response); } } From 9718f81692ffc9ff02899e826952c106a11877ee Mon Sep 17 00:00:00 2001 From: Matti Jokitulppo Date: Mon, 24 Apr 2017 19:06:49 +0300 Subject: [PATCH 9/9] Tweak notification times a bit --- app/src/main/java/fi/aalto/legroup/achso/app/App.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/fi/aalto/legroup/achso/app/App.java b/app/src/main/java/fi/aalto/legroup/achso/app/App.java index c0b4bc32..bf021cda 100644 --- a/app/src/main/java/fi/aalto/legroup/achso/app/App.java +++ b/app/src/main/java/fi/aalto/legroup/achso/app/App.java @@ -206,11 +206,11 @@ public void run() { App.registerToken(token); } } - }, 2000); + }, 4000); } @Subscribe - public static void onAccountLoggedOutEvent(final AccountLoggedOutEvent event) { + public static void onAccountLoggedOutEvent(final AccountLoggedOutEvent event) { new Timer().schedule(new TimerTask() { @Override public void run() { @@ -221,7 +221,7 @@ public void run() { App.removeTokenFromAccount(event.getAccount(), token); } - }, 2000); + }, 10); } private static void registerToken(final String notificationToken) {