Skip to content

Commit

Permalink
Merge pull request google#96 from ogeidix/master
Browse files Browse the repository at this point in the history
GCM-demo android app v5 (instance-id and UI polishing)
  • Loading branch information
tjohns committed Sep 3, 2015
2 parents 352dcc9 + bfcb7ae commit 545e15b
Show file tree
Hide file tree
Showing 63 changed files with 1,676 additions and 861 deletions.
6 changes: 3 additions & 3 deletions samples/android/gcm-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ and an API key to be able to test server side APIs. For more information, see
## Screenshots

![Menu](screenshots/menu.png "The app's menu")
![Registration](screenshots/registration1.png "Registration page - unregistered")
![Registration - registered](screenshots/registration2.png "Registration page - registered")
![Quick Tests](screenshots/home.png "Quick Tests page")
![InstanceID](screenshots/instanceid.png "InstanceID page")
![Downstream](screenshots/downstream.png "Sending downstream messages")
![Upstream](screenshots/upstream.png "Upstream page")
![Groups](screenshots/groups.png "Groups page")
![Topics](screenshots/topics.png "Topics page")
![Add topic](screenshots/add_topic.png "Add a topic")
![Tasks](screenshots/tasks.png "Network manager tasks page")

## Support
Expand Down
12 changes: 6 additions & 6 deletions samples/android/gcm-demo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ android {
applicationId "com.google.android.gcm.demo"
minSdkVersion 15
targetSdkVersion 22
versionCode 4
versionName "4.0"
versionCode 5
versionName "5.0"
}
buildTypes {
release {
Expand All @@ -42,8 +42,8 @@ android {
}

dependencies {
compile 'com.google.android.gms:play-services-gcm:7.5.0'
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'com.android.support:cardview-v7:22.1.1'
compile 'com.android.support:recyclerview-v7:22.1.1'
compile 'com.google.android.gms:play-services-gcm:7.8.0'
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.android.support:cardview-v7:22.2.0'
compile 'com.android.support:recyclerview-v7:22.2.0'
}
Binary file removed samples/android/gcm-demo/screenshots/add_topic.png
Binary file not shown.
Binary file modified samples/android/gcm-demo/screenshots/downstream.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified samples/android/gcm-demo/screenshots/groups.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/android/gcm-demo/screenshots/home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified samples/android/gcm-demo/screenshots/menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file modified samples/android/gcm-demo/screenshots/tasks.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified samples/android/gcm-demo/screenshots/topics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions samples/android/gcm-demo/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ limitations under the License.
</intent-filter>
</activity>

<activity
android:name=".ui.TokenActivity"
android:windowSoftInputMode="adjustPan"
android:parentActivityName="com.google.android.gcm.demo.ui.MainActivity">
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.google.android.gcm.demo.ui.MainActivity" />
</activity>

<activity
android:name=".ui.GroupActivity"
android:windowSoftInputMode="adjustPan"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.google.android.gcm.demo.model.Sender;
import com.google.android.gcm.demo.model.SenderCollection;
import com.google.android.gcm.demo.service.LoggingService;
import com.google.android.gcm.demo.ui.MainActivity;


public class DeviceGroupsHelper {
Expand Down Expand Up @@ -98,7 +99,7 @@ protected Void doInBackground(Void... voids) {
mLogger.log(Log.INFO, "Group creation failed."
+ "\ngroupName: " + groupName
+ "\nhttpResponse:" + httpRequest.getResponseBody());
showToast(R.string.group_toast_group_creation_failed,
MainActivity.showToast(mContext, R.string.group_toast_group_creation_failed,
responseBody.getString("error"));
} else {
// Store the group in the local storage.
Expand All @@ -116,13 +117,15 @@ protected Void doInBackground(Void... voids) {
mLogger.log(Log.INFO, "Group creation succeeded."
+ "\ngroupName: " + group.notificationKeyName
+ "\ngroupKey: " + group.notificationKey);
showToast(R.string.group_toast_group_creation_succeeded);
MainActivity.showToast(mContext,
R.string.group_toast_group_creation_succeeded);
}
} catch (JSONException | IOException e) {
mLogger.log(Log.INFO, "Exception while creating a new group"
+ "\nerror: " + e.getMessage()
+ "\ngroupName: " + groupName);
showToast(R.string.group_toast_group_creation_failed, e.getMessage());
MainActivity.showToast(mContext,
R.string.group_toast_group_creation_failed, e.getMessage());
}
return null;
}
Expand Down Expand Up @@ -222,7 +225,7 @@ public void addMembers(String senderId, String apiKey, String groupName,
+ "\ngroupName: " + groupName
+ "\ngroupKey: " + groupKey
+ "\nhttpResponse: " + httpRequest.getResponseBody());
showToast(R.string.group_toast_add_members_failed,
MainActivity.showToast(mContext, R.string.group_toast_add_members_failed,
responseBody.getString("error"));
} else {
// Store the group in the local storage.
Expand All @@ -236,14 +239,15 @@ public void addMembers(String senderId, String apiKey, String groupName,
mLogger.log(Log.INFO, "Group members added successfully."
+ "\ngroupName: " + groupName
+ "\ngroupKey: " + groupKey);
showToast(R.string.group_toast_add_members_succeeded);
MainActivity.showToast(mContext, R.string.group_toast_add_members_succeeded);
}
} catch (JSONException | IOException e) {
mLogger.log(Log.INFO, "Exception while adding new group members."
+ "\nerror: " + e.getMessage()
+ "\ngroupName: " + groupName
+ "\ngroupKey: " + groupKey);
showToast(R.string.group_toast_add_members_failed, e.getMessage());
MainActivity.showToast(mContext,
R.string.group_toast_add_members_failed, e.getMessage());
}
}

Expand Down Expand Up @@ -285,7 +289,7 @@ public void removeMembers(String senderId, String apiKey, String groupName,
+ "\ngroupName: " + groupName
+ "\ngroupKey: " + groupKey
+ "\nhttpResponse: " + httpRequest.getResponseBody());
showToast(R.string.group_toast_remove_members_failed,
MainActivity.showToast(mContext, R.string.group_toast_remove_members_failed,
responseBody.getString("error"));
} else {
// Store the group in the local storage.
Expand All @@ -300,14 +304,15 @@ public void removeMembers(String senderId, String apiKey, String groupName,
mLogger.log(Log.INFO, "Group members removed successfully."
+ "\ngroupName: " + groupName
+ "\ngroupKey: " + groupKey);
showToast(R.string.group_toast_remove_members_succeeded);
MainActivity.showToast(mContext, R.string.group_toast_remove_members_succeeded);
}
} catch (JSONException | IOException e) {
mLogger.log(Log.INFO, "Exception while removing group members."
+ "\nerror: " + e.getMessage()
+ "\ngroupName: " + groupName
+ "\ngroupKey: " + groupKey);
showToast(R.string.group_toast_remove_members_failed, e.getMessage());
MainActivity.showToast(mContext,
R.string.group_toast_remove_members_failed, e.getMessage());
}
}

Expand All @@ -318,13 +323,4 @@ private List<String> bundleValues2Array(Bundle bundle) {
}
return values;
}

