Android:如何使用 Parse 作为替代 GCM 推送通知提供程序?

标签 android push-notification parse-platform google-cloud-messaging

请参阅问题末尾的 EDIT#2(Google 更新了推送的实现方式,以便更轻松地一起处理 gcm 和解析)

我已经在应用程序中使用了 GCM,我想添加解析作为替代方案。这就是我现在所拥有的(所有权限都已正确声明):

<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”)类处理服务器注册和消息接收 - 它工作正常并且接收所有推送消息。服务器有时会发送自定义数据,因此我自己处理消息并以编程方式创建通知(单击通知时使用的 Intent 有一些从服务器发送的重要额外内容)。

我想以某种方式使解析以相同的方式运行,以便能够从解析网站发送 channel 推送并创建我自己的通知,但我尝试的一切都失败了(遵循 android 推送教程并没有真正起作用对于我的问题)。有没有人尝试过类似的事情?在花了很多时间调整推送指南/教程后,我有点失去了想法 - 有时我没有收到任何通知;有时解析和我的接收器都会被调用,并且我会收到双重通知。我还尝试使用解析 REST api 进行注册并自己处理所有事情,但发现这在 Android 上是不可能的。

那么,我如何处理解析推送和传统的 gcm 推送(使用我的服务器),以便我可以访问这两个通知,并且可以从头开始构建它们(使用所需的额外功能创建我自己的待处理通知) )?

编辑#1:

我尝试的第一件事是使用解析服务并使用单个广播接收器来处理 GCM 消息:

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>

解析库需要进行以下初始化:

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

问题是我收到了来自其他提供商的通知,但我没有收到来自解析的任何内容(声明了所有权限),并且我从解析库收到以下错误(当收到错误时,解析注册为未正确完成 - 我在解析控制台中看不到我的设备):

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:

我根据google push notification developer guide更新了gcm推送的处理方式。在实现扩展“GcmListenerService”的类时,您现在可以轻松检查“from”参数是否与用于注册推送的 Google 项目 ID 相同。

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

此外,parse 更新了它们的库(我现在使用的是“1.9.4”),您可以对“ParsePushBroadcastReceiver”进行子类化来根据需要处理通知。请参阅指南here进行基本实现。

在“Application”类的“onCreate”方法中解析初始化:

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 的 list 声明:

...

<!-- 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 还添加了一种处理 token 刷新的方法 - 示例包含完整代码示例可以在 here 中找到。

最佳答案

如果我理解正确的话,您希望您的代码能够处理所有传入的 GCM 消息,无论其来源如何(可以是您的服​​务器或 Parse 网站),这意味着您不希望应用程序中的 Parse 代码执行此操作处理它们。

您可以通过在 list 中仅声明一个处理 com.google.android.c2dm.intent.RECEIVE 操作的广播接收器来实现此目的。这将是您的 GCMBroadcastReceiver 类,它将处理所有到达的 GCM 消息。

当您声明两个处理相同操作的广播接收器时,可能会发生您当前遇到的行为。

关于Android:如何使用 Parse 作为替代 GCM 推送通知提供程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23055519/

相关文章:

Android picasso 将照片放大或适合 imageView(无空白)

php - 用于签署推送通知 token 的 Apple 签名 key 的 x、y 和曲线参数是什么?

android - GCM 中的注册应用程序问题

android - 从 Parse 中删除类/列时遇到问题

ios - 查询后写入 Parse 列 - Swift

java - 解析 withinMiles 首先返回最近的

java - ActionBarActivity 无法解析。无法启动需要 Theme.AppCompat 的 Activity 。修复 Android 应用中的依赖关系

android - 使用 MediaRecorder 录制 mp4 时获取/修改帧

android - 如何使 ListView 仅显示 3 个项目

android - 如何在点击推送通知时打开特定 Activity ?