gpt4 book ai didi

android - GCM 和 Parse 通知冲突

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:44:51 25 4
gpt4 key购买 nike

我需要我的 Android 应用程序与两个推送服务、GCM 和解析一起工作。我的问题是我找不到正确注册到 Parse、获取解析通知和 GCM 通知的方法。我可以单独接触到所有这些东西,但不能一起接触。我当前的实现看起来是这样的:

<!-- GCM BradcastReceiver & Service -->
<service android:name=".GcmIntentService"
android:enabled="true"/>
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter
android:priority="100"> <!-- higher priority to GCM messages -->

<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.twentyLines.GCM_NOTIFICATION_ACTION" />
<category android:name="com.twentyLines.app" />
</intent-filter>
</receiver>

这是GCM的broadcastReceiver,下面是另一个parse的receiver:

<service android:name="com.parse.PushService" />

<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter android:priority="0">

<!--<action android:name="com.google.android.c2dm.intent.RECEIVE" />-->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.twentyLines.app" />
</intent-filter>
</receiver>
<!-- Can remove this if application is already registered for GCM -->
<receiver android:name="com.parse.ParseBroadcastReceiver" android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="com.twentyLines.PARSE_NOTIFICATION_ACTION" />
</intent-filter>
</receiver>

我尝试添加一个自定义广播接收器来处理解析通知,这样我就可以避免它也处理 GCM。我是这样做的:

<receiver android:name="com.twentyLines.app.ParseBroadcastReceiver" android:exported="false" >
<intent-filter>
<action android:name="com.twentyLines.PARSE_NOTIFICATION_ACTION" />
</intent-filter>
</receiver>

这是我的 GCM BroadcastReceiver 的实现,避免显示解析通知。

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

boolean isFromParse = intent.getExtras().get("action").equals("com.twentyLines.PARSE_NOTIFICATION_ACTION");
if (isFromParse)
return;

// 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_CANCELED);
}
}

这是我的 PARSE 自定义 BroadcastReceiver 的实现,它应该避免显示 GCM。永远不会调用解析自定义接收器,我认为是因为 com.parse.GcmBroadcastReceiver 处理通知本身而不是传递它们。结果是,当我从我的服务器向 GCM 接收器发送通知时,这会从两者中检索到,并显示双重通知。(double 已经很好了,每次我卸载并重新安装我的应用程序时,Parse 都会注册另一个用户。我每次发送给 parse 的“UniqueId”对他们来说并不是那么独特)。

我尝试了什么?我真的快疯了,我什么都试过了。

 - I've read all related questions, and no one is good for me;
- I've tried to remove the parse receiver, and this cause a parse exception (so doesn't register to parse)
- I've tried to set the intent to RESULT_CANCELED, but in some way parse get it before GCM, so isn't working when I use GCM.
- I've changed about all using cowboy-coding, and it still not work...

任何帮助都将真正欢迎。谢谢大家!

编辑 - 添加工作 list

<!-- GCM BradcastReceiver & Service -->
<service android:name=".GcmIntentService"
android:enabled="true"/>
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />

<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter
android:priority="2"> <!-- higher priority to GCM messages -->

<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.twentyLines.GCM_NOTIFICATION_ACTION" />
<category android:name="com.twentyLines.app" />
</intent-filter>
</receiver>

<!-- Parse service broacastReceiver and receiver. -->
<service android:name="com.parse.PushService" />

<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter android:priority="1">

<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.twentyLines.app" />
</intent-filter>
</receiver>
<!-- Can remove this if application is already registered for GCM -->
<receiver android:name="com.parse.ParseBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="com.twentyLines.PARSE_NOTIFICATION_ACTION" />
</intent-filter>
</receiver>

<receiver android:name="com.twentyLines.app.ParseBroadcastReceiver" android:exported="false" >
<intent-filter>

