2015-06-05 11 views
12

Próbuję zaimplementować powiadomienia push przy użyciu GCM w mojej aplikacji Android. Stworzyłem serwer, aby pomyślnie przekazywać wiadomości do urządzeń, a także utworzyć api do przechowywania tokena urządzenia na serwerze. Utworzono klienta w aplikacji wymienionej w link na podstawie sample project. Stworzyła również funkcję w php, aby przekazywać powiadomienia do aplikacji. Kiedy uruchomię tę funkcję na serwerze, otrzymuję odpowiedź jako sukces. Oznacza to, że wiadomość jest wysyłana z gcm na telefon komórkowy. Ale powiadomienie nie jest wyświetlane, zamiast tego otrzymuję następujące informacje w dzienniku kota.Problem przy otrzymywaniu powiadomień wypychanych na kliencie GCM

06-05 14:58:59.172 23693-28001/com.greenboards.base I/dalvikvm﹕ Could not find method android.app.Notification$Builder.setColor, referenced from method com.google.android.gms.gcm.zza.zzv 
06-05 14:58:59.172 23693-28001/com.greenboards.base W/dalvikvm﹕ VFY: unable to resolve virtual method 184: Landroid/app/Notification$Builder;.setColor (I)Landroid/app/Notification$Builder; 
06-05 14:58:59.173 23693-28001/com.greenboards.base D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0068 
06-05 14:58:59.175 23693-28001/com.greenboards.base W/GcmNotification﹕ Failed to show notification: Missing icon 

jest przechwytywanie komunikatu ja przy użyciu tej samej usługi odbiornika, który oznaczony w przykładowej aplikacji (I dodaje poniżej dla porównania). Więc pomyślałem o problemie w menadżerze powiadomień. Więc skomentowałem to i uruchomiłem aplikację. Ale znowu otrzymuję tę samą odpowiedź bez żadnego powiadomienia. Nie wiem, o co chodzi.

package com.greenboards.base; 

import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.media.RingtoneManager; 
import android.net.Uri; 
import android.os.Bundle; 
import android.support.v4.app.NotificationCompat; 
import android.util.Log; 
import com.greenboards.base.R; 

import com.google.android.gms.gcm.GcmListenerService; 
import com.greenboards.base.SplashScreen; 

public class MyGcmListenerService extends GcmListenerService { 

    private static final String TAG = "MyGcmListenerService"; 

    /** 
    * Called when message is received. 
    * 
    * @param from SenderID of the sender. 
    * @param data Data bundle containing message data as key/value pairs. 
    *    For Set of keys use data.keySet(). 
    */ 
    // [START receive_message] 
    @Override 
    public void onMessageReceived(String from, Bundle data) { 
     String message = data.getString("message"); 
     Log.d(TAG, "From: " + from); 
     Log.d(TAG, "Message: " + message); 

     /** 
     * Production applications would usually process the message here. 
     * Eg: - Syncing with server. 
     *  - Store message in local database. 
     *  - Update UI. 
     */ 

     /** 
     * In some cases it may be useful to show a notification indicating to the user 
     * that a message was received. 
     */ 
     sendNotification(message); 
    } 
    // [END receive_message] 

    /** 
    * Create and show a simple notification containing the received GCM message. 
    * 
    * @param message GCM message received. 
    */ 
    private void sendNotification(String message) { 
     /*Intent intent = new Intent(this, SplashScreen.class); 
     intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
     PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 *//* Request code *//*, intent, 
       PendingIntent.FLAG_ONE_SHOT); 

     Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 
     NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) 
       .setSmallIcon(R.drawable.ic_stat_ic_notification) 
       .setContentTitle("GCM Message") 
       .setContentText(message) 
       .setAutoCancel(true) 
       .setSound(defaultSoundUri) 
       .setContentIntent(pendingIntent); 

     NotificationManager notificationManager = 
       (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 

     notificationManager.notify(0 *//* ID of notification *//*, notificationBuilder.build());*/ 
     Log.v("notification message",message); 
    } 
} 

Ale gdy komunikat odebrany z serwera onMessageReceived musi być wywołana w powyższym słuchacza. W funkcji onMessageReceived jest dostępna funkcja rejestrowania dwóch komunikatów i nadawcy. To też nie działa. Oznacza to, że sama funkcja nie jest wykonywana. Poniżej dodałem treść manifestu.

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

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

    <!-- Application Permissions --> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 

    <permission 
     android:name="com.greenboards.base.permission.C2D_MESSAGE" 
     android:protectionLevel="signature" /> 

    <uses-permission android:name="com.greenboards.base.permission.C2D_MESSAGE" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.VIBRATE" /> 

    <!-- Application Configuration and Activities --> 
    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme"> 
     <activity android:name=".SplashScreen"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <!-- [START gcm_receiver] --> 
     <receiver 
      android:name="com.google.android.gms.gcm.GcmReceiver" 
      android:exported="true" 
      android:permission="com.google.android.c2dm.permission.SEND" > 
      <intent-filter> 
       <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
       <category android:name="com.greenboards.base" /> 
      </intent-filter> 
     </receiver> 
     <!-- [END gcm_receiver] --> 

     <!-- [START gcm_listener] --> 
     <service 
      android:name="com.greenboards.base.MyGcmListenerService" 
      android:exported="false" > 
      <intent-filter> 
       <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
      </intent-filter> 
     </service> 
     <!-- [END gcm_listener] --> 
     <!-- [START instanceId_listener] --> 
     <service 
      android:name="com.greenboards.base.MyInstanceIDListenerService" 
      android:exported="false"> 
      <intent-filter> 
       <action android:name="com.google.android.gms.iid.InstanceID"/> 
      </intent-filter> 
     </service> 
     <!-- [END instanceId_listener] --> 
     <service 
      android:name="com.greenboards.base.RegistrationIntentService" 
      android:exported="false"> 
     </service> 

    </application> 
