Google 使用 java EE 的云消息传递

Google Cloud messaging with java EE

是否有关于使用 Java EE 的 google 云消息传递的任何好的教程,其中包含详细记录的代码......

http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/

使用 php。 我正在 android 中使用 websockets 制作聊天应用程序。 我有一个 android 到 websocket 端点 class 交互的工作代码。唯一的问题是如何在当前环境中使用GCM。

请指导

这是有史以来最好的 GCM 教程:

http://javapapers.com/android/google-cloud-messaging-gcm-for-android-and-push-notifications/

PHP 服务器代码:

    <?php
        //generic php function to send GCM push notification
       function sendPushNotificationToGCM($registatoin_ids, $message) {
            //Google cloud messaging GCM-API url
            $url = 'https://android.googleapis.com/gcm/send';
            $fields = array(
                'registration_ids' => $registatoin_ids,
                'data' => $message,
            );
            // Google Cloud Messaging GCM API Key
            define("GOOGLE_API_KEY", "AIzaSyDA5dlLInMWVsJEUTIHV0u7maB82MCsZbU");        
            $headers = array(
                'Authorization: key=' . GOOGLE_API_KEY,
                'Content-Type: application/json'
            );
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);   
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
            $result = curl_exec($ch);               
            if ($result === FALSE) {
                die('Curl failed: ' . curl_error($ch));
            }
            curl_close($ch);
            return $result;
        }
    ?>
    <?php

        //this block is to post message to GCM on-click
        $pushStatus = "";   
        if(!empty($_GET["push"])) { 
            $gcmRegID  = file_get_contents("GCMRegId.txt");
            $pushMessage = $_POST["message"];   
            if (isset($gcmRegID) && isset($pushMessage)) {      
                $gcmRegIds = array($gcmRegID);
                $message = array("m" => $pushMessage);  
                $pushStatus = sendPushNotificationToGCM($gcmRegIds, $message);
            }       
        }

        //this block is to receive the GCM regId from external (mobile apps)
        if(!empty($_GET["shareRegId"])) {
            $gcmRegID  = $_POST["regId"]; 
            file_put_contents("GCMRegId.txt",$gcmRegID);
            echo "Ok!";
            exit;
        }   
    ?>
    <html>
        <head>
            <title>Google Cloud Messaging (GCM) Server in PHP</title>
        </head>
        <body>
            <h1>Google Cloud Messaging (GCM) Server in PHP</h1> 
            <form method="post" action="gcm.php/?push=1">                                                
                <div>                                
                    <textarea rows="2" name="message" cols="23" placeholder="Message to transmit via GCM"></textarea>
                </div>
                <div><input type="submit"  value="Send Push Notification via GCM" /></div>
            </form>
            <p><h3><?php echo $pushStatus; ?></h3></p>        
        </body>
    </html>

或Java服务器:

index.jsp:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <%
        String pushStatus = "";
        Object pushStatusObj = request.getAttribute("pushStatus");

        if (pushStatusObj != null) {
            pushStatus = pushStatusObj.toString();
        }
    %>
    <head>
    <title>Google Cloud Messaging (GCM) Server in PHP</title>
    </head>
    <body>

        <h1>Google Cloud Messaging (GCM) Server in Java</h1>

        <form action="GCMNotification" method="post">

            <div>
                <textarea rows="2" name="message" cols="23"
                    placeholder="Message to transmit via GCM"></textarea>
            </div>
            <div>
                <input type="submit" value="Send Push Notification via GCM" />
            </div>
        </form>
        <p>
            <h3>
                <%=pushStatus%>
            </h3>
        </p>
    </body>
    </html>

GCMNotification.java:

    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.PrintWriter;

    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import com.google.android.gcm.server.Message;
    import com.google.android.gcm.server.Result;
    import com.google.android.gcm.server.Sender;

    @WebServlet("/GCMNotification")
    public class GCMNotification extends HttpServlet {
        private static final long serialVersionUID = 1L;

        // Put your Google API Server Key here
        private static final String GOOGLE_SERVER_KEY = "AIzaSyDA5dlLInMWVsJEUTIHV0u7maB82MCsZbU";
        static final String MESSAGE_KEY = "message";    

        public GCMNotification() {
            super();
        }

        protected void doGet(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);

        }

        protected void doPost(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {


            Result result = null;

            String share = request.getParameter("shareRegId");

            // GCM RedgId of Android device to send push notification
            String regId = "";
            if (share != null && !share.isEmpty()) {
                regId = request.getParameter("regId");
                PrintWriter writer = new PrintWriter("GCMRegId.txt");
                writer.println(regId);
                writer.close();
                request.setAttribute("pushStatus", "GCM RegId Received.");
                request.getRequestDispatcher("index.jsp")
                        .forward(request, response);
            } else {

                try {
                    BufferedReader br = new BufferedReader(new FileReader(
                            "GCMRegId.txt"));
                    regId = br.readLine();
                    br.close();
                    String userMessage = request.getParameter("message");
                    Sender sender = new Sender(GOOGLE_SERVER_KEY);
                    Message message = new Message.Builder().timeToLive(30)
                            .delayWhileIdle(true).addData(MESSAGE_KEY, userMessage).build();
                    System.out.println("regId: " + regId);
                    result = sender.send(message, regId, 1);
                    request.setAttribute("pushStatus", result.toString());
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                    request.setAttribute("pushStatus",
                            "RegId required: " + ioe.toString());
                } catch (Exception e) {
                    e.printStackTrace();
                    request.setAttribute("pushStatus", e.toString());
                }
                request.getRequestDispatcher("index.jsp")
                        .forward(request, response);
            }
        }
    }

