Home | History | Annotate | Download | only in gcm
      1 page.title=Using the GCM Helper Libraries
      2 page.tags="cloud","push","messaging"
      3 @jd:body
      4 
      5 <div id="deprecatedSticker">
      6   <a href="#" 
      7      onclick="$('#naMessage').show();$('#deprecatedSticker').hide();return false">
      8     <strong>This doc is deprecated</strong></a>
      9 </div>
     10 
     11 
     12 <div id="naMessage" style="display:block">
     13 <div><p><strong>The information in this document has been superseded by <a href="server.html">GCM Server</a> and <a href="client.html">GCM Client</a></strong>. Please use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> API instead of the GCM client helper library. The GCM server helper library is still valid.</p>
     14 
     15  <input style="margin-top:1em;padding:5px" type="button"
     16         value="That's nice, but I still want to read this document"
     17 onclick="$('#naMessage').hide();$('#deprecatedSticker').show()" />
     18 </div>
     19 </div>
     20 
     21 
     22 <div id="qv-wrapper">
     23 <div id="qv">
     24 
     25 <h2>Quickview</h2>
     26 
     27 <ul>
     28 <li>Walk through the steps of creating a GCM app.</li>
     29 </ul>
     30 
     31 
     32 <h2>In this document</h2>
     33 
     34 <ol class="toc">
     35 <li><a href="#libs">Installing the Helper Libraries</a></li>
     36 <li><a href="#android-app">Writing the Android Application</a>
     37 <li><a href="#server-app">Writing the Server-side Application</a> </li>
     38 </ol>
     39 
     40 <h2>See Also</h2>
     41 
     42 <ol class="toc">
     43 <li><a href="{@docRoot}google/play-services/gcm/gs.html">Getting Started with GCM Extensions</a></li>
     44 <li><a href="https://services.google.com/fb/forms/gcm/" class="external-link" target="_android">CCS and User Notifications Signup Form</a></li>
     45 </ol>
     46 
     47 </div>
     48 </div>
     49 
     50 <p>This document describes how to write an Android application and the  server-side logic, using the client and server <a href="{@docRoot}reference/com/google/android/gcm/package-summary.html">helper libraries</a> provided by GCM.</p> 
     51 
     52 <p>The helper libraries are one option for creating an Android application that uses GCM. You can alternatively use the approach described in the <a href="{@docRoot}google/gcm/gcm.html#writing_apps">GCM Architectural Overview</a>. If you need to perform upstream messaging, you must use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> APIs, and <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> also provides a streamlined registration process.</p>
     53 
     54 <p>For information on how to get started creating an Android GCM application and an example of how to use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">GoogleCloudMessaging</a> APIs, see <a href="{@docRoot}google/gcm/gs.html">Getting Started</a>.</p>
     55 
     56 <h2 id="libs">Installing the Helper Libraries</h2>
     57 <p>To perform the steps described in the following sections, you must first install the 
     58 <a href="{@docRoot}reference/com/google/android/gcm/package-summary.html">helper libraries</a>. Note that while using the helper libraries is recommended, it is not required. See the <a href="gcm.html#writing_apps">GCM Architectural Overview</a> for a description of how to write apps without using the helper libraries.
     59 
     60 <p>To install the helper libraries, choose 
     61 <strong>Extras &gt; Google Cloud Messaging for Android Library</strong>
     62 from the SDK Manager. This creates a <code>gcm</code> directory under
     63 <code><em>YOUR_SDK_ROOT</em>/extras/google/</code> containing these
     64 subdirectories: <code>gcm-client</code>, <code>gcm-server</code>,
     65 <code>samples/gcm-demo-client</code>, <code>samples/gcm-demo-server</code>,
     66 and <code>samples/gcm-demo-appengine</code>.</p>
     67 
     68 <p class="note"><strong>Note:</strong> If you don't see <strong>Extras &gt; Google Cloud Messaging for Android Library</strong> in the SDK Manager, make sure you are running version 20 or higher. Be sure to restart the SDK Manager after updating it.</p>
     69 
     70 <h2 id="android-app">Writing the Android Application</h2>
     71 <p>This section describes the steps involved in writing an Android application that uses GCM.</p>
     72 <h4>Step 1: Copy the gcm.jar file into your application classpath</h4>
     73 <p> To write your Android application, first copy the <code>gcm.jar</code> file from the SDK's <code>gcm-client/dist</code> directory to your application classpath.</p>
     74 <h4>Step 2: Make the following changes in the application's Android manifest</h4>
     75 <ol>
     76   <li>GCM requires Android 2.2 or later, so if your application cannot work without GCM, add the following line, where <em>xx</em> is the latest target SDK version:</li>
     77 
     78 <pre class="prettyprint pretty-xml">&lt;uses-sdk android:minSdkVersion=&quot;8&quot; android:targetSdkVersion=&quot;xx&quot;/&gt;</pre>
     79 
     80   <li>Declare and use a custom permission so only this application can receive GCM messages:<br>
     81   </li>
     82 
     83 <pre class="prettyprint pretty-xml">&lt;permission android:name=&quot;my_app_package.permission.C2D_MESSAGE&quot; android:protectionLevel=&quot;signature&quot; /&gt;
     84 &lt;uses-permission android:name=&quot;my_app_package.permission.C2D_MESSAGE&quot; /&gt; </pre>
     85 <p> This permission must be called <code>my_app_package.permission.C2D_MESSAGE</code> (where <code>my_app_package</code> is the package name of your app as defined by the manifest tag), otherwise it will not  work.</p>
     86 <p class="note"><strong>Note:</strong> This permission is not required if you are targeting your application to 4.1 or above (i.e., minSdkVersion 16)</p>
     87 
     88   <li>Add the following permissions:</li>
     89 
     90 <pre class="prettyprint pretty-xml">&lt;!-- App receives GCM messages. --&gt;
     91 &lt;uses-permission android:name=&quot;com.google.android.c2dm.permission.RECEIVE&quot; /&gt;
     92 &lt;!-- GCM connects to Google Services. --&gt;
     93 &lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt; 
     94 &lt;!-- GCM requires a Google account. --&gt;
     95 &lt;uses-permission android:name=&quot;android.permission.GET_ACCOUNTS&quot; /&gt;
     96 &lt;!-- Keeps the processor from sleeping when a message is received. --&gt;
     97 &lt;uses-permission android:name=&quot;android.permission.WAKE_LOCK&quot; /&gt;</pre>
     98 
     99   <li>Add the following broadcast receiver:</li>
    100 
    101 <pre class="prettyprint pretty-xml">&lt;receiver android:name=&quot;com.google.android.gcm.GCMBroadcastReceiver&quot; android:permission=&quot;com.google.android.c2dm.permission.SEND&quot; &gt;
    102   &lt;intent-filter&gt;
    103     &lt;action android:name=&quot;com.google.android.c2dm.intent.RECEIVE&quot; /&gt;
    104     &lt;action android:name=&quot;com.google.android.c2dm.intent.REGISTRATION&quot; /&gt;
    105     &lt;category android:name=&quot;my_app_package&quot; /&gt;
    106   &lt;/intent-filter&gt;
    107 &lt;/receiver&gt;</pre>
    108 <p> This broadcast receiver is responsible for handling the 2 intents that can be sent by GCM (<code>com.google.android.c2dm.intent.RECEIVE</code> and <code>com.google.android.c2dm.intent.REGISTRATION</code>) and should be defined in the manifest (rather than programmatically) so that these intents can be received even if the application is not running. By setting the <code>com.google.android.c2dm.permission.SEND</code> permission, you are ensuring that only intents sent by the GCM system framework are sent to the receiver (a regular application cannot issue intents with that permission).</p>
    109 <p> Notice that <code>android:name</code> in the category tag must be replaced by your application's package name (and the category tag  is not required for applications targeted to minSdkVersion 16 and higher).<br>
    110   </p>
    111 
    112   <li>Add the following intent service:</li>
    113 
    114 
    115  <pre class="prettyprint pretty-xml">&lt;service android:name=&quot;.GCMIntentService&quot; /&gt;</pre>
    116 
    117 </ol>
    118 <p>This intent service will be called by the <code>GCMBroadcastReceiver</code> (which is provided by the GCM library), as shown in the next step. It must be a subclass of <code>com.google.android.gcm.GCMBaseIntentService</code>, must contain a public constructor, and should be named <code>my_app_package.GCMIntentService</code> (unless you use a subclass of <code>GCMBroadcastReceiver</code> that overrides the method used to name the service).</p>
    119 
    120 <p>The intent service must also define its sender ID(s). It does this as follows:</p>
    121 <ul>
    122   <li>If the value is static, the service's default constructor should call <code>super(senderIds)</code>.</li>
    123   <li>If the value is dynamic, the service should override the <code>getSenderIds()</code> method.</li>
    124 </ul>
    125 
    126 
    127 <h4>Step 3: Write the my_app_package.GCMIntentService class</h4>
    128 
    129 <p>Next write the <code>my_app_package.GCMIntentService</code> class, overriding the following callback methods (which are called by <code>GCMBroadcastReceiver</code>):<br>
    130 </p>
    131 <ul>
    132   <li><code>onRegistered(Context context, String regId)</code>: Called after a registration intent is received, passes the registration ID assigned by GCM to that device/application pair as parameter. Typically, you should send the <code>regid</code> to your server so it can use it to send messages to this device.</li>
    133   <li><code>onUnregistered(Context context, String regId)</code>: Called after the device has been unregistered from GCM. Typically, you should send the <code>regid</code> to the server so it unregisters the device.</li>
    134   <li><code>onMessage(Context context, Intent intent)</code>: Called when your server sends a message to GCM, and GCM delivers it to the device. If the message has a payload, its contents are available as extras in the intent.</li>
    135   <li><code>onError(Context context, String errorId)</code>: Called when the device tries to register or unregister, but GCM returned an error. Typically, there is nothing to be done other than evaluating the error (returned by errorId) and trying to fix the problem.</li>
    136   <li> <code>onRecoverableError(Context context, String errorId)</code>: Called when the device tries to register or unregister, but the GCM servers are unavailable. The GCM library will retry the operation using exponential backup, unless this method is overridden and returns false. This method is optional and should be overridden only if you want to display the message to the user or cancel the retry attempts. 
    137   </li>
    138 </ul>
    139 
    140 <p class="note"><strong>Note:</strong> The methods above run in the intent service's thread and hence are free to make network calls without the risk of blocking the UI thread.</p>
    141 
    142 <h4> Step 4: Write your application's main activity</h4>
    143 Add the following import statement in your application's main activity:
    144 <pre class="prettyprint pretty-java">import com.google.android.gcm.GCMRegistrar;</pre>
    145 <p> In the <code>onCreate()</code> method, add the following code:</p>
    146 <pre class="prettyprint pretty-java">GCMRegistrar.checkDevice(this);
    147 GCMRegistrar.checkManifest(this);
    148 final String regId = GCMRegistrar.getRegistrationId(this);
    149 if (regId.equals("")) {
    150   GCMRegistrar.register(this, SENDER_ID);
    151 } else {
    152   Log.v(TAG, "Already registered");
    153 }</pre>
    154 <p>The <code>checkDevice()</code> method verifies that the device supports GCM and throws an exception if it does not (for instance, if it is an emulator that does not contain the Google APIs). Similarly, the <code>checkManifest()</code> method verifies that the application manifest contains meets all the requirements described in <a href="#android-app">Writing the Android Application</a> (this method is only necessary when you are developing the application; once the application is ready to be published, you can remove it).</p>
    155 
    156 <p>Once the sanity checks are done, the device calls <code>GCMRegsistrar.register()</code> to register the device, passing the <code>SENDER_ID</code> you got when you signed up for GCM. But since the <code>GCMRegistrar</code> singleton keeps track of the registration ID upon the arrival of registration intents, you can call <code>GCMRegistrar.getRegistrationId()</code> first to check if the device is already registered.</p>
    157 <p class="note"><strong>Note:</strong> It is possible that the device was successfully registered to GCM but failed to send the registration ID to your server, in which case you should retry. See <a href="adv.html#reg-state">Advanced Topics</a> for more details on how to handle this scenario.</p>
    158 
    159 <h2 id="server-app">Writing the Server-side Application</h2>
    160 
    161 <p>To write the server-side application:</p>
    162 <ol>
    163   <li> Copy the <code>gcm-server.jar</code> file from the SDK's <code>gcm-server/dist</code> directory to your server classpath.</li>
    164   <li>Create a servlet (or other server-side mechanism) that can be used by the Android application to send the registration ID received by GCM . The application might also need to send other information&mdash;such as the user's email address or username&mdash;so that the server can associate the registration ID with the user owning the device.</li>
    165   <li>Similarly, create a servlet used to unregister registration IDs.<br>
    166     </li>
    167 <li>When the server needs to send a message to the registration ID, it can use the <code>com.google.android.gcm.server.Sender</code> helper class from the GCM library. For example:</li>
    168 </ol>
    169 
    170 <pre class="prettyprint pretty-java">import com.google.android.gcm.server.*;
    171 
    172 Sender sender = new Sender(myApiKey);
    173 Message message = new Message.Builder().build();
    174 MulticastResult result = sender.send(message, devices, 5);</pre>
    175 
    176 <p> The snippet above does the following:
    177 <ul>
    178 <li>Creates a <code>Sender</code> object using your project's API key.</li>
    179 <li>Creates a message using a given registration ID (the message builder also has methods to set all message parameters such as the collapse key and payload data).</li>
    180 <li>Sends the message with a maximum of 5 retry attempts (in case the GCM servers are unavailable), and stores the response on result. </li>
    181 </ul>
    182 <p>It's now necessary to parse the result and take the proper action in the following cases:</p>
    183 <ul>
    184   <li>If the message was created but the result returned a canonical registration ID, it's necessary to replace the current registration ID with the canonical one.</li>
    185   <li>If the returned error is <code>NotRegistered</code>, it's necessary to remove that registration ID, because the application was uninstalled from the device.</li>
    186 </ul>
    187 <p> Here's a code snippet that handles these 2 conditions:</p>
    188 <pre class="prettyprint pretty-java">
    189 if (result.getMessageId() != null) {
    190  String canonicalRegId = result.getCanonicalRegistrationId();
    191  if (canonicalRegId != null) {
    192    // same device has more than on registration ID: update database
    193  }
    194 } else {
    195  String error = result.getErrorCodeName();
    196  if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
    197    // application has been removed from device - unregister database
    198  }
    199 }</pre>
    200