在 Android 中从 QuickBlox 发送推送通知

Posted

技术标签:

【中文标题】在 Android 中从 QuickBlox 发送推送通知【英文标题】:Sending Push Notification From QuickBlox in Android 【发布时间】:2015-01-08 20:00:45 【问题描述】:

我使用了 quickblox 聊天示例,它运行良好,但我想在其中使用推送通知。所以我遵循了一些教程并阅读了示例,然后就这样做了。但是当我从 QuickBlox 推送通知时管理面板:消息在我的应用程序中没有发生任何事情..没有日志,没有通知..没有事情..!

我确定项目号和api密钥是正确的..

这是清单:

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

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

<permission
    android:name="com.quickblox.sample.chat.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.quickblox.sample.chat.permission.C2D_MESSAGE" />

<!-- 5. Add the following permissions: -->
<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Access to  device info -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

<application
    android:name=".ApplicationSingleton"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".ui.activities.SplashActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:label="@string/app_name"
        android:screenOrientation="portrait" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".ui.activities.NewDialogActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:screenOrientation="portrait" />
    <activity
        android:name="com.quickblox.sample.chat.DialogsActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:screenOrientation="portrait" />
    <activity
        android:name=".ui.activities.ChatActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustResize" />

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

            <category android:name="com.quickblox.sample.chat" />
        </intent-filter>
    </receiver>

    <!-- 2. Add the following intent service: -->
    <service android:name=".GCMIntentService" />

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
</application>
</manifest>

GcmBroadcastReceiver:

package com.quickblox.sample.chat;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver 

@Override
public void onReceive(Context context, Intent intent) 
    // Explicitly specify that GcmIntentService will handle the intent.
    ComponentName comp = new ComponentName(context.getPackageName(), GCMIntentService.class.getName());
    // Start the service, keeping the device awake while it is launching.
    Log.d("Login", "Receiver - Received Message!");
    startWakefulService(context, (intent.setComponent(comp)));
    setResultCode(Activity.RESULT_OK);


GCMIntentService:

package com.quickblox.sample.chat;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.quickblox.sample.chat.definitions.Consts;

public class GCMIntentService extends IntentService 

public static final int NOTIFICATION_ID = 1;

private static final String TAG = GCMIntentService.class.getSimpleName();

private NotificationManager notificationManager;

public GCMIntentService() 
    super(Consts.GCM_INTENT_SERVICE);


@Override
protected void onHandleIntent(Intent intent) 
    Log.i(TAG, "new push");

    Bundle extras = intent.getExtras();
    GoogleCloudMessaging googleCloudMessaging = GoogleCloudMessaging.getInstance(this);
    // The getMessageType() intent parameter must be the intent you received
    // in your BroadcastReceiver.
    String messageType = googleCloudMessaging.getMessageType(intent);

    if (!extras.isEmpty())   // has effect of unparcelling Bundle
        /*
         * Filter messages based on message type. Since it is likely that GCM
         * will be extended in the future with new message types, just ignore
         * any message types you're not interested in, or that you don't
         * recognize.
         */
       if (GoogleCloudMessaging.
                MESSAGE_TYPE_SEND_ERROR.equals(messageType)) 
            processNotification(Consts.GCM_SEND_ERROR, extras);
         else if (GoogleCloudMessaging.
                MESSAGE_TYPE_DELETED.equals(messageType)) 
            processNotification(Consts.GCM_DELETED_MESSAGE, extras);
            // If it's a regular GCM message, do some work.
         else if (GoogleCloudMessaging.
                MESSAGE_TYPE_MESSAGE.equals(messageType)) 
            // Post notification of received message.
            processNotification(Consts.GCM_RECEIVED, extras);
            Log.i(TAG, "Received: " + extras.toString());
        
    
    // Release the wake lock provided by the WakefulBroadcastReceiver.
    WakefulBroadcastReceiver.completeWakefulIntent(intent);


// Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void processNotification(String type, Bundle extras) 
    notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    final String messageValue = extras.getString("message");

    Intent intent = new Intent(this, DialogsActivity.class);
    intent.putExtra(Consts.EXTRA_MESSAGE, messageValue);

    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
            intent, 0);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
            this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle(Consts.GCM_NOTIFICATION)
            .setStyle(
                    new NotificationCompat.BigTextStyle()
                            .bigText(messageValue))
            .setContentText(messageValue);

    mBuilder.setContentIntent(contentIntent);
    notificationManager.notify(NOTIFICATION_ID, mBuilder.build());




