Android:如何使用 Parse 作为替代 GCM 推送通知提供程序? [英] Android: How to use Parse as an alternative GCM push notification provider?
问题描述
请参阅问题末尾的 EDIT#2(Google 更新了推送的实现方式,以便更轻松地处理 gcm 和一起解析)
我已经在应用程序中使用了 GCM,我想添加 parse 作为替代.这就是我现在所拥有的(所有权限都已正确声明):
I already use GCM inside a application and I would like to add parse as an alternative. This is what I have now (all the permissions are correctly declared):
<service
android:name="com.mypackagename.GCMIntentService"
android:enabled="true" />
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.mypackagename.GCMIntentService" />
</intent-filter>
</receiver>
'GCMIntentService'(继承自'GCMBaseIntentService')类处理服务器注册和消息接收——它工作正常并且所有推送消息都被接收.服务器有时会发送自定义数据,因此我自己处理消息并以编程方式创建通知(单击通知时使用的意图有一些从服务器发送的重要附加信息).
The 'GCMIntentService' (inherits from 'GCMBaseIntentService') class handles the server registration and receiving of messages - it works fine and all the push messages are received. The server sometimes sends custom data so I handle the messages myself and create the notifications programmatically (the intent used when the notification is clicked has some important extras sent from the server).
我想以某种方式使 parse 以相同的方式运行,以便能够从 parse 网站发送频道推送并创建我自己的通知,但我尝试的一切都失败了(遵循 android 推送教程并没有真正起作用对于我的问题).有没有人尝试过类似的事情?在花了很多时间调整推送指南/教程后,我有点想不通了——有时我没有收到任何通知;有时 parse 和我的接收器都会被调用,我会收到双重通知.我还尝试使用解析 REST apis 进行注册并自己处理所有内容,但发现在 Android 上无法实现.
I would like to somehow make parse behave in the same way in order to be able to send channel pushes from the parse website and create my own notifications, but everything I tried failed (following the android push tutorial isn't really working for my problem). Is there anyone who tried a similar thing? I'm kind of out of ideas after spending a lot of time tweaking the push guides/tutorials - sometimes I don't receive any notifications; sometimes both parse and my receiver are called and I get double notifications. I also tried to register using parse REST apis and handle everything myself but found out it isn't possible on Android.
那么,我如何处理解析推送和传统的 gcm 推送(使用我的服务器),以便我可以访问这两个通知并且我可以从头开始构建它们(使用所需的附加功能创建我自己的待处理通知))?
So, how could I handle both parse pushes and the traditional gcm pushes (using my server) in such a way that I have access to both notifications and I can build them from scratch (create my own pending notifications with the required extras)?
编辑#1:
我尝试的第一件事是使用解析服务并有一个广播接收器来处理 GCM 消息:
The first thing I tried was to use the parse service and have a single broadcast receiver to handle the GCM messages:
AndroidMaifest.xml:
AndroidMaifest.xml:
<service
android:name="com.mypackagename.GCMIntentService"
android:enabled="true" />
<service android:name="com.parse.PushService"
android:enabled="true"/>
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.mypackagename.GCMIntentService" />
</intent-filter>
</receiver>
并且解析库需要以下初始化:
And the parse library requires the following initializations:
Parse.initialize(context, appId, apiKey);
PushService.setDefaultPushCallback(context, MainActivity.class);
// I'm subscribing to channel push because I send channel pushes from the
// parse console
PushService.subscribe(context, MDConstants.PARSE_PUSH_CHANNEL, MainActivity.class);
ParseInstallation.getCurrentInstallation().saveInBackground();
问题是我收到了来自其他提供商的通知,但我没有从 parse 收到任何信息(声明了所有权限)并且我从 parse 库中收到以下错误(当收到错误时,解析注册是没有正确完成 - 我在解析控制台中看不到我的设备):
The problem is that I receive the notifications from my other provider but I don't receive anything from parse (all the permissions are declared) and I get the following error from the parse library (when receiving the error the parse registration is not properly done - I can't see my device in the parse console):
E/com.parse.ManifestInfo(11677): Cannot use GCM for push because the app manifest is missing some required declarations. Please make sure that these permissions are declared as children of the root <manifest> element:
E/com.parse.ManifestInfo(11677):
E/com.parse.ManifestInfo(11677): <uses-permission android:name="android.permission.INTERNET" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="android.permission.VIBRATE" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="android.permission.WAKE_LOCK" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="android.permission.GET_ACCOUNTS" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
E/com.parse.ManifestInfo(11677): <permission android:name="com.mypackagename.permission.C2D_MESSAGE" android:protectionLevel="signature" />
E/com.parse.ManifestInfo(11677): <uses-permission android:name="com.mypackagename.permission.C2D_MESSAGE" />
E/com.parse.ManifestInfo(11677):
E/com.parse.ManifestInfo(11677): Also, please make sure that these services and broadcast receivers are declared as children of the <application> element:
E/com.parse.ManifestInfo(11677):
E/com.parse.ManifestInfo(11677): <service android:name="com.parse.PushService" />
E/com.parse.ManifestInfo(11677): <receiver android:name="com.parse.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
E/com.parse.ManifestInfo(11677): <intent-filter>
E/com.parse.ManifestInfo(11677): <action android:name="com.google.android.c2dm.intent.RECEIVE" />
E/com.parse.ManifestInfo(11677): <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
E/com.parse.ManifestInfo(11677): <category android:name="com.mypackagename" />
E/com.parse.ManifestInfo(11677): </intent-filter>
E/com.parse.ManifestInfo(11677): </receiver>
E/com.parse.PushService(11677): Tried to use push, but this app is not configured for push due to: Push is not configured for this app because the app manifest is missing required declarations. Please add the following declarations to your app manifest to support either GCM or PPNS for push (or both). To enable GCM support, please make sure that these permissions are declared as children of the root <manifest> element:
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.INTERNET" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.VIBRATE" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.WAKE_LOCK" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.GET_ACCOUNTS" />
E/com.parse.PushService(11677): <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
E/com.parse.PushService(11677): <permission android:name="com.mypackagename.permission.C2D_MESSAGE" android:protectionLevel="signature" />
E/com.parse.PushService(11677): <uses-permission android:name="com.mypackagename.permission.C2D_MESSAGE" />
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): Also, please make sure that these services and broadcast receivers are declared as children of the <application> element:
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): <service android:name="com.parse.PushService" />
E/com.parse.PushService(11677): <receiver android:name="com.parse.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
E/com.parse.PushService(11677): <intent-filter>
E/com.parse.PushService(11677): <action android:name="com.google.android.c2dm.intent.RECEIVE" />
E/com.parse.PushService(11677): <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
E/com.parse.PushService(11677): <category android:name="com.mypackagename" />
E/com.parse.PushService(11677): </intent-filter>
E/com.parse.PushService(11677): </receiver>
E/com.parse.PushService(11677): To enable PPNS support, please make sure that these permissions are declared as children of the root <manifest> element:
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.INTERNET" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.VIBRATE" />
E/com.parse.PushService(11677): <uses-permission android:name="android.permission.WAKE_LOCK" />
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): Also, please make sure that these services and broadcast receivers are declared as children of the <application> element:
E/com.parse.PushService(11677):
E/com.parse.PushService(11677): <service android:name="com.parse.PushService" />
E/com.parse.PushService(11677): <receiver android:name="com.parse.ParseBroadcastReceiver">
E/com.parse.PushService(11677): <intent-filter>
E/com.parse.PushService(11677): <action android:name="android.intent.action.BOOT_COMPLETED" />
E/com.parse.PushService(11677): <action android:name="android.intent.action.USER_PRESENT" />
E/com.parse.PushService(11677): </intent-filter>
E/com.parse.PushService(11677): </receiver>
编辑#2:
I updated the way gcm push was handled based on the google push notification developer guide. While implementing the class that extends 'GcmListenerService', you can now easily check if the 'from' arguments is the same as your google project id used to register for push.
public class MyGcmListenerService extends GcmListenerService {
@Override
public void onMessageReceived(String from, Bundle data) {
// only handle gcm messages that come from the same project id used to register
if (from.equals("Your google project id)) {
// handle the gcm push
}
}
}
此外,解析更新了他们的库(我现在使用的是1.9.4"),您可以将ParsePushBroadcastReceiver"子类化以根据需要处理通知.有关基本实现,请参阅此处指南.
Also, parse updated their libraries (I'm using '1.9.4' right now) and you can subclass the 'ParsePushBroadcastReceiver' to handle the notifications as you'd like. See the guide here for a basic implementation.
在Application"类的onCreate"方法中解析初始化:
Parse initialization in the 'onCreate' method of your 'Application' class:
Parse.initialize(this, "your parse app id", "your parse client key");
// subscribing to a channel
ParsePush.subscribeInBackground("your channel name", new SaveCallback() {
@Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push");
}
}
});
广播接收器实现:
public class MyParsePushBroadcastReceiver extends ParsePushBroadcastReceiver {
@Override
protected void onPushReceive(Context context, Intent intent) {
// handle the parse push notification
}
}
parse 和 gcm 的清单声明:
The manifest declaration for both parse and gcm:
...
<!-- GCM listener service -->
<service
android:name=".MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
...
<!-- Parse broadcast receiver -->
<receiver android:name=".MyParsePushBroadcastReceiver" android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
...
我只添加了服务和接收器,但是您需要确保遵循 GCM 指南和 Parse 推送指南以获得完整的实现(例如,google 还添加了处理令牌刷新的方法 - 示例可以找到包含完整代码示例的 这里).
I only added the service and the receiver, but you need to make sure you follow the GCM guide and the Parse push guides to have a full implementation (for example, google also added a way to handle the token refresh - a sample containing full code samples can be found here).
推荐答案
如果我理解正确,您希望您的代码处理所有传入的 GCM 消息,而不管它们的来源(可以是您的服务器或 Parse 网站),这意味着您不希望应用中的 Parse 代码处理它们.
If I understand correctly, you want your code to handle all the incoming GCM messages, regardless of their source (which can be either your server or Parse website), which means you don't want the Parse code in your app do handle them.
您可以通过在清单中仅声明一个处理 com.google.android.c2dm.intent.RECEIVE
操作的广播接收器来实现此目的.那将是您的 GCMBroadcastReceiver
类,它将处理所有到达的 GCM 消息.
You can achieve this by declaring only a single broadcast receiver handling com.google.android.c2dm.intent.RECEIVE
action in your manifest. That would be your GCMBroadcastReceiver
class, which would handle all the arriving GCM messages.
当您声明两个处理相同操作的广播接收器时,可能会发生您当前遇到的行为.
The behavior you are currently experiencing can happen when you declare two broadcast receivers that handle the same action.
这篇关于Android:如何使用 Parse 作为替代 GCM 推送通知提供程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!