Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 28.04.2013
Сообщений: 95
1

GCM notification на выключеный экран

19.07.2016, 21:27. Показов 2040. Ответов 5

Author24 — интернет-сервис помощи студентам
Народ помогите разобраться в проблеме с GCM. На экран блокировки уведомления приходят, на просто включеный экран уведомления приходят. Если выключить экран (питание) то пуши не доходят, телефон не просыпается и никак не взаимодействует с пришедшим сообщением. Телефон meizu m2 note с lollipop 5.1

Есть класс GCMPushReceiverService:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class GCMPushReceiverService extends GcmListenerService {
 
    //This method will be called on every new message received
    @Override
    public void onMessageReceived(String from, Bundle data) {
        //Getting the message from the bundle
        String message = data.getString("message");
        //Displaying a notiffication with the message
        sendNotification(message);
    }
 
    //This method is generating a notification and displaying the notification
    private void sendNotification(String message) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        int requestCode = 0;
        PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
        Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentText(message)
                .setAutoCancel(true)
                .setContentIntent(pendingIntent);
 
        NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, noBuilder.build()); //0 = ID of notification
    }
}
класс GCMRegistrationIntentService:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class GCMRegistrationIntentService extends IntentService {
    //Constants for success and errors
    public static final String REGISTRATION_SUCCESS = "RegistrationSuccess";
    public static final String REGISTRATION_ERROR = "RegistrationError";
 
    //Class constructor
    public GCMRegistrationIntentService() {
        super("");
    }
 
 
    @Override
    protected void onHandleIntent(Intent intent) {
        //Registering gcm to the device
        registerGCM();
    }
 
    private void registerGCM() {
        //Registration complete intent initially null
        Intent registrationComplete = null;
 
        //Register token is also null
        //we will get the token on successfull registration
        String token = null;
        try {
            //Creating an instanceid
            InstanceID instanceID = InstanceID.getInstance(getApplicationContext());
 
            //Getting the token from the instance id
            token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
 
            //Displaying the token in the log so that we can copy it to send push notification
            //You can also extend the app by storing the token in to your server
            Log.w("GCMRegIntentService", "token:" + token);
 
            //on registration complete creating intent with success
            registrationComplete = new Intent(REGISTRATION_SUCCESS);
 
            //Putting the token to the intent
            registrationComplete.putExtra("token", token);
        } catch (Exception e) {
            //If any error occurred
            Log.w("GCMRegIntentService", "Registration error");
            registrationComplete = new Intent(REGISTRATION_ERROR);
        }
 
        //Sending the broadcast that registration is completed
        LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
    }
}
класс GCMTokenRefreshListenerService:
Java
1
2
3
4
5
6
7
8
9
public class GCMTokenRefreshListenerService extends InstanceIDListenerService {
 
    //If the token is changed registering the device again
    @Override
    public void onTokenRefresh() {
        Intent intent = new Intent(this, GCMRegistrationIntentService.class);
        startService(intent);
    }
}
и MainActivity:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public class MainActivity extends AppCompatActivity {
 
    //Creating a broadcast receiver for gcm registration
    private BroadcastReceiver mRegistrationBroadcastReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        //Initializing our broadcast receiver
        mRegistrationBroadcastReceiver = new BroadcastReceiver() {
 
            //When the broadcast received
            //We are sending the broadcast from GCMRegistrationIntentService
 
            @Override
            public void onReceive(Context context, Intent intent) {
                //If the broadcast has received with success
                //that means device is registered successfully
                if(intent.getAction().equals(GCMRegistrationIntentService.REGISTRATION_SUCCESS)){
                    //Getting the registration token from the intent
                    String token = intent.getStringExtra("token");
                    //Displaying the token as toast
                    Toast.makeText(getApplicationContext(), "Registration token:" + token, Toast.LENGTH_LONG).show();
 
                    //if the intent is not with success then displaying error messages
                } else if(intent.getAction().equals(GCMRegistrationIntentService.REGISTRATION_ERROR)){
                    Toast.makeText(getApplicationContext(), "GCM registration error!", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getApplicationContext(), "Error occurred", Toast.LENGTH_LONG).show();
                }
            }
        };
 
        //Checking play service is available or not
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
 
        //if play service is not available
        if(ConnectionResult.SUCCESS != resultCode) {
            //If play service is supported but not installed
            if(GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                //Displaying message that play service is not installed
                Toast.makeText(getApplicationContext(), "Google Play Service is not install/enabled in this device!", Toast.LENGTH_LONG).show();
                GooglePlayServicesUtil.showErrorNotification(resultCode, getApplicationContext());
 
                //If play service is not supported
                //Displaying an error message
            } else {
                Toast.makeText(getApplicationContext(), "This device does not support for Google Play Service!", Toast.LENGTH_LONG).show();
            }
 
        //If play service is available
        } else {
            //Starting intent to register device
            Intent itent = new Intent(this, GCMRegistrationIntentService.class);
            startService(itent);
        }
    }
 
    //Registering receiver on activity resume
    @Override
    protected void onResume() {
        super.onResume();
        Log.w("MainActivity", "onResume");
        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(GCMRegistrationIntentService.REGISTRATION_SUCCESS));
        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(GCMRegistrationIntentService.REGISTRATION_ERROR));
    }
 
 
    //Unregistering receiver on activity paused
    @Override
    protected void onPause() {
        super.onPause();
        Log.w("MainActivity", "onPause");
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
    }
 
}