<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="com.twentyLines.PARSE_NOTIFICATION_ACTION" />
</intent-filter>
</receiver>

编辑 2:我如何注册 PARSE 和 GCM

我在我的应用程序类中注册了 Parse:

Parse.initialize(this, PARSE_APP_KEY_VALUE, PARSE_CLIENT_KEY_VALUE);
PushService.setDefaultPushCallback(getApplicationContext(), MainActivity.class);
final ParseInstallation installation = ParseInstallation.getCurrentInstallation();
final String androidId = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
installation.put("UniqueId", androidId);
installation.saveInBackground(new SaveCallback() {
@Override
public void done(ParseException e) {
Log.d("Parse installation saved in background", "If operation successfull, 'e' have to be NULL e= " + e);
}
});
}
}, 5000
);

然后我在 MainActivity 中获得了 gcm registration_id:

// Check if there is a saved registration_id in shared_prefs,
// or if app version has changed
private String getSavedRegistrationId() {
final SharedPreferences gcmShared = getGCMSharedPrefss();
String registrationId = gcmShared.getString(Constant.GCM_REGISTRATION_ID_KEY, "");
if (registrationId.isEmpty()) {
Log.i("GCM", "Registration not found.");
return "";
}

int registeredVersion = gcmShared.getInt(Constant.APP_VERSION_KEY, Integer.MIN_VALUE);
int currentVersion = getAppVersion(this);
if (registeredVersion != currentVersion) {
clearSavedGCMRegistrationId();
Log.i("GCM", "App version changed.");
return "";
}
return registrationId;
}

// If there isn't, request one
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
String msg;
try {
if (_gcm == null) {
_gcm = GoogleCloudMessaging.getInstance(MainActivity.this);
}
String regid = _gcm.register(Constant.GCM_SENDER_ID);
msg = "Device registered, registration ID=" + regid;
sendRegistrationIdToBackend(regid);
storeRegistrationId(regid); // Save reg_id to shared
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
// If there is an error, don't just keep trying to register.
// Require the startupLoggedUser to click a button again, or perform
// exponential back-off.
}
return msg;
}

@Override
protected void onPostExecute(String msg) {
Log.d("GCM registration", msg);
}
}.execute(null, null, null);
}

最佳答案

我们这里有两个广播接收器来监听c2dm intent

  1. .GcmBroadcastReceiver :让我们将其称为 GCM 接收器...Parse Push 永远不会到达此接收器。
  2. com.parse.GcmBroadcastReceiver :我们称它为 Parse 接收器

由于您为 GCM 接收器赋予了更高的优先级,因此广播将首先到达 GCM 接收器,然后再到达 Parse 接收器。这并不能保证 Broadcast 不会去 Parse receiver。您需要添加 abortBroadcast();作为 onReceive 方法中的最后一行,以确保当我们让 GCM 接收器工作时不会触发 Parse 接收器。

根据 Parse 推送通知指南,接收带有特定 Intent 操作的推送。数据被发送到注册了该操作的广播接收器。在您的情况下,如果通过操作“com.twentyLines.PARSE_NOTIFICATION_ACTION”接收到推送,您可以使用自定义广播接收器来收听此操作。在该广播接收器中,您可以通过以下代码获取数据,

try {
String action = intent.getAction();
String channel = intent.getExtras().getString("com.parse.Channel");
JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));

Log.d(TAG, "got action " + action + " on channel " + channel + " with:");
Iterator itr = json.keys();
while (itr.hasNext()) {
String key = (String) itr.next();
Log.d(TAG, "..." + key + " => " + json.getString(key));
}
} catch (JSONException e) {
Log.d(TAG, "JSONException: " + e.getMessage());
}

当有 GCM 推送时,此自定义接收器将永远不会收到广播事件,因为 C2DM 广播在 GCM 接收器 (".GcmBroadcastReceiver") 中中止

希望对您有所帮助!

关于android - GCM 和 Parse 通知冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25397163/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com