我有以下活动注册代码:

    gcm = GoogleCloudMessaging.getInstance(this);

    regId = getRegisterationId(this);
    Log.d("Login", "ID: " + regId);
    if (regId.isEmpty()) 
        new Thread(new Runnable() 
            @Override
            public void run() 

                try 
                    if (gcm == null) 
                        gcm = GoogleCloudMessaging.getInstance(DialogsActivity.this);
                    

                    regId = gcm.register(Consts.PROJECT_NUMBER);
                    Log.d("Login", "Registered! ID: " + regId);

                    runOnUiThread(new Runnable() 
                        @Override
                        public void run() 
                            subscribeToPushNotifications(regId);
                        
                    );


                 catch (Exception e) 
                    Log.d("Login", "Reg e: " + e);
                
            
        ).start();
     else 
        Log.d("Login", "Already Exist");
        subscribeToPushNotifications(regId);
           gcm = GoogleCloudMessaging.getInstance(this);

    regId = getRegisterationId(this);
    Log.d("Login", "ID: " + regId);
    if (regId.isEmpty()) 
        new Thread(new Runnable() 
            @Override
            public void run() 

                try 
                    if (gcm == null) 
                        gcm = GoogleCloudMessaging.getInstance(DialogsActivity.this);
                    

                    regId = gcm.register(Consts.PROJECT_NUMBER);
                    Log.d("Login", "Registered! ID: " + regId);

                    runOnUiThread(new Runnable() 
                        @Override
                        public void run() 
                            subscribeToPushNotifications(regId);
                        
                    );


                 catch (Exception e) 
                    Log.d("Login", "Reg e: " + e);
                
            
        ).start();
     else 
        Log.d("Login", "Already Exist");
        subscribeToPushNotifications(regId);
    

public void subscribeToPushNotifications(String regId) 
    String deviceId = ((TelephonyManager) getBaseContext()
            .getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();

    QBMessages.subscribeToPushNotificationsTask(regId, deviceId,
            QBEnvironment.DEVELOPMENT,
            new QBEntityCallbackImpl<ArrayList<QBSubscription>>() 
                @Override
                public void onSuccess(ArrayList<QBSubscription> result,
                        Bundle params) 
                    Log.d("Login", "Successfully Registered");
                

                @Override
                public void onError(List<String> errors) 
                    Log.d("Login", "e : " + errors);
                
            );



private String getRegisterationId(Context context) 
    SharedPreferences prefs = getGCMPreferences(context);
    String registerationId = prefs.getString(PROPERTY_REG_ID, "");
    if (registerationId.isEmpty()) 
        Log.d("Login", "Not registered!");
        return "";
    
    return registerationId;



private SharedPreferences getGCMPreferences(Context context) 
    return getSharedPreferences(DialogsActivity.class.getSimpleName(),
            Context.MODE_PRIVATE);


private void storeRegisterationId(Context context, String regId) 
    final SharedPreferences prefs = getGCMPreferences(context);
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString(PROPERTY_REG_ID, regId);
    editor.commit();

我成功完成了注册.. :S

我已经寻找解决方案 2 天了:/ 任何帮助将不胜感激.. 谢谢。

【问题讨论】:

【参考方案1】:

我没有足够的声誉来发表评论,所以我把它作为一个可能的答案 -

过去几天我一直在做同样的事情,这里有几件事需要检查:

    在设置 GCM API 密钥时,是否设置了任何 IP?您应该将此留空以接受全部。

    当您说注册成功时,您的意思是您从subscribeToPushNotificationsTask 收到onSuccess Log 消息吗?检查您的设备 ID;我的 deviceId 为 null 来自:

String deviceId = ((TelephonyManager)getBaseContext().getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();

所以我不得不使用

String deviceId = Secure.getString(this.getContentResolver(), Secure.ANDROID_ID);

    您在 Quickblox 管理面板 > 消息中选择了哪些选项?确保您在频道选项下选择了“GCM (Android Push)”。

    最后,确保您的环境使用所有生产或所有开发 (QBEnvironment.DEVELOPMENT)。我不知何故最终混音,现在将它们全部转换为生产。

我的推送通知现在可以正常工作,所以如果您有具体问题,也许我可以提供更多帮助。

【讨论】:

以上是关于在 Android 中从 QuickBlox 发送推送通知的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中从 Quickblox 进行身份验证和获取会话令牌

如何在 Quickblox iOS 中从远程视频中捕获视频帧

没有收到推送通知,quickblox,android

Quickblox:我如何知道消息是不是已发送/接收?

使用 Quickblox SDK 未收到从 iOS 到 android 的推送通知

带有 Quickblox 的 Android 版 Google Cloud Messaging