我正在根据此处提供的示例创建GCM客户端 - http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/和此处 - http://developer.android.com/google/gcm/client.html。基本上,它只是做了第一个例子,但我更新它以使用GoogleCloudMessaing API。
作为服务器,我使用了第一个链接中使用的示例php服务器。但是当我通过php脚本发送消息时,我的设备上没有收到任何消息。
在服务器端,我使用mysql密码和Google API密钥修改了config.php文件。
?php
/**
* Database config variables
/
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASSWORD", "password");
define("DB_DATABASE", "gcm");
/*
* Google API Key
*/
define("GOOGLE_API_KEY", "MY GOOGLE API KEY"); // Place your Google API Key
我在gcm_users表中手动创建了一个条目,这样我就不必从我的应用程序发送注册ID了。该表包含第一个链接中提到的regId,name,email。
然后我从index.php页面发送一条消息,但是从未收到该消息。
我的Android清单文件 -
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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.gcmclient.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcmclient.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".RegisterActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".GCMClientActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name" >
</activity>
<receiver
android:name=".GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.gcmclient" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
GCMIntentService.java文件:
package com.example.gcmclient;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import com.google.android.gms.gcm.GoogleCloudMessaging;
public class GCMIntentService extends IntentService {
public GCMIntentService() {
super("GCMIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
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)) {
Utilities.showNotification(this, "Send error: " + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
Utilities.showNotification(this, "Deleted messages on server: " + extras.toString());
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
Utilities.showNotification(this, "Received: " + extras.toString());
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GCMBroadcastReceiver.completeWakefulIntent(intent);
}
}
}
我已经确认我已正确注册gcm服务器并且服务器将注册ID返回到我的应用。 RegisterActivity.java文件的主要部分:
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
private Random mRandom = new Random();
private long mBackoff = BACKOFF_MILLI_SECONDS + mRandom.nextInt(1000);
private ProgressDialog mDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
mDialog = new ProgressDialog(mContext);
mDialog.setMessage("Registering with Google Cloud Messaging (GCM)");
mDialog.setIndeterminate(true);
mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mDialog.setCancelable(false);
mDialog.show();
}
@Override
protected String doInBackground(Void... params) {
String msg = "";
for (int i = 1; i <= MAX_ATTEMPTS; i++, mBackoff *= 2) {
msg = "";
try {
if (mGcm == null) {
mGcm = GoogleCloudMessaging.getInstance(mContext);
}
mRegId = mGcm.register(SENDER_ID);
msg = "Device registered, registration ID = " + mRegId;
storeRegistrationId(mContext, mRegId);
break;
} catch (IOException e) {
Log.d(TAG, e.toString());
// 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.d(TAG, "Failed to register on attempt: " + i);
try {
Log.d(TAG, "Sleeping for " + mBackoff + " ms before retry");
Thread.sleep(mBackoff);
} catch(InterruptedException e1) {
Log.d(TAG, "Thread interrupted: abort remaining retries!");
Thread.currentThread().interrupt();
return msg;
}
}
}
return msg;
}
注册后,我的应用程序收到一条带有注册ID的广播消息。
09-16 19:27:41.970:D / GCMBoradcastReceiver(19723):onReceive调用:Key = registration_id value =
我在我的mysql数据库表中复制了。
我在本地PC上运行服务器,其IP地址为192.168.1.139(没有公共IP)。 IPtables的输出 -
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:5228
ACCEPT tcp -- anywhere anywhere tcp dpt:5229
ACCEPT tcp -- anywhere anywhere tcp dpt:5230
Apache日志显示来自index.php的原始发送请求的状态ok(200)。
那我错过了什么?任何帮助将不胜感激。
答案 0 :(得分:0)
你GCMIntentService不像GCM说的那样......
public class GCMIntentService extends GCMBaseIntentService {
@SuppressWarnings("hiding")
private static final String TAG = "GCMIntentService";
public GCMIntentService() {
super(Utility.SENDER_ID);
}
@Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
}
@Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
}
@Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
}
@Override
protected void onDeletedMessages(Context context, int total) {
Log.i(TAG, "Received deleted messages notification");
}
@Override
public void onError(Context context, String errorId) {
Log.i(TAG, "Received error: " + errorId);
}
@Override
protected boolean onRecoverableError(Context context, String errorId) {
// log message
Log.i(TAG, "Received recoverable error: " + errorId);
return super.onRecoverableError(context, errorId);
}
}