Pull to refresh

Нюансы Firebase messaging для начинающих

Reading time 4 min
Views 40K
После публикации на Хабре статьи Артёма Осипова "Push уведомления в Android с помощью Firebase Cloud Messaging для начинающих" возник ряд вопросов, которые удалось решить.

Удалось добиться отправки Push-уведомления с вибрацией и со своим звуком + уведомление в статус баре имеет большую иконку и рядом вмещается весь текст. И неважно активно приложение или висит в фоне — при клике на уведомление Main Activity всегда обновляется и несет в себе параметры из уведомления.

Итак, в layout activity_mail.xml добавим два TextView: один для заголовка уведомления и один для текста.

В MainActivity между:

setContentView(R.layout.activity_main); 

и

Button subscribeButton = (Button) findViewById(R.id.subscribeButton);

удалить все строки и вставить:

        TextView titleText = (TextView)findViewById(R.id.textView);
        TextView bodyText = (TextView)findViewById(R.id.textView2);

        // [START handle_data_extras]
        if (getIntent().getExtras() != null) {
            Intent intent = getIntent();
            String title = intent.getStringExtra("title");
            String body = intent.getStringExtra("body");
            titleText.setText(title);
            bodyText.setText(body);
        }

В файле MyFirebaseMessagingService функция

onMessageReceived

должна иметь такой код:

public void onMessageReceived(RemoteMessage remoteMessage) {
        sendNotification (remoteMessage.getData().get("title"), remoteMessage.getData().get("body"));
    }

и функция

sendNotification

должна принять код такого вида:

private void sendNotification(String messageTitle, String messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra("title",  messageTitle);
        intent.putExtra("body",  messageBody);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);
        
        Bitmap largeIcon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_krolik);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_stat_s1)
                .setLargeIcon(largeIcon)
                .setColor(Color.parseColor("#4B8A08"))
                .setStyle(new NotificationCompat.BigTextStyle().bigText(messageBody))
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.circles0))
                .setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 })
                .setLights(Color.MAGENTA, 500, 1000)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

где

R.drawable.ic_krolik

это моя иконка для уведомления, и

R.raw.circles0

это мой .mp3 файл для звукового сопровождения входящего уведомления, помещённый в директорию raw.

Отправку уведомлений осуществляю через CURL. Сначала для тестов пробовал делать это из терминала Raspberry Pi, где строка имела такой вид:

curl -s "https://gcm-http.googleapis.com/gcm/send" -H "Authorization: key=AIzaSyB4ZanJWaCay_fXxO5z0jI55T8UOwdGNNQ" -H "Content-Type: application/json" -d '{"to": "fJuOOiTAk4w:APA91bHLrg95cyxodZDULzXU604BXJZUJKBaV8LHCbWPvMUlBhr6tzeD7TfNUp1rOMMObYmnC87OyqwRFbROjZV_pGUtNEh1fGFPDf0ApgljyDrLYEmAneKycVX5jCf8Rm2lpC7MDCss","priority" : "high", "vibrate": 1, "notification": { "title": "Port", "body" : "great", "sound": "circles0.mp3", "color": "#379F00", "icon" : "ic_stat_s"}, "data": {"title" : "3.21.15", "body": 12345678}}' 

но когда приложение в фоне или закрыто, то уведомление приходило в урезанном текстовом формате без вибрации, но со своими звуком и иконкой. Пришлось отправлять CURL из PHP. Сначала установим CURL в Raspberry Pi:

sudo apt-get install curl libcurl3 libcurl3-dev php5-curl

Создаём файл PHP:

<?php
// API access key from Google API's Console
define( 'API_ACCESS_KEY', 'AIzaSyB4ZanJWaCay_fXxO5z0jI55T8UOwdGNNQ' );

$registrationIds = array( 'fJuOOiTAk4w:APA91bHLrg95cyxodZDULzXU604BXJZUJKBaV8LHCbWPvMUlBhr6tzeD7TfNUp1rOMMObYmnC87OyqwRFbROjZV_pGUtNEh1fGFPDf0ApgljyDrLYEmAneKycVX5jCf8Rm2lpC7MDCss' );

// prep the bundle
$msg = array
(
	'message' 	=> 'here is a message. message',
	'title'		=> 'This is a title. title',
	'body'	=> 'This is a subtitle. subtitle,  subtitle. subtitle  subtitle. subtitle,  subtitle. subtitle  subtitle. subtitle,  subtitle. subtitle  subtitle. subtitle',
	'tickerText'	=> 'Ticker text here...Ticker text here...Ticker text here',
	'vibrate'	=> 1,
	'sound'		=> 1,
	'largeIcon'	=> 'large_icon',
	'smallIcon'	=> 'small_icon'
);

$fields = array
(
	'registration_ids' 	=> $registrationIds,
	'data'			=> $msg
);
 
$headers = array
(
	'Authorization: key=' . API_ACCESS_KEY,
	'Content-Type: application/json'
);
 
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://gcm-http.googleapis.com/gcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );
echo $result;
?>

Из терминала запускаем отправку уведомления:

php curl.php

и не важно в каком состоянии находится наше приложение: в фоне или работает — мы получаем уведомление со своим звуком, со своей иконкой и текст уведомления вмещается весь. При нажатии на уведомление (если приложение запущено) главное activity обновится и в двух TextView будут помещены title и body уведомления. Если приложение в фоне, то оно запускается с вышеозначенным результатом.

Ежели мы хотим чтобы при нажатии на уведомление открывалось другое активити, то делаем так:
создаём другое activity с именем Main2Activity. В манифесте перед

</application>

добавляем код:

<activity android:name=".Main2Activity">
        <intent-filter>
            <action android:name="OPEN_ACTIVITY_1" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
        </activity>

В CURLе добавляем значение

"click_action": "OPEN_ACTIVITY_1"
Tags:
Hubs:
+6
Comments 4
Comments Comments 4

Articles