private void showToast(final int msgId, final Object... args) {
Handler handler = new Handler(mContext.getMainLooper());
handler.post( new Runnable(){
public void run(){
Toast.makeText(mContext, mContext.getString(msgId, args), Toast.LENGTH_LONG).show();
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

import android.util.Log;

import com.google.android.gcm.demo.R;
import com.google.android.gcm.demo.service.LoggingService;
import com.google.android.gcm.demo.ui.MainActivity;

import org.json.JSONException;
import org.json.JSONObject;
Expand Down Expand Up @@ -149,7 +151,7 @@ public void sendHttpPlaintextDownstreamMessage(String destination, Message messa
* @param message the message to be sent
* @throws IOException
*/
public void sendHttpJsonDownstreamMessage(String destination,
public String sendHttpJsonDownstreamMessage(String destination,
Message message) throws IOException {

JSONObject jsonBody = new JSONObject();
Expand All @@ -170,7 +172,7 @@ public void sendHttpJsonDownstreamMessage(String destination,
}
} catch (JSONException e) {
logger.log(Log.ERROR, "Failed to build JSON body");
return;
throw new IOException("Failed to build JSON body");
}

HttpRequest httpRequest = new HttpRequest();
Expand All @@ -192,6 +194,7 @@ public void sendHttpJsonDownstreamMessage(String destination,
logger.log(Log.ERROR, "Failed to parse server response:\n"
+ httpRequest.getResponseBody());
}
return httpRequest.getResponseBody();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,22 @@

import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

import com.google.android.gcm.demo.R;
import com.google.android.gcm.demo.model.Sender;
import com.google.android.gcm.demo.model.SenderCollection;
import com.google.android.gcm.demo.model.Token;
import com.google.android.gcm.demo.service.LoggingService;
import com.google.android.gcm.demo.ui.AbstractFragment;
import com.google.android.gcm.demo.ui.MainActivity;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.android.gms.iid.InstanceID;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

/**
* This class used to register and unregister the app for GCM.
Expand All @@ -46,31 +53,43 @@ public InstanceIdHelper(Context context) {
}

/**
* Register for GCM
*
* @param senderId the project id used by the app's server
* Get a Instance ID authorization Token
*/
public void getGcmTokenInBackground(final String senderId) {
public void getTokenInBackground(final String authorizedEntity, final String scope,
final Bundle extras) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
String token =
InstanceID.getInstance(mContext).getToken(senderId,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
mLogger.log(Log.INFO, "registration succeeded." +
"\nsenderId: " + senderId + "\ntoken: " + token);
String token = InstanceID.getInstance(mContext)
.getToken(authorizedEntity, scope, extras);
mLogger.log(Log.INFO, "getToken succeeded." +
"\nsenderId: " + authorizedEntity + "\ntoken: " + token);
MainActivity.showToast(mContext, R.string.iid_get_token_toast_success,
AbstractFragment.truncateToLongString(token));

// Save the token in the address book
Sender entry = mSenders.getSender(senderId);
Sender entry = mSenders.getSender(authorizedEntity);
if (entry == null) {
mLogger.log(Log.ERROR, "Could not save token, missing sender id");
return null;
}
entry.testAppToken = token;
Token tokenModel = new Token();
tokenModel.token = token;
tokenModel.scope = scope;
if (extras != null) {
for (String key : extras.keySet()) {
tokenModel.extras.put(key, extras.getString(key));
}
}
tokenModel.createdAt = System.currentTimeMillis();
entry.appTokens.put(token, tokenModel);
mSenders.updateSender(entry);

} catch (final IOException e) {
mLogger.log(Log.INFO, "registration failed." +
"\nsenderId: " + senderId + "\nerror: " + e.getMessage());
mLogger.log(Log.INFO, "getToken failed." +
"\nsenderId: " + authorizedEntity + "\nerror: " + e.getMessage());
MainActivity.showToast(mContext, R.string.iid_toast_error, e.getMessage());
}
return null;
}
Expand All @@ -79,28 +98,83 @@ protected Void doInBackground(Void... params) {

/**
* Unregister by deleting the token
*
* @param senderId the project id used by the app's server
*/
public void deleteGcmTokeInBackground(final String senderId) {
public void deleteTokenInBackground(final String authorizedEntity, final String scope) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
InstanceID.getInstance(mContext).deleteToken(senderId,
GoogleCloudMessaging.INSTANCE_ID_SCOPE);
InstanceID.getInstance(mContext).deleteToken(authorizedEntity, scope);
mLogger.log(Log.INFO, "delete token succeeded." +
"\nsenderId: " + senderId);
Sender entry = mSenders.getSender(senderId);
"\nsenderId: " + authorizedEntity);
MainActivity.showToast(mContext, R.string.iid_delete_token_toast_success);

Sender entry = mSenders.getSender(authorizedEntity);
if (entry == null) {
mLogger.log(Log.ERROR, "Could not remove token, missing sender id");
return null;
}
entry.testAppToken = null;
// In rare cases multiple token with same authorizedEntity:scope could exists
// example: during a rotation period, the app could have for the same
// authorizedEntity:scope an old token and a newer one.
List<String> toBeRemoved = new LinkedList<>();
for (Token token : entry.appTokens.values()) {
if (token.scope.equals(scope)) {
toBeRemoved.add(token.token);
}
}
for (String token : toBeRemoved) {
entry.appTokens.remove(token);
}
mSenders.updateSender(entry);
} catch (final IOException e) {
mLogger.log(Log.INFO, "remove token failed." +
"\nsenderId: " + senderId + "\nerror: " + e.getMessage());
"\nsenderId: " + authorizedEntity + "\nerror: " + e.getMessage());
MainActivity.showToast(mContext, R.string.iid_toast_error, e.getMessage());
}
return null;
}
}.execute();
}

public String getInstanceId() {
return InstanceID.getInstance(mContext).getId();
}

public long getCreationTime() {
return InstanceID.getInstance(mContext).getCreationTime();
}

public void deleteInstanceIdInBackground() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
InstanceID.getInstance(mContext).deleteInstanceID();
mLogger.log(Log.INFO, "delete instanceId succeeded.");
MainActivity.showToast(mContext, R.string.iid_delete_token_toast_success);

// Remove all appTokens and topics subscriptions tied to any Sender.
for (int i = 0; i < mSenders.getSenders().size(); i++) {
Sender sender = mSenders.getSenders().valueAt(i);
boolean senderIsDirty = false;
if (sender.appTokens.size() > 0) {
sender.appTokens.clear();
senderIsDirty = true;
}
for (String topic : sender.topics.keySet()) {
if (sender.topics.get(topic)) {
sender.topics.put(topic, false);
senderIsDirty = true;
}
}
if (senderIsDirty) {
mSenders.updateSender(sender);
}
}
} catch (final IOException e) {
mLogger.log(Log.INFO, "delete instanceId failed.\nerror: " + e.getMessage());
MainActivity.showToast(mContext, R.string.iid_toast_error, e.getMessage());
}
return null;
}
Expand Down
Loading

0 comments on commit 545e15b

Please sign in to comment.