(一) 在上一章,我们提到Android 消息推送的基本流程和需要的几个键值。
这里介绍一下怎样使用Google Cloud Messaging (GCM)。
对于GCM的实现,google 早期使用的接口可以参考这篇文章。文章中已经充分介绍了在老接口下怎样实现GCM。
http://blog.csdn.net/huangjialiang1986/article/details/8056221
下面是对这篇文章代码的部分更改:
Android 客户端的代码为:
https://github.com/yuxiaohui78/Google_Cloud_Messaging/tree/master/GCMClientOnMobile_deprecated_version
模拟第三方服务器的消息发送部分代码:
https://github.com/yuxiaohui78/Google_Cloud_Messaging/tree/master/GCMSendOnPC
(二)由于google已经决定废弃老接口。所以下面我们来介绍一下新接口怎样实现。
新的Api接口需要google service 3.1+ 的支持。
1.在AndroidManifest.xml 中增加支持,允许接收云消息com.google.android.c2dm.permission.RECEIVE
<manifest package="com.example.gcm" ...> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/> <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=".GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <category android:name="com.example.gcm" /> </intent-filter> </receiver> <service android:name=".GcmIntentService" /> </application> </manifest>
/** * Main UI for the demo app. */ public class DemoActivity extends Activity { public static final String EXTRA_MESSAGE = "message"; public static final String PROPERTY_REG_ID = "registration_id"; private static final String PROPERTY_APP_VERSION = "appVersion"; private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; /** * Substitute you own sender ID here. This is the project number you got * from the API Console, as described in "Getting Started." */ String SENDER_ID = "Your-Sender-ID"; /** * Tag used on log messages. */ static final String TAG = "GCMDemo"; TextView mDisplay; GoogleCloudMessaging gcm; AtomicInteger msgId = new AtomicInteger(); SharedPreferences prefs; Context context; String regid; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mDisplay = (TextView) findViewById(R.id.display); context = getApplicationContext(); // Check device for Play Services APK. If check succeeds, proceed with // GCM registration. if (checkPlayServices()) { gcm = GoogleCloudMessaging.getInstance(this); regid = getRegistrationId(context); if (regid.isEmpty()) { registerInBackground(); } } else { Log.i(TAG, "No valid Google Play Services APK found."); } } ... }
/** * Registers the application with GCM servers asynchronously. * <p> * Stores the registration ID and app versionCode in the application's * shared preferences. */ private void registerInBackground() { new AsyncTask() { @Override protected String doInBackground(Void... params) { String msg = ""; try { if (gcm == null) { gcm = GoogleCloudMessaging.getInstance(context); } regid = gcm.register(SENDER_ID); msg = "Device registered, registration ID=" + regid; // You should send the registration ID to your server over HTTP, // so it can use GCM/HTTP or CCS to send messages to your app. // The request to your server should be authenticated if your app // is using accounts. sendRegistrationIdToBackend(); // For this demo: we don't need to send it because the device // will send upstream messages to a server that echo back the // message using the 'from' address in the message. // Persist the regID - no need to register again. storeRegistrationId(context, regid); } catch (IOException ex) { msg = "Error :" + ex.getMessage(); // If there is an error, don't just keep trying to register. // Require the user to click a button again, or perform // exponential back-off. } return msg; } @Override protected void onPostExecute(String msg) { mDisplay.append(msg + "\n"); } }.execute(null, null, null); ... }
public class GcmIntentService extends IntentService { public static final int NOTIFICATION_ID = 1; private NotificationManager mNotificationManager; NotificationCompat.Builder builder; public GcmIntentService() { super("GcmIntentService"); } @Override protected void onHandleIntent(Intent intent) { Bundle extras = intent.getExtras(); GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); // The getMessageType() intent parameter must be the intent you received // in your BroadcastReceiver. String messageType = gcm.getMessageType(intent); if (!extras.isEmpty()) { // has effect of unparcelling Bundle /* * Filter messages based on message type. Since it is likely that GCM * will be extended in the future with new message types, just ignore * any message types you're not interested in, or that you don't * recognize. */ if (GoogleCloudMessaging. MESSAGE_TYPE_SEND_ERROR.equals(messageType)) { sendNotification("Send error: " + extras.toString()); } else if (GoogleCloudMessaging. MESSAGE_TYPE_DELETED.equals(messageType)) { sendNotification("Deleted messages on server: " + extras.toString()); // If it's a regular GCM message, do some work. } else if (GoogleCloudMessaging. MESSAGE_TYPE_MESSAGE.equals(messageType)) { // This loop represents the service doing some work. for (int i=0; i<5; i++) { Log.i(TAG, "Working... " + (i+1) + "/5 @ " + SystemClock.elapsedRealtime()); try { Thread.sleep(5000); } catch (InterruptedException e) { } } Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime()); // Post notification of received message. sendNotification("Received: " + extras.toString()); Log.i(TAG, "Received: " + extras.toString()); } } // Release the wake lock provided by the WakefulBroadcastReceiver. GcmBroadcastReceiver.completeWakefulIntent(intent); } // Put the message into a notification and post it. // This is just one simple example of what you might choose to do with // a GCM message. private void sendNotification(String msg) { mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, DemoActivity.class), 0); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_stat_gcm) .setContentTitle("GCM Notification") .setStyle(new NotificationCompat.BigTextStyle() .bigText(msg)) .setContentText(msg); mBuilder.setContentIntent(contentIntent); mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build()); } }
可用的代码:
https://github.com/yuxiaohui78/Google_Cloud_Messaging/tree/master/GCMClientOnMobile
使用代码的方法很简单,只需要将DemoActivity.java中的SENDER_ID替换为上一章中的Project Number就可以使用。
下一章,将介绍怎样测试Google Cloud Messaging。
http://developer.android.com/google/gcm/client.html
原始代码:
https://code.google.com/p/gcm/source/checkout