2015-07-27 9 views
13

Próbuję użyć powiadomienia gcm. Mój kod serwera działa dobrze i odnoszę sukces jako potwierdzenie.Powiadomienie Gcm odebrane po godzinach na niektórych urządzeniach

Problemem jest to zgłoszenie jest uzyskiwanie wysłany poprawnie:

1) W większości urządzeń powiadamiania jest odbierany natychmiast. Testowane na google nexus, telefony Sony.

2) Inne urządzenia również otrzymają powiadomienie, ale po kilku godzinach. Tak, godzin. Przetestowany na Karbonn, Micromax niektóre telefony.

Uwaga:

Wszystkie urządzenia są podłączone do tej samej sieci Wi-Fi tak łączność nie problem. Używanie php po stronie serwera; Istnieje kilka pytań bez odpowiedzi dotyczących tego tematu. Ja niniejszym wymieniając niektóre z nich:

gcm notification is not working on some devices like micromax

One device doesn't receive push notifications (GCM)

Push notifications delay with GCM

Ktoś inny o podobnym problemem dołączyć swoje pytanie też.

Nieudane próby sprostowania:

Mam również wprowadziła zmiany do kodu po przejściu przez kilka pytań, w których znaleziono twórcy ich rozwiązanie jak usunięcie tego wiersza kodu z onHandleIntent()

GcmBroadcastReceiver.completeWakefulIntent(intent); 

Lub zmieniając wartość delay_while_ideal na true/false w kodzie serwera.

lub osobno wymienić odbiornik i rejestracji intencyjny filtr

<intent-filter> 
<action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
<category android:name="com.nothing.gcmclient" /> 
</intent-filter> 
<intent-filter> 
<action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
<category android:name="com.nothing.gcmclient" /> 
</intent-filter> 

kod: Android.manifest

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.nothing.gcmclient" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="9" 
     android:targetSdkVersion="22" /> 

    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 

    <permission 
     android:name="com.nothing.gcmclient.permission.C2D_MESSAGE" 
     android:protectionLevel="signature" /> 

    <uses-permission android:name="com.nothing.gcmclient.permission.C2D_MESSAGE" /> 
    <uses-permission android:name="com.nothing.gcmclient.c2dm.permission.RECEIVE" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.VIBRATE" /> 

    <uses-permission android:name="ANDROID.PERMISSION.WRITE_EXTERNAL_STORAGE"></uses-permission> 
    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:name=".RegisterActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <activity 
      android:name=".MainActivity" 
      android:configChanges="orientation|keyboardHidden" 
      android:label="@string/app_name" > 
     </activity> 

     <receiver 
      android:name=".GcmBroadcastReceiver" 
      android:permission="com.google.android.c2dm.permission.SEND" > 
      <intent-filter> 
       <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
       <category android:name="com.nothing.gcmclient" /> 
      </intent-filter> 
      <intent-filter> 
       <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
       <category android:name="com.nothing.gcmclient" /> 
      </intent-filter> 
     </receiver> 

     <service android:name=".GCMNotificationIntentService"></service> 

     <activity 
      android:name=".ChatActivity" 
      android:label="@string/title_activity_chat" > 
     </activity> 
     <activity 
      android:name=".RegisterScreen" 
      android:label="@string/title_activity_register_screen" > 
     </activity> 
     <activity 
      android:name=".RegisterChatButtonActivity" 
      android:label="@string/title_activity_register_chat_button" > 
     </activity> 
     <activity 
      android:name=".ChatHistory" 
      android:label="@string/title_activity_chat_history" > 
     </activity> 
     <activity 
      android:name=".MessageScreen" 
      android:label="@string/title_activity_message_screen" > 
     </activity> 
    </application> 

</manifest> 

Kod: GCMNotificationIntentService.java

public class GCMNotificationIntentService extends IntentService { 

    public static final int NOTIFICATION_ID = 1; 
    private NotificationManager mNotificationManager; 
    NotificationCompat.Builder builder; 

