GCM与PHP(Google Cloud Messaging)

我如何将新的Google云消息传递整合到PHP后端?

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

// 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; } 
 <?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); ?> 

这很容易做到。 Elad Nava在这里放置的网页上的cURL代码正常工作。 Elad 评论了他收到的错误 。

描述处理该收件人的邮件时发生的错误的string。 可能的值与上表中logging的相同,再加上“不可用”(意思是GCM服务器繁忙,无法处理该特定收件人的邮件,因此可能会重试)。

我已经build立了一个似乎正在工作的服务(ish),到目前为止,我所有的服务都是Google无法提供的回报。 这很可能很快就会改变。

要回答这个问题,请使用PHP,确保Zend Framework位于包含path中,并使用以下代码:

 <?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新的GCM的一个工作(很快就会开始)。

经过了很长时间的search后,我终于明白了自己确实需要什么,使用PHP作为服务器端脚本语言来连接到GCM。下面的教程将会给我们一个清晰的想法,告诉我们如何设置入门所需的一切与GCM

使用Google Cloud Messaging(GCM),PHP和MySQL的Android推送通知

我实际上已经在我的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']); } } 

你也可以试试这段代码, 来源 :

 <?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); 

很多教程已经过时,即使当前的代码没有考虑设备registration_ids更新或设备取消注册。 如果这些项目未经检查,最终将导致阻止收到消息的问题。 http://forum.loungekatt.com/viewtopic.php?t=63#p181

 <?php function sendMessageToPhone($deviceToken, $collapseKey, $messageText, $yourKey) { echo "DeviceToken:".$deviceToken."Key:".$collapseKey."Message:".$messageText ."API Key:".$yourKey."Response"."<br/>"; $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); ?> 

在上面的脚本只是改变:

将API密钥的“YOURKEY”键转换为API控制台的服务器密钥。
“REGISTERED_ID”与您的设备的注册ID
“COLLAPSE_KEY”与你需要的钥匙
带有您要发送的信息的“MESSAGE”

让我知道如果你有任何问题,我可以使用相同的脚本成功地通知。

你可以在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(); } 

这里是我从CodeMonkeysRU分叉的一个库。

我分手的原因是因为Google需要指数回退。 我使用redis服务器排队消息并在设定的时间后重新发送。

我也更新了它,以支持iOS。

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

这里是@Elad Nava发布的以上PHP代码的android代码

MainActivity.java(启动器活动)

 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> 

用这个

  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; }