我正在我的应用程序中集成推送通知以获取痒痒和基本消息。这个想法是它们永远不会从服务器(云到设备)发送,而是从设备(设备到设备)发送。我使用的第三台服务器是Firebase。
我可以在GCM注册就好了。但是,当我50%的时间发送消息时,我从未看到它。当我这样做时,它需要10多分钟才能得到它,并且捆绑包总是空的。这是我的代码:
要注册,我从我的Application.java
中调用它GcmRegister gcmRegister = new GcmRegister(this);
gcmRegister.register();
要发送帖子,我会异步执行此操作:
try {
Bundle b = new Bundle()
b.putString("title", title);
b.putString("message", message);
///apikey is the id i get from registering with GCM
gcm.send(apiKey + "@gcm.googleapis.com", String.valueOf(new AtomicInteger().incrementAndGet()), b);
} catch (IOException e)
log.e(e.getMessage());
e.printStackTrace();
}
的AndroidManifest.xml
<permission android:name="com.super.secret.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.super.secret.permission.C2D_MESSAGE" />
<application
....
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
<service android:name="com.super.secret.core.gcm.GcmIntentService"/>
<receiver
android:name="com.super.secret.core.gcm.GcmReceiver"
android:permission="com.google.android.c2dm.permission.RECEIVE">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.gcm.intent.REGISTRATION" />
<category android:name="com.super.secret" />
</intent-filter>
</receiver>
....
</application>
GCMRegister.java 似乎工作正常
public class GcmRegister {
private static String SENDER_ID;
private Context mContext;
private String mDeviceId;
private String mAccountName;
private String mRegistrationId;
private final UserManager mUserManager = UserManager.getInstance();
private GoogleCloudMessaging gcm;
private Prefs mPrefs;
public GcmRegister(Context context) {
this.mContext = context;
mPrefs = new Prefs(mContext);
gcm = GoogleCloudMessaging.getInstance(mContext);
initStrings();
}
public void register() {
if (checkPlayServices()) {
if (getRegistrationId().isEmpty()) {
registerWithGcm();
} else {
save();
}
} else {
Log.i(TAG, "No valid Google Play Services APK found.");
}
}
private void initStrings() {
SENDER_ID = mContext.getString(R.string.gcm_project_number);
mAccountName = mPrefs.getAccountName();
mDeviceId = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.ANDROID_ID);
}
private void registerWithGcm() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(mContext);
}
Log.i(TAG, "SenderId: " + SENDER_ID);
mRegistrationId = gcm.register(SENDER_ID);
Log.i(TAG, "Device registered, registration ID=" + mRegistrationId);
save();
} catch (IOException ex) {
log.e("Error :" + ex.getMessage());
ex.printStackTrace();
}
return null;
}
}.execute();
}
private void save() {
// Persist the regID - no need to register again.
int appVersion = getAppVersion();
Log.i(TAG, "Saving regId on app version " + appVersion);
mPrefs.setGcmAuthId(mRegistrationId);
mPrefs.setAppVersion(appVersion);
//save to Firebase
....
}
private String getRegistrationId() {
String registrationId = mPrefs.getGcmAuthId();
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 = mPrefs.getAppVersion();
int currentVersion = getAppVersion();
if (registeredVersion != currentVersion) {
log.i("App version changed.");
mPrefs.setGcmAuthId("");
return "";
}
return registrationId;
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
Log.i(TAG, "This device is not supported.");
}
return false;
}
return true;
}
private int getAppVersion() {
try {
PackageInfo packageInfo = mContext.getPackageManager()
.getPackageInfo(mContext.getPackageName(), 0);
return packageInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
// should never happen
throw new RuntimeException("Could not get package name: " + e);
}
}
}
BroadcastReceiver.java
public class GcmReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Message 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);
}
}
GcmIntentService.java
public class GcmIntentService extends IntentService {
public GcmIntentService() {
super("GcmIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.i(TAG, "Intent Service Called");
Bundle extras = intent.getExtras();
String title = extras.getString("title");
String message = extras.getString("message");
NotificationClient noteClient = new NotificationClient(this);
noteClient.showNotification(title, message);
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmReceiver.completeWakefulIntent(intent);
}
}
注意:会显示通知,但没有标题,也没有消息。我曾试图打破广播接收器以查看捆绑包实际包含的内容,但我无法确定何时会收到该消息。所以我还没有成功地完成它。