    public GCMNotificationIntentService() { 
     super("GcmIntentService"); 
    } 

    public static final String TAG = "GCMNotificationIntentService"; 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     Bundle extras = intent.getExtras(); 
     GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); 

     String messageType = gcm.getMessageType(intent); 

     if (!extras.isEmpty()) { 
      if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR 
        .equals(messageType)) { 
       sendNotification("Send error: " + extras.toString()); 
      } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED 
        .equals(messageType)) { 
       sendNotification("Deleted messages on server: " 
         + extras.toString()); 
      } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE 
        .equals(messageType)) { 
       String sender=extras.get(Config.SENDER).toString().toLowerCase(); 
       String message=extras.get(Config.MESSAGE_KEY).toString(); 

       if(!RegisterActivity.appVisible==true) 
       { 
        sendNotification("New message Received from "+ extras.get(Config.SENDER)); 
       } 
      } 
     } 
     //GcmBroadcastReceiver.completeWakefulIntent(intent); 
    } 

    private void sendNotification(String msg) { 
     Log.d(TAG, "Preparing to send notification...: " + msg); 
     mNotificationManager = (NotificationManager) this 
       .getSystemService(Context.NOTIFICATION_SERVICE); 

     PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 
       new Intent(this, ChatHistory.class), 0); 

     NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
       this).setSmallIcon(R.drawable.gcm_cloud) 
       .setContentTitle("New Notification") 
       .setStyle(new NotificationCompat.BigTextStyle().bigText(msg)) 
       .setContentText(msg); 

     mBuilder.setContentIntent(contentIntent); 
     mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build()); 
     Log.d(TAG, "Notification sent successfully."); 
    } 
} 

Eksperci proszę spojrzeć na problem i zasugerować odpowiednią przyczynę i rozwiązanie. Moja aplikacja byłaby bezużyteczna, gdyby działała tylko dla niektórych telefonów. Jeśli potrzebujesz więcej plików w naszej aplikacji, uprzejmie poinformuj.

PS - Prosimy o przeczytanie całego pytania, a następnie zamieścić swoje komentarze lub odpowiedzi lub oznaczyć duplikat, jeśli to konieczne.

+0

Brzmi jak problem z urządzeniem lub problem z serwerem GCM (prawdopodobnie urządzenie).Żadne z nich nie będzie w stanie naprawić – tyczj

+0

Próbowałem na 7 urządzeniach. Nie powiodło się dla trzech osób. Ten odsetek jest wystarczająco wysoki, by sądzić, że problem specyficzny dla urządzenia. – user2653926

+0