</manifest> 

Nadal nie mogę przeprowadzić debugowania problemu. Czy robię coś złego, czy też czegoś brakuje?

+1

Właśnie natknąłem się na ten sam problem. Jednak nie otrzymuję ostrzeżenia "' 'W/GcmNotification: Nie można wyświetlić powiadomienia: Brak ikony" ". Czy możesz również pokazać, co wysyłasz do gcm (twoje żądanie curl)? – peshkira

+0

Czy testujesz na urządzeniu z Androidem API 21? setColor został dodany w 21 i wygląda na to, że niektóre biblioteki nadal używają Notification, not NotificationCompat. – Koh

+1

Spróbuj wprowadzić zmiany sugerowane przez @rohitsakala i zaktualizuj swoje repozytorium pomocy technicznej, bibliotekę i usługi odtwarzania ze swojego menedżera SDK. Mam nadzieję że to pomoże. – Koh

Odpowiedz

12

Zgodnie z tym link powinieneś mieć parę klucz/wartość ikony.

Sprawdź parametr ikony powiadomienia. Jest określony jako wymagany.

Należy zatem dołączyć ikonę do JSON.

Przykładem może być

{ 
    "to": 
"ci4ZzC4BW....", 
    "notification": { 
     "title": "Testing", 
     "body": "Success", 
     "icon": "@drawable/myicon" 
    } 
} 

myicon jest obraz o nazwie myicon.png w drawable folderu w aplikacji.

onMessageReceived jest wywoływane, gdy odebrany jest komunikat o wartości użytecznej data. Kiedy zmienimy notification na data (jak poniżej) w powyższym jsonie zostanie wywołana funkcja onMessageReceived.

{ 
    "to": 
"ci4ZzC4BW....", 
    "data": { 
     "title": "Testing", 
     "body": "Success", 
     "icon": "@drawable/myicon" 
    } 
} 
+0

Dzięki @rohitsakala. Rozwiązałeś połowę mojego pytania. Po zmianie na 'json' jak wyżej otrzymuję powiadomienie, ale funkcja' onMessageReceived' nie jest wywoływana podczas otrzymywania powiadomienia. Wiesz dlaczego? Jeśli otrzymam odpowiedź na powyższe pytanie, oznacza to, że przyjmuję to jako odpowiedź. –

+1

@Mahendran musisz zmienić powiadomienie na dane w powyższym jsonie, aby onMessageReceived został wywołany! Przykład: - { "do": "ci4ZzC4BW ...." "dane": { "title": "testing", "ciało": "sukces", "ikona" : „@drawable/myicon " } } a następnie możesz zbudować powiadomienie przez budowniczego powiadomień! – rohitsakala

+0

Tak @rohitsakala. to zadziałało. Jeszcze raz dziękuję. –

0

I napotkać ten sam problem

zapoznać się z informacją w LogCat:

dalvikvm﹕ Could not find method android.app.Notification$Builder.setColor, referenced from method com.google.android.gms.gcm.zza.zzv 

dalvikvm﹕ VFY: unable to resolve virtual method 173: Landroid/app/Notification$Builder;.setColor (I)Landroid/app/Notification$Builder; 

i odniesienie doc API: http://developer.android.com/reference/android/app/Notification.Builder.html

wyszukiwania "setColor" dowiesz się, dodano go w "poziomie interfejsu API 21", co oznacza, że ​​ta metoda działa tylko powyżej 5.0 (Lollipop)

Próbowałem strukturę poniżej testu na 2 różnych urządzeniach OS, 5.0 & 4.4 i działają tylko na 5.0

{"to": "/topics/global","data": {"message": "<message>"},"notification": {"icon": "ic_stat_ic_notification","body": "Use Gradle Command","title": "Self test"}} 

Uwaga: używam test JSON na OS 5.0, powiadomienie jest wyświetlane, ale onMessageReceived jeszcze nie nazywa

+0

Kolor nie jest specyficzny w ładunku danych, więc biorąc pod uwagę, że jest opcjonalny, nie powinno to powodować problemów? Walczę z tym samym problemem, ale muszę wspierać Jellybean i nowsze wersje –

0

Choć stary wątek, chciałem dodać do tego na podstawie niektórych podobnych sprawach przed którym stanąłem.

Aplikacja ma dwa stany: aktywny i nieaktywny.

Jeśli aplikacja jest aktywna, nadal będzie działać wysłanie notification bez ikony o wartości (podejrzewam, że klucz nadal jest wymagany). Działa dla mnie, ale klucz wciąż tam jest.

Moje JSON obiekt wygląda tak:

.., icon=, sound=default, title=Bruce... 

Od docs autorów:

dla aktywnej aplikacji Android, ładowność zgłoszenia są przekazywane do onMessageReceived() w kluczu powiadomień w danych pakiet.

Gdy aplikacja jest nieaktywna:

Powiadomienia są dostarczane na pasku powiadomień, gdy aplikacja jest nieaktywna.

Tutaj pojawia się problem z numerem Missing icon. Tak więc para kluczy i wartości jest wymagana, jeśli aplikacja jest nieaktywna.

Jeśli ładunek jest powiadomieniem, upewnij się, że zawsze ma on parę klucz/wartość icon, aby działała zgodnie z oczekiwaniami, niezależnie od tego, czy aplikacja jest aktywna czy nieaktywna.

See here for details

Wreszcie, nie powinny być wyraźne rozróżnienie pomiędzy tym, co notification jest i co data jest w projektowaniu aplikacji. Używałem notification dla wszystkich komunikatów push dla mojej aplikacji, co moim zdaniem nie jest właściwą metodą.