Android GCM客户端未接收推送通知
我希望我的Android应用程序从我的后端接收GCM推送消息。我已经实现了GCM客户端,如中所示,但在我的两个测试设备(Android 4.2.2 original和CM mod 10.1 Android 4.2.2)上没有收到任何推送消息。 这些是我在我的Android GCM客户端未接收推送通知,android,push-notification,google-cloud-messaging,buddy.com,Android,Push Notification,Google Cloud Messaging,Buddy.com,我希望我的Android应用程序从我的后端接收GCM推送消息。我已经实现了GCM客户端,如中所示,但在我的两个测试设备(Android 4.2.2 original和CM mod 10.1 Android 4.2.2)上没有收到任何推送消息。 这些是我在我的AndroidManifest.xml中的权限和更改: <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-per
AndroidManifest.xml
中的权限和更改:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name=".permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.SEND" />
<uses-permission android:name="com.google.android.c2dm.intent.RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name=".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=".gcm" />
</intent-filter>
</receiver>
<service android:name=".GcmIntentService" />
</application>
MyGcmBroadcastReceiver
:
package .wop;
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) {
System.out.println("PUSH RECEIVED!!!");
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
以及我在我的main活动中对GCM所做的更改:
public class MainActivity extends ActionBarActivity {
//GCM
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 = "3019882...";
/**
* 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
protected void onCreate(Bundle savedInstanceState) {
mDisplay = (TextView) findViewById(R.id.displayPush);
context = getApplicationContext();
//GCM
// 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 {
System.out.println("regid: " + regid);
}
} else {
Log.i(TAG, "No valid Google Play Services APK found.");
}
/**
* Registers the application with GCM servers asynchronously.
* <p/>
* Stores the registration ID and the app versionCode in the application's
* shared preferences.
*/
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
@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;
System.out.println(msg);
// 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.
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();
System.out.println(msg);
// 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);
}
/**
* Sends the registration ID to your server over HTTP, so it can use GCM/HTTP
* or CCS to send messages to your app. Not needed for this demo since the
* device sends upstream messages to a server that echoes back the message
* using the 'from' address in the message.
*/
private void sendRegistrationIdToBackend() {
//ADDED BY MYSELF
Buddy.setPushToken(regid, new BuddyCallback<Boolean>(Boolean.class) {
@Override
public void completed(BuddyResult<Boolean> result) {
System.out.println("sendPushToken successfully");
}
});
}
/**
* 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();
}
/**
* 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;
}
/**
* @return Application's {@code SharedPreferences}.
*/
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 getSharedPreferences(MainActivity.class.getSimpleName(),
Context.MODE_PRIVATE);
}
/**
* @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 (PackageManager.NameNotFoundException e) {
// should never happen
throw new RuntimeException("Could not get package name: " + e);
}
}
//GCM
// You need to do the Play Services APK check here too.
@Override
protected void onResume() {
super.onResume();
checkPlayServices();
}
//GCM
/**
* 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(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Log.i(TAG, "This device is not supported.");
finish();
}
return false;
}
return true;
}
公共类MainActivity扩展了ActionBarActivity{
//GCM
公共静态最终字符串EXTRA_MESSAGE=“MESSAGE”;
公共静态最终字符串属性\u REG\u ID=“注册\u ID”;
私有静态最终字符串属性\u APP\u VERSION=“appVersion”;
专用最终静态整数播放服务解析请求=9000;
/**
*在此处替换您自己的发件人ID。这是您获得的项目编号
*从API控制台,如“入门”中所述
*/
字符串发送者_ID=“3019882…”;
/**
*日志消息上使用的标记。
*/
静态最终字符串TAG=“GCMDemo”;
文本视图mDisplay;
谷歌云通讯gcm;
AtomicInteger msgId=新的AtomicInteger();
共享引用优先权;
语境;
字符串寄存器;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
mDisplay=(TextView)findViewById(R.id.displayPush);
context=getApplicationContext();
//GCM
//检查设备的播放服务APK。如果检查成功,请继续
//GCM注册。
如果(checkPlayServices()){
gcm=GoogleCloudMessaging.getInstance(this);
regid=getRegistrationId(上下文);
if(regid.isEmpty()){
registerInBackground();
}否则{
System.out.println(“regid:+regid”);
}
}否则{
i(标记“找不到有效的Google Play服务APK”);
}
/**
*异步向GCM服务器注册应用程序。
*
*将注册ID和应用程序版本代码存储在应用程序的
*共享偏好。
*/
私有无效注册表背景(){
新建异步任务(){
@凌驾
受保护字符串doInBackground(无效…参数){
字符串msg=“”;
试一试{
如果(gcm==null){
gcm=GoogleCloudMessaging.getInstance(上下文);
}
regid=gcm.寄存器(发送方ID);
msg=“设备已注册,注册ID=“+regid;
System.out.println(msg);
//您应该通过HTTP将注册ID发送到服务器,以便
//可以使用GCM/HTTP或CCS向您的应用程序发送消息。
sendRegistrationIdToBackend();
//对于本演示:我们不需要发送它,因为设备将发送
//向服务器发送的上游消息,使用
//消息中的“发件人”地址。
//坚持注册-无需再次注册。
storeRegistrationId(上下文,regid);
}捕获(IOEX异常){
msg=“错误:”+ex.getMessage();
System.out.println(msg);
//如果出现错误,不要一直尝试注册。
//要求用户再次单击按钮,或执行以下操作
//退后。
}
返回味精;
}
@凌驾
受保护的void onPostExecute(字符串msg){
mDisplay.append(msg+“\n”);
}
}.执行(空,空,空);
}
/**
*通过HTTP将注册ID发送到服务器,以便它可以使用GCM/HTTP
*或CCS向您的应用程序发送消息。此演示不需要,因为
*设备将上行消息发送到服务器,服务器将回显该消息
*使用邮件中的“发件人”地址。
*/
私有void sendRegistrationIdToBackend(){
//我自己加的
setPushToken(regid,新BuddyCallback(Boolean.class)){
@凌驾
已完成公共作废(BuddyResult结果){
System.out.println(“sendPushToken成功”);
}
});
}
/**
*将注册ID和应用程序版本代码存储在应用程序的
*{@code-SharedPreferences}。
*
*@param context应用程序的上下文。
*@param regId注册ID
*/
私有void storeRegistrationId(上下文上下文,字符串regId){
最终SharedReferences prefs=getGCMPreferences(上下文);
int-appVersion=getAppVersion(上下文);
Log.i(标记“在应用程序版本上保存注册表”+应用程序版本);
SharedReferences.Editor=prefs.edit();
编辑器.putString(PROPERTY\u REG\u ID,regId);
编辑器.putInt(属性\应用\版本,应用版本);
commit();
}
/**
*获取GCM服务上应用程序的当前注册ID。
*
*如果结果为空,则应用程序需要注册。
*
*@返回注册ID,如果不存在,则返回空字符串
*注册号。
*/
私有字符串getRegistrationId(上下文){
最终SharedReferences prefs=getGCMPreferences(上下文);
String registrationId=prefs.getString(PROPERTY_REG_ID,“”);
if(registrationId.isEmpty()){
Log.i(标记“未找到注册”);
返回“”;
}
//检查应用程序是否已更新;如果已更新,则必须清除注册ID
//因为现有的regID不能保证与新的
//应用程序版本。
int registeredVersion=prefs.getInt(属性\应用\版本,整数.MIN \值);
int currentVersion=getAppVersion(上下文);
if(registeredVersion!=当前版本){
Log.i(标记“应用程序版本已更改”);
返回“”;
}
返回注册ID;
}
/**
*@return应用程序的{@code SharedPreferences}。
*/
私有SharedReferences getGCMPreferences(上下文){
//此示例应用程序将注册ID保留在共享首选项中,但
//如何在应用程序中存储regID取决于您。
返回GetSharedReferences(MainActivity.class.getSimpleName(),
Context.MO
public class MainActivity extends ActionBarActivity {
//GCM
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 = "3019882...";
/**
* 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
protected void onCreate(Bundle savedInstanceState) {
mDisplay = (TextView) findViewById(R.id.displayPush);
context = getApplicationContext();
//GCM
// 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 {
System.out.println("regid: " + regid);
}
} else {
Log.i(TAG, "No valid Google Play Services APK found.");
}
/**
* Registers the application with GCM servers asynchronously.
* <p/>
* Stores the registration ID and the app versionCode in the application's
* shared preferences.
*/
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
@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;
System.out.println(msg);
// 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.
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();
System.out.println(msg);
// 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);
}
/**
* Sends the registration ID to your server over HTTP, so it can use GCM/HTTP
* or CCS to send messages to your app. Not needed for this demo since the
* device sends upstream messages to a server that echoes back the message
* using the 'from' address in the message.
*/
private void sendRegistrationIdToBackend() {
//ADDED BY MYSELF
Buddy.setPushToken(regid, new BuddyCallback<Boolean>(Boolean.class) {
@Override
public void completed(BuddyResult<Boolean> result) {
System.out.println("sendPushToken successfully");
}
});
}
/**
* 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();
}
/**
* 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;
}
/**
* @return Application's {@code SharedPreferences}.
*/
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 getSharedPreferences(MainActivity.class.getSimpleName(),
Context.MODE_PRIVATE);
}
/**
* @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 (PackageManager.NameNotFoundException e) {
// should never happen
throw new RuntimeException("Could not get package name: " + e);
}
}
//GCM
// You need to do the Play Services APK check here too.
@Override
protected void onResume() {
super.onResume();
checkPlayServices();
}
//GCM
/**
* 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(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Log.i(TAG, "This device is not supported.");
finish();
}
return false;
}
return true;
}