manifest.xml :
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.simplifiedcoding.androidgcm">
 
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <permission
        android:name="net.simplifiedcoding.androidgcm.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="net.simplifiedcoding.androidgcm.permission.C2D_MESSAGE" />
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <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="net.simplifiedcoding.androidgcm"/>
            </intent-filter>
        </receiver>
 
        <service android:name=".GCMPushReceiverService" android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
            </intent-filter>
        </service>
 
        <service android:name=".GCMRegistrationIntentService" android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.gms.iid.InstanceID"/>
            </intent-filter>
        </service>
 
    </application>
 
</manifest>
Добавлено через 3 часа 49 минут
Взял другой телефон, все работает.
Теперь вопрос в другом, сообщение приходит на не выводится на экран (экран не загорается вообще). Как сделать что бы отобразилось ?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.07.2016, 21:27
Ответы с готовыми решениями:

Notification и выключенный экран
пишу небольшое приложение на Android 4.4. в фоне работает Service, и каждые 10 минут (в зависимости...

GCM
Начал разбираться с GCM и появилось несколько вопросов. Кто знаком с GCM помогите разобраться,...

Подскажите по GCM
Ранее с push сообщениями от гугла дел не имел. Открыл их турториал - вроде все ок. Вознилка...

По gcm подскажите
Играю с google cloud messaging. Задача: получение уведомлений в реальном времени. По докам от...

5
2883 / 2295 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
20.07.2016, 15:44 2
Короче меня бомбануло и пришлось потратить несколько часов на выяснение.

У меня в наработках давно болтался тестовый проектик с подключенным GCM.
На нем при включенном экране все работает и метод onMessageRevieve вызывается. При выключенном экране - метод не вызывается.
Я сразу сделал вывод что надо копать не в сторону WakeLock-ов, а куда-то дальше.

Студия намекала что порабы сменить GCM на Firebase Messaging.
Перевел проект на FCM, ничего не изменилось. Кстати, стало все намного проще, меньше кода, меньше классов, проще регистрация и т.д.
Метод onMessageReceived теперь принимает RemoteMessage.

Пришлось читать доки внимательно.
Итак, что надо добавить/изменить что бы заработало (уведомление включало экран) на FCM.
1. важно: когда формируется json для передачи сообщения, из него нужно убрать всю ветку notification, просто убрать и все, все данные передавать в секции data. Тогда метод onMessageReceived будет вызываться даже при выключенном экране
2. в методе onMessageReceived до или после показа уведомления вызвать метод типа такого
Java
1
2
3
4
5
    private void wakeUp() {
        PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
        final PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "");
        wl.acquire();
    }
без второго флага экран не включится
1
0 / 0 / 0
Регистрация: 28.04.2013
Сообщений: 95
20.07.2016, 15:49  [ТС] 3
Можно на примере про "убрать всю ветку notification" ?
PowerManager пробовал, студия дает ошибку NullPointerException на строку с PowerManager
0
2883 / 2295 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
20.07.2016, 15:55 4
в коде в начале темы я не нашел код, где отправляется сообщение
0
0 / 0 / 0
Регистрация: 28.04.2013
Сообщений: 95
20.07.2016, 15:59  [ТС] 5
в onMessageReceived - приходит "message" и передается в sendNotification сразу, где и формируется структура сообщения и отправка
0
2883 / 2295 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
20.07.2016, 16:05 6
так я и спашиваю - кто отправляет изначально это сообщение?
0
20.07.2016, 16:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.07.2016, 16:05
Помогаю со студенческими работами здесь

Не доходят GCM уведомления
Всем доброго времени! Столкнулся с такой не понятной проблемой: отправляемые с сервера GCM...

Стек сообщений GCM
Есть новостное приложение, которое получает через GCM id новой новости. Если на долго выключить...

GCM не работает в моей программе
Здравствуйте! Задался такой стандартной задачей, как рассылка новостных push-уведомлений всем...

Шифрование AES-256 GCM
Как на C# можно сделать шифрование AES-256 GCM, без библиотек, хоть что можете предложить WinAPI и...

GCM в C++ Builder Berlin без BAAS
Здравствуйте. В Дельфи все нормально работает. В С++ Builder Berlin update 2 не могу...

Поместите приложение во временный белый список при получении высокоприоритетного gcm
На Android M(Marshmallow) и выше, а также в реализации Google, приложения будут разбужены и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru