0

У меня возникла проблема с моей реализацией GCM на Android, min SDK 15. Я отлично могу получать push-уведомления от GCM, а моя реализация GcmListenerService функционирует onMessageReceived(...) callback. Моя проблема, однако, в том, что всякий раз, когда кто-то выполняет прием, он заставляет приложение на передний план!Android GcmReceiver/GcmListenerService Принудительное приложение для Foreground при получении

Ожидаемое поведение: я могу получать эти push-уведомления по мере их поступления, независимо от того, находится ли приложение в фоновом режиме, а затем создать уведомление в лотке, который запускает действие, если это потребует полезная нагрузка.

Поток, который вызывает проблему, это (физическое устройство, Motorola Razr M xt907):

1. Запустить приложение. Ключ устройства проверяется с помощью экземпляра GCM.
2. Нажмите «Домой» на Android.
3. Нажмите кнопку «Последние приложения»; удалите приложение; подождите несколько секунд
4. Вручную отправить уведомление толчок к устройству через GCM
5. Применение получает уведомление, а само приложение силы обратно на первый план

Если это поможет, я бросил главное приложение и приемники на отдельные процессы, чтобы получить представление о том, что на самом деле происходит в фоновом режиме, и усеченный вариант это ниже:

NotificationsProcess I/MultiDex﹕ VM with version 1.6.0 does not have multidex support 
NotificationsProcess I/MultiDex﹕ install 
NotificationsProcess I/MultiDex﹕ MultiDexExtractor.load(/data/app/com.MyApp.MyAppmobile.alpha-1.apk, false) 
NotificationsProcess I/MultiDex﹕ loading existing secondary dex files 
NotificationsProcess I/MultiDex﹕ load found 1 secondary dex files 
NotificationsProcess I/MultiDex﹕ install done 
... 
[... Main Application Code ... ] 
... 
PrivateProcess I/MultiDex﹕ VM with version 1.6.0 does not have multidex support 
PrivateProcess I/MultiDex﹕ install 
PrivateProcess I/MultiDex﹕ MultiDexExtractor.load(/data/app/com.MyApp.MyAppmobile.alpha-1.apk, false) 
PrivateProcess I/MultiDex﹕ loading existing secondary dex files 
PrivateProcess I/MultiDex﹕ load found 1 secondary dex files 
PrivateProcess I/MultiDex﹕ install done 
NotificationsProcess D/MyApp﹕ Network is connected via WIFI 
NotificationsProcess D/MyApp﹕ Executing networkWentOnline() callbacks 
NotificationsProcess D/MyApp﹕ Successfully connected to GoogleApiServices for Location Awareness. 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
GcmListenerService finally comes alive 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
NotificationsProcess D/GCMMessageHandler﹕ From: 149994375514 
NotificationsProcess D/GCMMessageHandler﹕ Message: null 
NotificationsProcess D/GCMMessageHandler﹕ Data: Bundle[{gcm.notification.body=Hey there dude, I like text =), collapse_key=com.MyApp.MyAppmobile.alpha}] 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
GcmListenerService is finished 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

NotificationsProcess D/MyApp﹕ [... Main Application Code ... ] 
NotificationsProcess D/MyApp﹕ [... Main Application Code ... ] 
PrivateProcess D/MyApp﹕ [... Main Application Code ... ] 
PrivateProcess D/MyApp﹕ [... Main Application Code ... ] 
PrivateProcess D/MyApp﹕ [... Main Application Code ... ] 
PrivateProcess D/MyApp﹕ [... Main Application Code ... ] 
PrivateProcess D/MyApp﹕ [... Main Application Code ... ] 
PrivateProcess V/TDCollateJSON﹕ SQLite3 handle is 1417181168 
PrivateProcess D/MyApp﹕ [... Main Application Code ... ] 
PrivateProcess D/MyApp﹕ [... Main Application Code ... ] 
PrivateProcess D/MyApp﹕ [... Main Application Code ... ] 
PrivateProcess D/MyApp﹕ [... Main Application Code ... ] 
PrivateProcess D/MyApp﹕ [... Main Application Code ... ] 

Моего Android манифест установка как таковые, со следующими пунктами найденных под главными <application> тег:

<receiver 
    android:name="com.google.android.gms.gcm.GcmReceiver" 
    android:process="NotificationsProcess" 
    android:exported="true" 
    android:permission="com.google.android.c2dm.permission.SEND" > 
    <intent-filter 
     android:process="NotificationsProcess"> 
     <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
     <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
    </intent-filter> 
</receiver> 
<service 
    android:name=".GCMMessageHandler" 
    android:process="NotificationsProcess" 
    android:exported="false"> 
    <intent-filter 
     android:process="NotificationsProcess"> 
     <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
    </intent-filter> 