Możesz wypróbować dwie oficjalne aplikacje demonstracyjne [tutaj] (https://github.com/google/gcm/tree/master/samples/android) i [tutaj] (https://github.com/googlesamples/google-services/tree/master/android/gcm). Jeśli problem nadal istnieje, myślę, że to na pewno problem specyficzny dla urządzenia, więc może uda Ci się znaleźć firmę wsparcia przez firmę. – bjiang

Odpowiedz

1

Miałem ten sam problem.

Najpierw upewnij się, że wiadomości nie przekraczają maksymalnej długości zwęglenia. Po drugie, wiele osób powiedziało mi, że mogą to być problemy z zaporą ogniową z telefonów lub sieci, ale inne aplikacje (np. WhatsApp) działały sprawnie. Po kilku tygodniach zatrzymało to opóźnienia i moje problemy rozwiązano sam.

Wiem, że to nie jest prawdziwe rozwiązanie, ale spróbuj czekać, opracuj inne rzeczy i wróć, aby przetestować je ponownie za kilka tygodni.

+0

Czy znalazłeś coś złego w manifeście – user2653926

+1

Nie, w moim przypadku, ja zrezygnowałem z obsługi wszystkich urządzeń i kontynuowałem budowę aplikacji. Kiedy aplikacja została zakończona, po prostu przetestowałem i wszystko działało. Radzę nie przestawać, zakończyć aplikację tak, jakby działała prawidłowo, niż ponownie przetestować. Prawdopodobnie system Google ma pewną niezawodność aplikacji lub jakiś skalowalny system oceniania. –

+0

Te słowa są zachęcające. Mam nadzieję, że to działa. – user2653926

1

Ponieważ otrzymujesz powiadomienia na niektórych urządzeniach zgodnie z oczekiwaniami, zakładam, że Twój manifest i kod Java, które napisałeś, powinny być w porządku. Czy mógłbyś opublikować swoją klasę GcmBroadcastReceiver? To powinno być coś takiego:

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver { 

/** 
* Starts GcmIntentService which handles the intent. 
*/ 
@Override 
public void onReceive(Context context, Intent intent) {  

    // Explicitly specify that GcmIntentService will handle the intent. 
    ComponentName comp = new ComponentName(context.getPackageName(), GCMNotificationIntentService.class.getName()); 

    // Start the service, keeping the device awake while it is launching. 
    startWakefulService(context, (intent.setComponent(comp))); 
    setResultCode(Activity.RESULT_OK); 
} 

Ta klasa jest odpowiedzialna za budzenie się swoją aplikację (jeśli proces app's nie został jeszcze uruchomiony) i nazywając swoją usługę, jeśli nie wdrożyć go tak Android system nie uruchomi usługi GCMNotificationIntentService, ponieważ aplikacja nie jest jeszcze uruchomiona, dlatego nie można wyświetlić powiadomienia. To również wyjaśnia, dlaczego powiadomienia są natychmiast odbierane na niektórych urządzeniach. Zakładam, że otrzymujesz powiadomienie na każdym urządzeniu, ale nie wyświetlaj go natychmiast.

Ponadto nie jest to zdecydowanie konieczne zadzwonić GcmBroadcastReceiver.completeWakefulIntent(intent); w GCMNotificationIntentService jeśli BroadcastReceiver jest poprawna, ponieważ linia ta nawet nie może mieć żadnego wpływu, ponieważ nigdy nie jest wywoływana (jeśli moje założenie jest słuszne, że BroadcastReceiver jest problem).

O ile widzę, używasz starej wersji GCM-API. Nie wiem, czy wiesz, że nowsze API GCM są dostępne od kilku tygodni. Miałem też podobny problem ze starą wersją jakiś czas temu, ale ponieważ używam nowego interfejsu API (w tym InstanceID-API, który zastępuje stary identyfikator rejestracyjny), nigdy nie miałem już żadnego problemu z powiadomieniem o opóźnieniu.

Potrafię zdecydowanie zarekomendować wdrożenie nowego interfejsu API GCM. Zobacz docs for further information. I that´s the doc dla InstanceID-API.

+0

Przejdę przez to. Dzięki – user2653926

7
  • GCM działa za pośrednictwem usługi Google Play
  • Urządzenia połączyć się z Google Play przez TCP na porcie 5228
  • Urządzenia należy używać portu 443 jako awaryjnej czy port 5228 jest zablokowany, ale najwyraźniej tylko don” t używać fallback czasami (stało się z wielu moich urządzeń)
  • urządzenie wysyła pakiet tętno do usługi Google Play co 28 minut na telefon i 15 minut na wifi
  • Można sprawdzić stan połączenia, częstotliwość pulsu, adres i numer portu połączenia, itd numerem *#*#426#*#* na urządzeniu

Jak rozwiązać typowe problemy, gdy urządzenia nie należy podłączać do usługi Google Play na połączenia WiFi lub stracić często:

  1. otwarty port 5228
  2. Skonfiguruj routery, żeby nie zabić nieaktywnych połączeń tCP, zanim czeka co najmniej 15 minut

Aby uzyskać więcej informacji, patrz this post on Google Product Forums.

+0

Dzięki za informację .. Ten kod był szczególnie pomocny. – user2653926

+0

Czy możesz wyjaśnić, jak "otworzyć port 5228"? –

+0

Po prostu niesamowite. –

Powiązane problemy