首页 文章

使用PHP的GCM(Google Cloud Messaging)

提问于
浏览
207

更新:不推荐使用GCM,请使用FCM

如何在PHP后端中集成新的Google Cloud Messaging

12 回答

  • 10

    此代码将通过PHP CURL向多个注册ID发送GCM消息 .

    // Payload data you want to send to Android device(s)
    // (it will be accessible via intent extras)    
    $data = array('message' => 'Hello World!');
    
    // The recipient registration tokens for this notification
    // https://developer.android.com/google/gcm/    
    $ids = array('abc', 'def');
    
    // Send push notification via Google Cloud Messaging
    sendPushNotification($data, $ids);
    
    function sendPushNotification($data, $ids) {
        // Insert real GCM API key from the Google APIs Console
        // https://code.google.com/apis/console/        
        $apiKey = 'abc';
    
        // Set POST request body
        $post = array(
                        'registration_ids'  => $ids,
                        'data'              => $data,
                     );
    
        // Set CURL request headers 
        $headers = array( 
                            'Authorization: key=' . $apiKey,
                            'Content-Type: application/json'
                        );
    
        // Initialize curl handle       
        $ch = curl_init();
    
        // Set URL to GCM push endpoint     
        curl_setopt($ch, CURLOPT_URL, 'https://gcm-http.googleapis.com/gcm/send');
    
        // Set request method to POST       
        curl_setopt($ch, CURLOPT_POST, true);
    
        // Set custom request headers       
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    
        // Get the response back as string instead of printing it       
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
        // Set JSON post data
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post));
    
        // Actually send the request    
        $result = curl_exec($ch);
    
        // Handle errors
        if (curl_errno($ch)) {
            echo 'GCM error: ' . curl_error($ch);
        }
    
        // Close curl handle
        curl_close($ch);
    
        // Debug GCM response       
        echo $result;
    }
    
  • 233
    <?php
        // Replace with the real server API key from Google APIs
        $apiKey = "your api key";
    
        // Replace with the real client registration IDs
        $registrationIDs = array( "reg id1","reg id2");
    
        // Message to be sent
        $message = "hi Shailesh";
    
        // Set POST variables
        $url = 'https://android.googleapis.com/gcm/send';
    
        $fields = array(
            'registration_ids' => $registrationIDs,
            'data' => array( "message" => $message ),
        );
        $headers = array(
            'Authorization: key=' . $apiKey,
            'Content-Type: application/json'
        );
    
        // Open connection
        $ch = curl_init();
    
        // Set the URL, number of POST vars, POST data
        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_POSTFIELDS, json_encode( $fields));
    
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        // curl_setopt($ch, CURLOPT_POST, true);
        // curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode( $fields));
    
        // Execute post
        $result = curl_exec($ch);
    
        // Close connection
        curl_close($ch);
        echo $result;
        //print_r($result);
        //var_dump($result);
    ?>
    
  • 13

    这很容易做到 . Elad Nava在这里放置的页面上的cURL代码有效 . Elad有commented about the error他正在收到 .

    描述处理该收件人的邮件时发生的错误的字符串 . 可能的值与上表中记录的相同,加上“不可用”(意味着GCM服务器很忙,无法处理该特定收件人的消息,因此可以重试) .

    我已经设置了一个似乎正在运行的服务(ish),到目前为止我所有的回复都是谷歌提供的 . 这很可能会很快改变 .

    要回答这个问题,请使用PHP,确保Zend Framework在您的包含路径中,并使用以下代码:

    <?php
        ini_set('display_errors',1);
        include"Zend/Loader/Autoloader.php";
        Zend_Loader_Autoloader::getInstance();
    
        $url = 'https://android.googleapis.com/gcm/send';
        $serverApiKey = "YOUR API KEY AS GENERATED IN API CONSOLE";
        $reg = "DEVICE REGISTRATION ID";
    
        $data = array(
                'registration_ids' => array($reg),
                'data' => array('yourname' => 'Joe Bloggs')
        );
    
        print(json_encode($data));
    
        $client = new Zend_Http_Client($url);
        $client->setMethod('POST');
        $client->setHeaders(array("Content-Type" => "application/json", "Authorization" => "key=" . $serverApiKey));
        $client->setRawData(json_encode($data));
        $request = $client->request('POST');
        $body = $request->getBody();
        $headers = $request->getHeaders();
        print("<xmp>");
        var_dump($body);
        var_dump($headers);
    

    我们终于得到它了 . 在Zend Framework PHP中使用Googles new GCM的一个工作(它将很快工作)的例子 .

  • 0

    经过很长一段时间的搜索,我终于找到了我真正需要的东西,使用PHP作为服务器端脚本语言连接到GCM,以下教程将让我们清楚地了解如何设置我们开始所需的一切与GCM

    Android Push Notifications using Google Cloud Messaging (GCM), PHP and MySQL

  • 4

    我实际上现在在Zend_Mobile树的一个分支中工作:https://github.com/mwillbanks/Zend_Mobile/tree/feature/gcm

    这将与ZF 1.12一起发布,但它应该给你一些很好的例子来说明如何做到这一点 .

    这是一个关于它如何工作的快速演示....

    <?php
    require_once 'Zend/Mobile/Push/Gcm.php';
    require_once 'Zend/Mobile/Push/Message/Gcm.php';
    
    $message = new Zend_Mobile_Push_Message_Gcm();
    $message->setId(time());
    $message->addToken('ABCDEF0123456789');
    $message->setData(array(
        'foo' => 'bar',
        'bar' => 'foo',
    ));
    
    $gcm = new Zend_Mobile_Push_Gcm();
    $gcm->setApiKey('MYAPIKEY');
    
    $response = false;
    
    try {
        $response = $gcm->send($message);
    } catch (Zend_Mobile_Push_Exception $e) {
        // all other exceptions only require action to be sent or implementation of exponential backoff.
        die($e->getMessage());
    }
    
    // handle all errors and registration_id's
    foreach ($response->getResults() as $k => $v) {
        if ($v['registration_id']) {
            printf("%s has a new registration id of: %s\r\n", $k, $v['registration_id']);
        }
        if ($v['error']) {
            printf("%s had an error of: %s\r\n", $k, $v['error']);
        }
        if ($v['message_id']) {
            printf("%s was successfully sent the message, message id is: %s", $k, $v['message_id']);
        }
    }
    
  • 0

    许多教程已经过时,甚至当前代码也没有说明何时更新设备registration_ids或取消注册设备 . 如果这些项目未经检查,最终将导致阻止接收邮件的问题 . http://forum.loungekatt.com/viewtopic.php?t=63#p181

  • 6

    你也可以试试这段代码,source

    <?php
        define("GOOGLE_API_KEY", "AIzaSyCJiVkatisdQ44rEM353PFGbia29mBVscA");
        define("GOOGLE_GCM_URL", "https://android.googleapis.com/gcm/send");
    
        function send_gcm_notify($reg_id, $message) {
            $fields = array(
                'registration_ids'  => array( $reg_id ),
                'data'              => array( "message" => $message ),
            );
    
            $headers = array(
                'Authorization: key=' . GOOGLE_API_KEY,
                'Content-Type: application/json'
            );
    
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, GOOGLE_GCM_URL);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
    
            $result = curl_exec($ch);
            if ($result === FALSE) {
                die('Problem occurred: ' . curl_error($ch));
            }
    
            curl_close($ch);
            echo $result;
        }
    
        $reg_id = "APA91bHuSGES.....nn5pWrrSz0dV63pg";
        $msg = "Google Cloud Messaging working well";
    
        send_gcm_notify($reg_id, $msg);
    
  • 2
    <?php
    
    function sendMessageToPhone($deviceToken, $collapseKey, $messageText, $yourKey) {    
        echo "DeviceToken:".$deviceToken."Key:".$collapseKey."Message:".$messageText
                ."API Key:".$yourKey."Response"."
    "; $headers = array('Authorization:key=' . $yourKey); $data = array( 'registration_id' => $deviceToken, 'collapse_key' => $collapseKey, 'data.message' => $messageText); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://android.googleapis.com/gcm/send"); if ($headers) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $response = curl_exec($ch); var_dump($response); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if (curl_errno($ch)) { return false; } if ($httpCode != 200) { return false; } curl_close($ch); return $response; } $yourKey = "YOURKEY"; $deviceToken = "REGISTERED_ID"; $collapseKey = "COLLAPSE_KEY"; $messageText = "MESSAGE"; echo sendMessageToPhone($deviceToken, $collapseKey, $messageText, $yourKey); ?>

    在上面的脚本中只需更改:

    “YOURKEY”到API控制台的服务器密钥的API密钥 . “REGISTERED_ID”,您的设备的注册ID“COLLAPSE_KEY”,其中包含您要发送的消息“MESSAGE”的密钥

    如果您在此处遇到任何问题,请告诉我,我可以使用相同的脚本成功获得通知 .

  • 34

    你可以在packagist上使用这个PHP库:

    https://github.com/CoreProc/gcm-php

    安装后你可以这样做:

    $gcmClient = new GcmClient('your-gcm-api-key-here');
    
    $message = new Message($gcmClient);
    
    $message->addRegistrationId('xxxxxxxxxx');
    $message->setData([
        'title' => 'Sample Push Notification',
        'message' => 'This is a test push notification using Google Cloud Messaging'
    ]);
    
    try {
    
        $response = $message->send();
    
        // The send() method returns a Response object
        print_r($response);
    
    } catch (Exception $exception) {
    
        echo 'uh-oh: ' . $exception->getMessage();
    
    }
    
  • 18

    这是我从CodeMonkeysRU分叉的库 .

    我分叉的原因是因为谷歌要求指数退避 . 我使用redis服务器对消息进行排队,并在设定的时间后重新发送 .

    我也更新了它以支持iOS .

    https://github.com/stevetauber/php-gcm-queue

  • 6

    这是由@Elad Nava发布的上面PHP代码的android代码

    MainActivity.java (Launcher Activity)

    public class MainActivity extends AppCompatActivity {
        String PROJECT_NUMBER="your project number/sender id";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    
    
            GCMClientManager pushClientManager = new GCMClientManager(this, PROJECT_NUMBER);
            pushClientManager.registerIfNeeded(new GCMClientManager.RegistrationCompletedHandler() {
                @Override
                public void onSuccess(String registrationId, boolean isNewRegistration) {
    
                    Log.d("Registration id", registrationId);
                    //send this registrationId to your server
                }
    
                @Override
                public void onFailure(String ex) {
                    super.onFailure(ex);
                }
            });
        }
    }
    

    GCMClientManager.java

    public class GCMClientManager {
        // Constants
        public static final String TAG = "GCMClientManager";
        public static final String EXTRA_MESSAGE = "message";
        public static final String PROPERTY_REG_ID = "your sender id";
        private static final String PROPERTY_APP_VERSION = "appVersion";
        private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
        // Member variables
        private GoogleCloudMessaging gcm;
        private String regid;
        private String projectNumber;
        private Activity activity;
        public GCMClientManager(Activity activity, String projectNumber) {
            this.activity = activity;
            this.projectNumber = projectNumber;
            this.gcm = GoogleCloudMessaging.getInstance(activity);
        }
        /**
         * @return Application's version code from the {@code PackageManager}.
         */
        private static int getAppVersion(Context context) {
            try {
                PackageInfo packageInfo = context.getPackageManager()
                        .getPackageInfo(context.getPackageName(), 0);
                return packageInfo.versionCode;
            } catch (NameNotFoundException e) {
                // should never happen
                throw new RuntimeException("Could not get package name: " + e);
            }
        }
        // Register if needed or fetch from local store
        public void registerIfNeeded(final RegistrationCompletedHandler handler) {
            if (checkPlayServices()) {
                regid = getRegistrationId(getContext());
                if (regid.isEmpty()) {
                    registerInBackground(handler);
                } else { // got id from cache
                    Log.i(TAG, regid);
                    handler.onSuccess(regid, false);
                }
            } else { // no play services
                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(final RegistrationCompletedHandler handler) {
            new AsyncTask<Void, Void, String>() {
                @Override
                protected String doInBackground(Void... params) {
                    try {
                        if (gcm == null) {
                            gcm = GoogleCloudMessaging.getInstance(getContext());
                        }
                        InstanceID instanceID = InstanceID.getInstance(getContext());
                        regid = instanceID.getToken(projectNumber, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
                        Log.i(TAG, regid);
                        // Persist the regID - no need to register again.
                        storeRegistrationId(getContext(), regid);
                    } catch (IOException ex) {
                        // 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.
                        handler.onFailure("Error :" + ex.getMessage());
                    }
                    return regid;
                }
                @Override
                protected void onPostExecute(String regId) {
                    if (regId != null) {
                        handler.onSuccess(regId, true);
                    }
                }
            }.execute(null, null, null);
        }
        /**
         * Gets the current registration ID for application on GCM service.
         * <p>
         * If result is empty, the app needs to register.
         *
         * @return registration ID, or empty string if there is no existing
         *     registration ID.
         */
        private String getRegistrationId(Context context) {
            final SharedPreferences prefs = getGCMPreferences(context);
            String registrationId = prefs.getString(PROPERTY_REG_ID, "");
            if (registrationId.isEmpty()) {
                Log.i(TAG, "Registration not found.");
                return "";
            }
            // Check if app was updated; if so, it must clear the registration ID
            // since the existing regID is not guaranteed to work with the new
            // app version.
            int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
            int currentVersion = getAppVersion(context);
            if (registeredVersion != currentVersion) {
                Log.i(TAG, "App version changed.");
                return "";
            }
            return registrationId;
        }
        /**
         * Stores the registration ID and app versionCode in the application's
         * {@code SharedPreferences}.
         *
         * @param context application's context.
         * @param regId registration ID
         */
        private void storeRegistrationId(Context context, String regId) {
            final SharedPreferences prefs = getGCMPreferences(context);
            int appVersion = getAppVersion(context);
            Log.i(TAG, "Saving regId on app version " + appVersion);
            SharedPreferences.Editor editor = prefs.edit();
            editor.putString(PROPERTY_REG_ID, regId);
            editor.putInt(PROPERTY_APP_VERSION, appVersion);
            editor.commit();
        }
        private SharedPreferences getGCMPreferences(Context context) {
            // This sample app persists the registration ID in shared preferences, but
            // how you store the regID in your app is up to you.
            return getContext().getSharedPreferences(context.getPackageName(),
                    Context.MODE_PRIVATE);
        }
        /**
         * Check the device to make sure it has the Google Play Services APK. If
         * it doesn't, display a dialog that allows users to download the APK from
         * the Google Play Store or enable it in the device's system settings.
         */
        private boolean checkPlayServices() {
            int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getContext());
            if (resultCode != ConnectionResult.SUCCESS) {
                if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                    GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(),
                            PLAY_SERVICES_RESOLUTION_REQUEST).show();
                } else {
                    Log.i(TAG, "This device is not supported.");
                }
                return false;
            }
            return true;
        }
        private Context getContext() {
            return activity;
        }
        private Activity getActivity() {
            return activity;
        }
        public static abstract class RegistrationCompletedHandler {
            public abstract void onSuccess(String registrationId, boolean isNewRegistration);
            public void onFailure(String ex) {
                // 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.
                Log.e(TAG, ex);
            }
        }
    }
    

    PushNotificationService.java (通知发生器)

    public class PushNotificationService extends GcmListenerService{
    
        public static int MESSAGE_NOTIFICATION_ID = 100;
    
        @Override
        public void onMessageReceived(String from, Bundle data) {
            String message = data.getString("message");
            sendNotification("Hi-"+message, "My App sent you a message");
        }
    
        private void sendNotification(String title, String body) {
            Context context = getBaseContext();
            NotificationCompat.Builder mBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(context)
                    .setSmallIcon(R.mipmap.ic_launcher).setContentTitle(title)
                    .setContentText(body);
            NotificationManager mNotificationManager = (NotificationManager) context
                    .getSystemService(Context.NOTIFICATION_SERVICE);
            mNotificationManager.notify(MESSAGE_NOTIFICATION_ID, mBuilder.build());
        }
    }
    

    AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    
    <uses-permission android:name="android.permission.INTERNET" />
    <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
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    
        <service
            android:name=".PushNotificationService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>
    
        <receiver
            android:name="com.google.android.gms.gcm.GcmReceiver"
            android:exported="true"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="package.gcmdemo" />
            </intent-filter>
        </receiver>
    </application>
    
  • 0

    用这个

    function pnstest(){
    
                    $data = array('post_id'=>'12345','title'=>'A Blog post', 'message' =>'test msg');
    
                    $url = 'https://fcm.googleapis.com/fcm/send';
    
                    $server_key = 'AIzaSyDVpDdS7EyNgMUpoZV6sI2p-cG';
    
                    $target ='fO3JGJw4CXI:APA91bFKvHv8wzZ05w2JQSor6D8lFvEGE_jHZGDAKzFmKWc73LABnumtRosWuJx--I4SoyF1XQ4w01P77MKft33grAPhA8g-wuBPZTgmgttaC9U4S3uCHjdDn5c3YHAnBF3H';
    
                    $fields = array();
                    $fields['data'] = $data;
                    if(is_array($target)){
                        $fields['registration_ids'] = $target;
                    }else{
                        $fields['to'] = $target;
                    }
    
                    //header with content_type api key
                    $headers = array(
                        'Content-Type:application/json',
                      'Authorization:key='.$server_key
                    );
    
                    $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('FCM Send Error: ' . curl_error($ch));
                    }
                    curl_close($ch);
                    return $result;
    
    }
    

相关问题