对于设备端的 GCM 需要这些东西:

  1. Google 在 SDK 中播放服务
  2. Google API
  3. Google Play Services Lib 项目作为 Android 依赖项
  4. Google 项目编号

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="yourPkgName"
android:versionCode="1"
android:versionName="1.0" >

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<permission
    android:name="yourPkgName.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="yourPkgName.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />

<uses-sdk
    android:minSdkVersion="9"
    android:targetSdkVersion="16" />

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    ...
    <receiver
        android:name=".GcmBroadcastReceiver"
        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="yourPkgName" />
        </intent-filter>
    </receiver>

    <service android:name=".GCMNotificationIntentService" />
</application>

</manifest>

GCMNotificationIntentService.java:

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;

public class GCMNotificationIntentService extends IntentService {

    public static final int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;

    public GCMNotificationIntentService() {
        super("GcmIntentService");
    }

    public static final String TAG = "GCMNotificationIntentService";

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);

        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty()) {
            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());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
                    .equals(messageType)) {

                for (int i = 0; i < 3; i++) {
                    Log.i(TAG,
                            "Working... " + (i + 1) + "/5 @ "
                                    + SystemClock.elapsedRealtime());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                    }

                }
                Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());

                sendNotification("Message Received from Google GCM Server: "
                        + extras.get(Config.MESSAGE_KEY));
                Log.i(TAG, "Received: " + extras.toString());
            }
        }
        GcmBroadcastReceiver.completeWakefulIntent(intent);
    }

    private void sendNotification(String msg) {
        Log.d(TAG, "Preparing to send notification...: " + msg);
        mNotificationManager = (NotificationManager) this
                .getSystemService(Context.NOTIFICATION_SERVICE);

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, MainActivity.class), 0);

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                this).setSmallIcon(R.drawable.gcm_cloud)
                .setContentTitle("GCM Notification")
                .setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
                .setContentText(msg);

        mBuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
        Log.d(TAG, "Notification sent successfully.");
    }
}

GcmBroadcastReceiver.java:

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        ComponentName comp = new ComponentName(context.getPackageName(),
                GCMNotificationIntentService.class.getName());
        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
    }
}

所以现在您只需要调用 registerInBackground() 方法并将 regId 发送到您的服务器:

    private void registerInBackground() {
        new AsyncTask() {
            @Override
            protected String doInBackground(Void... params) {
                String msg = "";
                try {
                    if (gcm == null) {
                        gcm = GoogleCloudMessaging.getInstance(context);
                    }
                    regId = gcm.register(Config.GOOGLE_PROJECT_ID);
                    Log.d("RegisterActivity", "registerInBackground - regId: "
                            + regId);
                    msg = "Device registered, registration ID=" + regId;
                    //Save in preferences and send to your server
                    storeRegistrationId(context, regId);
                } catch (IOException ex) {
                    msg = "Error :" + ex.getMessage();
                    Log.d("RegisterActivity", "Error: " + msg);
                }
                Log.d("RegisterActivity", "AsyncTask completed: " + msg);
                return msg;
            }

            @Override
            protected void onPostExecute(String msg) {
                Toast.makeText(getApplicationContext(),
                        "Registered with GCM Server." + msg, Toast.LENGTH_LONG)
                        .show();
            }
        }.execute(null, null, null);
    }

发送regId到服务器的例子:

    public String shareRegIdWithAppServer(final Context context, final String regId) {

        String result = "";
        Map paramsMap = new HashMap();
        paramsMap.put("regId", regId);
        try {
            URL serverUrl = null;
            try {
                serverUrl = new URL(Config.APP_SERVER_URL);
            } catch (MalformedURLException e) {
                Log.e("AppUtil", "URL Connection Error: " + Config.APP_SERVER_URL, e);
                result = "Invalid URL: " + Config.APP_SERVER_URL;
            }
            StringBuilder postBody = new StringBuilder();
            Iterator> iterator = paramsMap.entrySet().iterator();

            while (iterator.hasNext()) {
                Entry param = iterator.next();
                postBody.append(param.getKey()).append('=').append(param.getValue());
                if (iterator.hasNext()) {
                    postBody.append('&');
                }
            }
            String body = postBody.toString();
            byte[] bytes = body.getBytes();
            HttpURLConnection httpCon = null;
            try {
                httpCon = (HttpURLConnection) serverUrl.openConnection();
                httpCon.setDoOutput(true);
                httpCon.setUseCaches(false);
                httpCon.setFixedLengthStreamingMode(bytes.length);
                httpCon.setRequestMethod("POST");
                httpCon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
                OutputStream out = httpCon.getOutputStream();
                out.write(bytes);
                out.close();
                int status = httpCon.getResponseCode();
                if (status == 200) {
                    result = "RegId shared with Application Server. RegId: " + regId;
                } else {
                    result = "Post Failure." + " Status: " + status;
                }
            } finally {
                if (httpCon != null) {
                    httpCon.disconnect();
                }
            }

        } catch (IOException e) {
            result = "Post Failure. Error in sharing with App Server.";
            Log.e("AppUtil", "Error in sharing with App Server: " + e);
        }
        return result;
    }