</service> 
<service 
    android:name=".GCMInstanceIDListenerService" 
    android:process="NotificationsProcess" 
    android:exported="false"> 
    <intent-filter 
     android:process="NotificationsProcess"> 
     <action android:name="com.google.android.gms.iid.InstanceID"/> 
    </intent-filter> 
</service> 
<service 
    android:name=".RegistrationIntentService" 
    android:process="NotificationsProcess" 
    android:exported="false"> 
</service> 

[... Other app activities ...] 

<activity 
    android:name=".activities.SyncActivity" 
    android:label="@string/app_name" 
    android:theme="@style/Theme.AppCompat.NoActionBar" 
    android:screenOrientation="portrait"> 
    <intent-filter> 
     <action android:name="android.intent.action.MAIN" /> 
     <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 
</activity> 

У меня отличное чувство, что это простая проблема, но я не удивлюсь, если это будет гораздо более тонкая проблема. Если я могу предложить больше вывода приложений, пожалуйста, дайте мне знать!

Любые опыт, мудрость или пути, чтобы попробовать для этого, очень признательны!

EDIT:

Я в том числе реализацию GcmListenerService. Обратите внимание, что единственное, что я делаю, это на самом деле создать уведомление и опубликовать его. С no взаимодействие с пользователем, приложение просто выходит на передний план - нет крана, нет салфетки, только poof переднего плана.

@Override 
public void onMessageReceived(String from, Bundle data) { 

    String message = data.getString("gcm.notification.body"); 
    Log.d("GCMMessageHandler", "From: " + from); 
    Log.d("GCMMessageHandler", "Message: " + message); 

    MyApp.WAS_STARTED_FROM_NOTIFICATION = true; 

    NotificationCompat.Builder mBuilder = 
      new NotificationCompat.Builder(this) 
        .setSmallIcon(R.drawable.ic_launcher) 
        .setContentTitle("Hello from MyApp") 
        .setContentText(message); 

    NotificationManager mNotificationManager = 
      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
    mNotificationManager.notify(MY_APP_NOTIFICATION_ID, mBuilder.build()); 

} 
+0

Canyou разместить код для класса, который»... создайте уведомление в лотке, в котором начинается действие, если требуется его полезная нагрузка ... ». Мое первое предположение заключается в том, что вы не используете ожидающее намерения при создании уведомления в лотке – petey

+1

Лучше, если вы разместите свой gcmlistenerservice, где будете обрабатывать сообщение gcm. Я написал много приложений, но я не видел такого поведения, и нет необходимости запускать его в другом процессе. – 7383

+0

@petey Спасибо за комментарии! Я добавил экземпляр GcmListenerService к основному сообщению. –

ответ

0

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

Его комментарий задал вопрос о запуске приложения, чтобы убедиться, что что-то еще в потоке не заставило действие, предназначенное для стрельбы. Что-то я сделал не осознать, что Android (как неоперившийся разработчик) был полным жизненным циклом класса Application и его отношением к приемникам и фильтрам Intent.

Моя проблема в том, что класс MyApplication (расширенный от приложения) содержал логику, которая активировала Intent на основе нескольких других сохраненных состояний приложения - не было ничего, что защищало бы от этого, если фильтр заставил приложение открыто, и эти приемники были в первый раз, когда приложение должно было быть запущено каким-либо образом, кроме пусковой установки устройства.

Для тех, кто еще испытывает аналогичные проблемы: Intent фильтров для того, чтобы функционировать, всегда будут огнь вашего проявленного Применения, в соответствии со стандартом андроида поведения. Сделайте Уверенный, что ваш основной логический поток способен справиться с тем, что ваш запуск может происходить из мест другой, чем пользователь нажимает на вас!

PS: Для любых разработчиков, кому это сильно очевидно, быть нежным, и помогают объяснить большой обзор Android концепции приложения жизненный цикл ваших коллег;)

+0

, и какой код вам нужно было точно изменить, чтобы он не срабатывал? – trippedout

+0

Я не могу опубликовать код точно, но я могу проиллюстрировать его немного лучше, если это поможет: * Устройство получает уведомление * -> * MyApplication Starts * -> * Код MyApplication проверяет сохраненное состояние и видит, что пользователю необходимо чтобы увидеть экран и автоматически открыть его * -> * GcmMessageHandler наконец получает намерение push noticification * Третий шаг в этом проблема: в общем, кажется, что ваше основное приложение НЕ ДОЛЖНО выполнять какую-либо автоматическую работу на основе работы on state, и вместо этого такое действие должно начинаться с какого-то основного «запуска», который пользователь явно открывает. –

+1

ohhh вы начали работу с подкласса приложения напрямую, я вас сейчас дам, и да, если вы это сделаете, у вас будет плохое время :) спасибо, что написано – trippedout

Смежные вопросы