Подтвердить что ты не робот

Уведомление Gcm, полученное после нескольких часов на некоторых устройствах

Я пытаюсь использовать gcm-уведомление. Мой серверный код работает нормально, и я получаю успех в качестве подтверждения.

Проблема заключается в том, что уведомление отправляется должным образом:

1) В большинстве устройств уведомление принимается мгновенно.  Протестировано на Google Nexus, телефоны sony.

2) Другие устройства также получают уведомление, но через несколько часов. Да, часы. Протестировано на Karbonn, Micromax на некоторых телефонах.

Примечание:

Все устройства подключены к одному и тому же Wi-Fi, поэтому сетевое подключение не является проблемой. Использование php на стороне сервера; Есть несколько неотвеченных вопросов по этой теме. Настоящим я перечисляю некоторые из них:

gcm уведомление не работает на некоторых устройствах, таких как micromax

Одно устройство не получает push-уведомления (GCM)

Задержка отправки уведомлений с помощью GCM

Любой другой, имеющий аналогичную проблему, также присоединяет ваш вопрос.

Неудачные испытания исправления:

Я также вносил изменения в код после прохождения нескольких вопросов, в которых разработчики нашли свое решение, подобное удаление этой строки кода из onHandleIntent()

GcmBroadcastReceiver.completeWakefulIntent(intent);

Или измените значение delay_while_ideal на true/false в коде сервера.

Или отдельно указывая фильтр-приемник и фильтр регистрации

<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>

код: 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>

Код: 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.");
    }
}

Эксперты, пожалуйста, изучите проблему и предложите соответствующую причину и решение. Мое приложение было бы бесполезно, если оно работает только для определенных телефонов. Если вам нужен еще один файл в нашем приложении, сообщите об этом.

PS. Пожалуйста, прочитайте весь вопрос, а затем разместите свои комментарии или ответы или отметьте дубликат, если необходимо.

4b9b3361

Ответ 1

  • GCM работает через службы Google Play.
  • Устройства подключаются к сервисам Google Play через TCP на порту 5228
  • Устройства должны использовать порт 443 как резерв, если порт 5228 заблокирован, но, по-видимому, они просто не используют резервную копию (иногда с несколькими моими устройствами).
  • Устройство отправляет пакет heartbeat в Службы Google Play каждые 28 минут на мобильном устройстве и 15 минут на Wi-Fi
  • Вы можете проверить состояние соединения, интервал сердцебиения, адрес соединения и порт и т.д., набрав *#*#426#*#* на устройстве

Как устранить распространенные проблемы, когда устройства не подключаются к сервисам Google Play на Wi-Fi или часто теряют соединение:

  • Открытый порт 5228
  • Настройте свои маршрутизаторы, чтобы они не убивали неактивные подключения tcp до ожидания не менее 15 минут

Подробнее см. этот пост на форумах продуктов Google.

Ответ 2

У меня была та же проблема.

Во-первых, убедитесь, что ваши сообщения не превышают максимальную длину char. Во-вторых, многие люди говорили мне, что это могут быть проблемы с брандмауэром из телефонов или сети, но другие приложения (например, whatsapp) работали плавно. Через пару недель он остановил задержки, и мои проблемы были решены в одиночку.

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

Ответ 3

Поскольку вы получаете уведомления на некоторых устройствах, как ожидается, я предполагаю, что ваш манифест и Java-код, который вы опубликовали, в основном должны быть в порядке. Не могли бы вы разместить свой GcmBroadcastReceiver -класс? Это должно быть примерно так:

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

Этот класс отвечает за пробуждение вашего приложения (если процесс вашего приложения еще не запущен) и вызов вашей службы, если вы его не реализуете, система Android не запускает ваш GCMNotificationIntentService, потому что приложение не но, тем не менее, уведомление не может быть отображено. Это также объясняет, почему уведомления принимаются на некоторых устройствах немедленно. Поэтому я предполагаю, что вы получаете уведомление на каждом устройстве, но просто не показываете его мгновенно.

Кроме того, совершенно необязательно вызывать GcmBroadcastReceiver.completeWakefulIntent(intent); в GCMNotificationIntentService, если ваш BroadcastReceiver является правильным, потому что эта строка даже не может иметь никакого эффекта, поскольку она никогда не вызывается (если мое предположение верно, что проблема с BroadcastReceiver является проблемой).

Насколько я вижу, вы используете старую версию GCM-API. Я не знаю, знаете ли вы, что новый GCM-API доступен с нескольких недель. У меня также была аналогичная проблема со старой версией некоторое время назад, но поскольку я использую новый API (в том числе InstanceID-API, который заменяет старый идентификатор регистрации), у меня больше не было проблемы с задержкой уведомлений.

Я могу настоятельно рекомендовать реализовать новый GCM-API. Дополнительную информацию см. В документах . И это документ для InstanceID-API.