diff --git a/docs/html/google/gcm/ccs.jd b/docs/html/google/gcm/ccs.jd index ffe15c556c807..0cadbd245c16b 100644 --- a/docs/html/google/gcm/ccs.jd +++ b/docs/html/google/gcm/ccs.jd @@ -23,7 +23,7 @@ page.title=GCM Cloud Connection Server
  • Message Examples
  • -
  • Control Flow
  • +
  • Flow Control
  • See Also

    @@ -48,6 +48,8 @@ page.title=GCM Cloud Connection Server

    The upstream messaging (device-to-cloud) feature of CCS is part of the Google Play services platform. Upstream messaging is available through the {@code GoogleCloudMessaging} APIs. To use upstream messaging and the new streamlined registration process, you must set up the Google Play services SDK.

    +

    Note: For an example of an XMPP server, see GCM Server. +

    CCS vs. GCM HTTP

    CCS messaging differs from GCM HTTP messaging in the following ways:

    @@ -229,69 +231,13 @@ gcm.send(GCM_SENDER_ID + "@gcm.googleapis.com", id, ttl, data); </gcm> </message> -

    Python Example

    -

    This example illustrates how to connect, -send, and receive GCM messages using XMPP. It shouldn't be used as-is -on a production deployment.

    -
    -import sys, json, xmpp
    -SERVER = ('gcm.googleapis.com', 5235)
    -#USERNAME = '<your_numeric_project_id>'
    -#PASSWORD = '<your_gcm_api_key>'
    +

    Flow Control

    -# Unique message id for downstream messages -sent_message_id = 0 +

    Every message sent to CCS receives either an ACK or a NACK response. Messages that haven't received one of these responses are considered pending. If the pending message count reaches 1000, the 3rd-party server should stop sending new messages and wait for CCS to acknowledge some of the existing pending messages.

    -def message_callback(session, message): - global sent_message_id - gcm = message.getTags('gcm') +

    Conversely, to avoid overloading the 3rd-party server, CCS will stop sending if there are too many unacknowledged messages. Therefore, the 3rd-party server should "ACK" received messages as soon as possible to maintain a constant flow of incoming messages. The aforementioned pending message limit doesn't apply to these ACKs. Even if the pending message count reaches 1000, the 3rd-party server should continue sending ACKs to avoid blocking delivery of new messages.

    - if gcm: - gcm_json = gcm[0].getData() - msg = json.loads(gcm_json) - msg_id = msg['message_id'] - device_reg_id = msg['from'] - - # Ignore non-standard messages (e.g. acks/nacks). - if not msg.has_key('message_type'): - # Acknowledge the incoming message. - send({'to': device_reg_id, - 'message_type': 'ack', - 'message_id': msg_id}) - - # Send a response back to the server. - send({'to': device_reg_id, - 'message_id' : str(sent_message_id), - 'data': {'pong': 1}}) - sent_message_id = sent_message_id + 1 - -def send(json_dict): - template = ("<message from='{0}' to='gcm@google.com'>" - "<gcm xmlns='google:mobile:data'>{1}</gcm></message>") - client.send(xmpp.protocol.Message( - node=template.format(client.Bind.bound[0], - json.dumps(json_dict)))) - -client = xmpp.Client(SERVER[0], debug=['socket']) -client.connect(server=SERVER, secure=1, use_srv=False) -auth = client.auth(USERNAME, PASSWORD, 'test') -if not auth: - print 'Authentication failed!' - sys.exit(1) - -client.RegisterHandler('message', message_callback) - -while True: - client.Process(1)
    - -

    Control Flow

    - -

    Every message sent by a 3rd-party server to CCS receives either an ACK or a NACK response. A single connection can have at most 1000 messages that were sent without having yet received a response.

    - -

    To enforce this policy, the app can maintain a counter of sent messages that increments on each send and decrements on each ACK or NACK. If the counter exceeds 1000, the app should stop sending messages until an ACK or NACK is received.

    - -

    Conversely, when CCS sends messages to a 3rd-party server, it expects ACKs for each message it sends, and it will not send more than 1000 unacknowledged messages.

    - -

    The ACKs and messages must match on each connection. You can only send an ACK for a message on the connection on which it was received.

    +

    ACKs are only valid within the context of one connection. If the connection is closed before a message can be ACKed, the 3rd-party server should wait for CCS to resend the message before ACKing it again. +

    diff --git a/docs/html/google/gcm/client.jd b/docs/html/google/gcm/client.jd new file mode 100644 index 0000000000000..7604932aa3832 --- /dev/null +++ b/docs/html/google/gcm/client.jd @@ -0,0 +1,24 @@ +page.title=GCM Client +page.tags="cloud","push","messaging" +@jd:body + +
    +
    + +

    See Also

    + +
      +
    1. Getting Started
    2. +
    3. GCM Server
    4. +
    + +
    +
    + +

    A GCM client is a GCM-enabled app that runs on an Android device. To write your client code, we recommend that you use the new {@code GoogleCloudMessaging} APIs. The client helper library that was offered in previous versions of GCM still works, but it has been superseded by the more efficient {@code GoogleCloudMessaging} APIs.

    + +

    A full GCM implementation requires both a client implementation and a server-side implementation. For a step-by-step guide to creating a complete sample implementation that includes both client and server, see Getting Started.

    + +

    + + diff --git a/docs/html/google/gcm/demo.jd b/docs/html/google/gcm/demo.jd index 6da9e986aa8b6..012eb9a09d628 100644 --- a/docs/html/google/gcm/demo.jd +++ b/docs/html/google/gcm/demo.jd @@ -1,6 +1,22 @@ page.title=GCM Demo Application @jd:body +

    + + This doc is deprecated +
    + + +
    +

    The information in this document has been superseded by GCM Server and GCM Client. Please use the {@code GoogleCloudMessaging} API instead of the GCM client helper library. The GCM server helper library is still valid.

    + + +
    +
    +
    diff --git a/docs/html/google/gcm/gcm.jd b/docs/html/google/gcm/gcm.jd index b5bcfc9d8b506..4d26e6b54ce16 100644 --- a/docs/html/google/gcm/gcm.jd +++ b/docs/html/google/gcm/gcm.jd @@ -28,20 +28,6 @@ page.title=GCM Architectural Overview
  • What Does the User See?
  • -
  • Writing Android Applications that use GCM -
      -
    1. Creating the Manifest
    2. -
    3. Registering for GCM
    4. - -
    5. Handling Intents Sent by GCM -
        -
      1. Handling Registration Results
      2. -
      3. Handling Received Data
      4. -
      -
    6. -
    7. Developing and Testing Your Android Applications
    8. -
    -
  • Role of the 3rd-party Application Server
    1. Sending Messages @@ -53,7 +39,6 @@ page.title=GCM Architectural Overview
  • Viewing Statistics
  • -
  • Examples
  • @@ -306,336 +291,6 @@ from the com.google.android.c2dm.intent.RECEIVE Intent includes GCM. They must approve the use of this feature to install the Android application.

    -

    Writing Android Applications that Use GCM

    - -

    To write Android applications that use GCM, you must have an application -server that can perform the tasks described in Role of the -3rd-party Application Server. This section describes the steps you take to -create a client application that uses GCM.

    - -

    Remember that there is no user interface associated with GCM. -However you choose to process messages in your Android application is up to you.

    - -

    There are two primary steps involved in writing a client Android application:

    - - - -

    Note: This section describes how to -write an app without using the -helper libraries. -For details on writing -an app that uses the helper libraries (which is the recommended and -simpler approach), see GCM: Getting Started. - -

    Creating the Manifest

    - -

    To use the GCM feature, the -AndroidManifest.xml file must include the following:

    - - - -

    Here are excerpts from a manifest that supports GCM:

    - -
    -<manifest package="com.example.gcm" ...>
    -
    -    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16"/>
    -    <uses-permission android:name="android.permission.INTERNET" />
    -    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    -    <uses-permission android:name="android.permission.WAKE_LOCK" />
    -    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    -
    -    <permission android:name="com.example.gcm.permission.C2D_MESSAGE" 
    -        android:protectionLevel="signature" />
    -    <uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
    -
    -    <application ...>
    -        <receiver
    -            android:name=".MyBroadcastReceiver"
    -            android:permission="com.google.android.c2dm.permission.SEND" >
    -            <intent-filter>
    -                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    -                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
    -                <category android:name="com.example.gcm" />
    -            </intent-filter>
    -        </receiver>
    -        <service android:name=".MyIntentService" />
    -    </application>
    -
    -</manifest>
    -
    - -

    Registering for GCM

    - - - -

    An Android application needs to register with GCM servers before it can receive messages. To register, the application sends an Intent -(com.google.android.c2dm.intent.REGISTER), with 2 extra parameters: -

    - - - -

    For example:

    - -
    Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
    -// sets the app name in the intent
    -registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
    -registrationIntent.putExtra("sender", senderID);
    -startService(registrationIntent);
    - -

    This intent will be asynchronously sent to the GCM server, and the response will be delivered to -the application as a com.google.android.c2dm.intent.REGISTRATION intent containing -the registration ID assigned to the Android application running on that particular device.

    - -

    Registration is not complete until the Android application sends the registration ID -to the 3rd-party application server, which in turn will use the registration ID to send -messages to the application.

    - -

    Unregistering from GCM

    - -

    To unregister from GCM, do the following:

    - -
    Intent unregIntent = new Intent("com.google.android.c2dm.intent.UNREGISTER");
    -unregIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
    -startService(unregIntent);
    -
    - -

    Similar to the registration request, this intent is sent asynchronously, and the response comes as a com.google.android.c2dm.intent.REGISTRATION intent. - - -

    Handling Intents sent by GCM

    - -

    As discussed in Creating the Manifest, the manifest -defines a broadcast receiver for the com.google.android.c2dm.intent.REGISTRATION and com.google.android.c2dm.intent.RECEIVE intents. -These intents are sent by GCM to indicate that a device was registered (or unregistered), or to deliver messages, respectively.

    - -

    Handling these intents might require I/O operations (such as network calls to the 3rd-party server), and -such operations should not be done in the receiver's onReceive() method. -You may be tempted to spawn a new thread directly, but there are no guarantees that the process will run long enough for the thread to finish the work. -Thus the recommended way to handle the intents is to delegate them to a service, such as an {@link android.app.IntentService}. -For example:

    - - -
    -public class MyBroadcastReceiver extends BroadcastReceiver {
    -
    -    @Override
    -    public final void onReceive(Context context, Intent intent) {
    -        MyIntentService.runIntentInService(context, intent);
    -        setResult(Activity.RESULT_OK, null, null);
    -    }
    -}
    -
    - -

    Then in MyIntentService:

    -
    -public class MyIntentService extends IntentService {
    -
    -    private static PowerManager.WakeLock sWakeLock;
    -    private static final Object LOCK = MyIntentService.class;
    -    
    -    static void runIntentInService(Context context, Intent intent) {
    -        synchronized(LOCK) {
    -            if (sWakeLock == null) {
    -                PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    -                sWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "my_wakelock");
    -            }
    -        }
    -        sWakeLock.acquire();
    -        intent.setClassName(context, MyIntentService.class.getName());
    -        context.startService(intent);
    -    }
    -    
    -    @Override
    -    public final void onHandleIntent(Intent intent) {
    -        try {
    -            String action = intent.getAction();
    -            if (action.equals("com.google.android.c2dm.intent.REGISTRATION")) {
    -                handleRegistration(intent);
    -            } else if (action.equals("com.google.android.c2dm.intent.RECEIVE")) {
    -                handleMessage(intent);
    -            }
    -        } finally {
    -            synchronized(LOCK) {
    -                sWakeLock.release();
    -            }
    -        }
    -    }
    -}
    -
    - -

    Note: your application must acquire a wake lock before starting the service—otherwise the device could be put to sleep before the service is started.

    - -

    Handling Registration Results

    - -

    When a com.google.android.c2dm.intent.REGISTRATION intent is received, it could potentially contain 3 extras: registration_id, error, and unregistered. - -

    When a registration succeeds, registration_id contains the registration ID and the other extras are not set. -The application must ensure that the 3rd-party server receives the registration ID. It may do so by saving the registration ID and sending it to the server. -If the network is down or there are errors, the application should retry sending the registration ID when the network is up again or the next time it starts.

    - -

    Note: Although the com.google.android.c2dm.intent.REGISTRATION intent is typically received after a request was made by the application, -Google may periodically refresh the registration ID. So the application must be prepared to handle it at any time.

    - -

    When an unregistration succeeds, only the unregistered extra is set, and similar to the registration workflow, -the application must contact the 3rd-party server to remove the registration ID (note that the registration ID is not available in the intent, -but the application should have saved the registration ID when it got it).

    - -

    If the application request (be it register or unregister) fails, the error will be set with an error code, and the other extras will not be set. - -Here are the possible error codes:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Error CodeDescription
    SERVICE_NOT_AVAILABLEThe device can't read the response, or there was a 500/503 from the -server that can be retried later. The Android application should use exponential back-off and retry. See Advanced Topics for more information.
    ACCOUNT_MISSINGThere is no Google account on the phone. The Android application should ask the -user to open the account manager and add a Google account. Fix on the device -side.
    AUTHENTICATION_FAILEDBad Google Account password. The Android application should ask the user to enter his/her Google Account -password, and let the user retry manually later. Fix on the device side.
    INVALID_SENDERThe sender account is not recognized. This must be fixed on the Android application side. The developer must fix the application to provide the right sender extra in the com.google.android.c2dm.intent.REGISTER intent.
    PHONE_REGISTRATION_ERROR Incorrect phone registration with Google. This -phone doesn't currently support GCM.
    INVALID_PARAMETERSThe request sent by the phone does not contain the expected parameters. This phone doesn't currently support GCM.
    - - - - -

    Here's an example on how to handle the registration in the MyIntentService example:

    - -
    -private void handleRegistration(Intent intent) {
    -    String registrationId = intent.getStringExtra("registration_id");
    -    String error = intent.getStringExtra("error");
    -    String unregistered = intent.getStringExtra("unregistered");
    -    // registration succeeded
    -    if (registrationId != null) {
    -        // store registration ID on shared preferences
    -        // notify 3rd-party server about the registered ID
    -    }
    -        
    -    // unregistration succeeded
    -    if (unregistered != null) {
    -        // get old registration ID from shared preferences
    -        // notify 3rd-party server about the unregistered ID
    -    } 
    -        
    -    // last operation (registration or unregistration) returned an error;
    -    if (error != null) {
    -        if ("SERVICE_NOT_AVAILABLE".equals(error)) {
    -           // optionally retry using exponential back-off
    -           // (see Advanced Topics)
    -        } else {
    -            // Unrecoverable error, log it
    -            Log.i(TAG, "Received error: " + error);
    -        }
    -    }
    -}
    - - - -

    Handling Received Data

    - -

    The com.google.android.c2dm.intent.RECEIVE intent is used by GCM to -deliver the messages sent by the 3rd-party server to the application running in the device. -If the server included key-pair values in the data parameter, they are available as -extras in this intent, with the keys being the extra names. GCM also includes an extra called -from which contains the sender ID as an string, and another called collapse_key containing the collapse key (when in use). - -

    Here is an example, again using the MyIntentReceiver class:

    - -
    -private void handleMessage(Intent intent) {
    -    // server sent 2 key-value pairs, score and time
    -    String score = intent.getExtra("score");
    -    String time = intent.getExtra("time");
    -    // generates a system notification to display the score and time
    -}
    - -

    Developing and Testing Your Android Applications

    - -

    Here are some guidelines for developing and testing an Android application -that uses the GCM feature:

    - - -

    Role of the 3rd-party Application Server

    @@ -1104,6 +759,4 @@ registration_id=32

    Note: Stats on the Google API Console are not enabled for GCM. You must use the Developer Console.

    -

    Examples

    -

    See the GCM Demo Application document.

    diff --git a/docs/html/google/gcm/gs.jd b/docs/html/google/gcm/gs.jd index d938bd6f2d84a..8ceea0cc8b0d6 100644 --- a/docs/html/google/gcm/gs.jd +++ b/docs/html/google/gcm/gs.jd @@ -12,14 +12,14 @@ page.tags="cloud","push","messaging"
  • Creating a Google API Project
  • Enabling the GCM Service
  • Obtaining an API Key
  • -
  • Writing the Android Application +
  • Writing a Client App
  • +
  • Writing the Server Code
  • See Also

    1. Google APIs Console page
    2. -
    3. Using the GCM Helper Libraries
    4. CCS and User Notifications Signup Form
    @@ -29,20 +29,9 @@ page.tags="cloud","push","messaging"

    The sections below guide you through the process of setting up a GCM implementation. Before you start, make sure to set up -the Google Play Services SDK. You need this SDK to use the {@code GoogleCloudMessaging} methods. Strictly speaking, the only thing you absolutely need this API for is upstream (device-to-cloud) messaging, but it also offers a streamlined registration API that is recommended.

    - - - - +the Google Play Services SDK. You need this SDK to use the {@code GoogleCloudMessaging} methods.

    +

    Note that a full GCM implementation requires a server-side implementation, in addition to the client implementation in your app. This document offers a complete example that includes both the client and server.

    Creating a Google API project

    @@ -95,17 +84,21 @@ the Google Play Services SDK. You need this SDK to use the Note: If you need to rotate the key, click Generate new key. A new key will be created while the old one will still be active for up to 24 hours. If you want to get rid of the old key immediately (for example, if you feel it was compromised), click Delete key.

    +

    The following sections walk you through the steps of creating client and server-side code.

    -

    Writing the Android Application

    -

    This section describes the steps involved in writing an Android application that uses GCM.

    +

    Writing a Client App

    -

    Step 1: Make the following changes in the application's Android manifest

    +

    This section walks you through the steps involved in writing a client-side application—that is, the GCM-enabled application that runs on an Android device. This client sample is designed to work in conjunction with the server code shown in Writing the Server Code, below.

    + + + +

    Step 1: Edit Your App's Manifest

    diff --git a/docs/html/reference/gcm-packages.html b/docs/html/reference/gcm-packages.html index 8065be917ec68..2b5dc2dc823cd 100644 --- a/docs/html/reference/gcm-packages.html +++ b/docs/html/reference/gcm-packages.html @@ -623,14 +623,15 @@ onkeyup="return search_changed(event, false, '/')" /> com.google.android.gcm - + DEPRECATED. Please use the GoogleCloudMessaging API instead of this client helper library. See GCM Client for more information. com.google.android.gcm.server - + Helper library for GCM HTTP server operations. See GCM Server for more information.