Использование 2 или более служб намерений GCM в одном приложении

Я пишу приложение, которое интегрируется с Smooch и Карнавал. Обе эти библиотеки получают push-сообщения GCM, используя стандартный подход определения службы намерений GCM для получения сообщений.

Когда я использую только Smooch, все работает отлично. Когда я использую только Carnival, все работает отлично. Проблема возникает, когда я пытаюсь использовать оба. Я обнаружил, что получатель GCM просто запустит первую службу, указанную в манифесте, которая определяет намерение com.google.android.c2dm.intent.RECEIVE.

Фактически, я обнаружил, что порядок библиотек, перечисленных в моем build.gradle, влияет на то, в каком порядке их манифесты объединяются в манифест приложения. Итак, если я сначала поставлю поцелуй, это сработает (но Carnival ничего не получит). И если я поставлю Carnival на первое место, это сработает (но Smooch никогда ничего не получает).

Как я могу управлять несколькими службами намерений GCM, если я не контролирую ни одну из них? В целом, как приложения должны определять и управлять несколькими службами намерений GCM?


person Greg Ennis    schedule 11.04.2016    source источник


Ответы (2)


Причина, по которой вы не можете заставить работать как Carnival, так и Smooch, заключается в том, что обе библиотеки регистрируют свои собственные GcmListenerService, а в Android первый GcmListenerService, определенный в вашем манифесте, будет получать все сообщения GCM.

У меня есть решение для вас, основанное главным образом на следующей статье SO: Несколько прослушивателей GCM с использованием GcmListenerService

Лучшим решением было бы иметь только одну реализацию GcmListenerService и обрабатывать сообщения для обоих.

Чтобы указать свой собственный GcmListenerService, следуйте инструкциям из Документация по облачным сообщениям Google. .

Smooch предоставляет инструменты, необходимые для отключения их внутренней регистрации GCM, когда у вас есть собственная.

Для этого просто вызовите setGoogleCloudMessagingAutoRegistrationEnabled при инициализации Smooch:

Settings settings = new Settings("<your_app_token>");
settings.setGoogleCloudMessagingAutoRegistrationEnabled(false);
Smooch.init(this, settings);

А в своем GcmRegistrationIntentService позвоните Smooch.setGoogleCloudMessagingToken(token); со своим токеном.

Как только это будет завершено, вы сможете передать сообщение GCM любому получателю GCM, который вам нужен.

@Override
public void onMessageReceived(String from, Bundle data) {
    final String smoochNotification = data.getString("smoochNotification");

    if (smoochNotification != null && smoochNotification.equals("true")) {
        data.putString("from", from);

        Intent intent = new Intent();
        intent.putExtras(data);
        intent.setAction("com.google.android.c2dm.intent.RECEIVE");
        intent.setComponent(new ComponentName(getPackageName(), "io.smooch.core.GcmService"));

        GcmReceiver.startWakefulService(getApplicationContext(), intent);
    }
}

ИЗМЕНИТЬ

Начиная с Smooch версии 3.2.0, теперь вы можете более легко активировать уведомление Smooch, вызвав GcmService.triggerSmoochGcm в вашем onMessageReceived.

@Override
public void onMessageReceived(String from, Bundle data) {
    final String smoochNotification = data.getString("smoochNotification");

    if (smoochNotification != null && smoochNotification.equals("true")) {
        GcmService.triggerSmoochGcm(data, this);
    }
}
person Julian Garritano    schedule 11.04.2016
comment
Спасибо, приятно видеть, что Smooch предлагает такую ​​возможность. К сожалению, я уверен, что карнавала нет. Однако я должен иметь возможность использовать тот же подход и дважды вызывать startWakefulService для каждой службы и убедиться, что моя служба намерения ретрансляции указана первой в манифесте. Попробую это и обновлю здесь. - person Greg Ennis; 11.04.2016
comment
Это работает. На самом деле мне не нужно отключать регистрацию GCM и делать это самостоятельно, потому что я использую один и тот же идентификатор отправителя и ключ API для обеих служб. Также я могу использовать флаг smoochNotification, чтобы отправить сообщение в нужное место, а не просто слепо отправить его обоим. Итак, все хорошо... Спасибо! - person Greg Ennis; 11.04.2016

Вы используете оба в качестве зависимостей Gradle? Вам нужно будет загрузить обе библиотеки и использовать их как модули, они, вероятно, используют одни и те же службы, если вы загрузите их, вы сможете изменить имя службы и решить любую проблему, которая может быть связана с обеими.

Я предполагаю, что вам, вероятно, придется создать широковещательный приемник GCM с вашим модулем приложения (даже если он вызывает службы libs).

person sagits    schedule 11.04.2016
comment
Извините, я не понимаю вашего ответа. Имена сервисов не проблема — они оба уже имеют уникальные имена. Я подумал о том, чтобы определить свою собственную службу для вызова двух других, но, похоже, это чревато проблемами. - person Greg Ennis; 11.04.2016