设备上未收到Android GCM消息

时间:2015-11-22 20:00:55

标签: android google-cloud-messaging

我尝试设置我的应用以接收推送通知。但问题是,虽然它们是从服务器成功发送的,但它们并没有到达设备。

这是我的代码:

清单

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />

<permission android:name="com.jampez.smalltalk.permission.C2D_MESSAGE" 
    android:protectionLevel="signature" />
<uses-permission android:name="com.jampez.smalltalk.permission.C2D_MESSAGE" />

<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<!-- Network State Permissions to detect Internet status -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<activity
        android:name=".MainActivity"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
        android:label="@string/app_name" >
        <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.gcm.GCMBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>

            <!-- Receives the actual messages. -->
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <!-- Receives the registration id. -->
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />

            <category android:name="com.jampez.smalltalk" />
        </intent-filter>
    </receiver>

GCMIntentService.java

这是主要包中的其他活动

public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";

public GCMIntentService() {
    super(SENDER_ID);
}

/**
 * Method called on device registered
 **/
@Override
protected void onRegistered(Context context, String registrationId) {
    Log.i(TAG, "Device registered: regId = " + registrationId);
    displayMessage(context, "Your device registred with GCM");
    ServerUtilities.register(context, registrationId);
}

/**
 * Method called on device un registred
 * */
@Override
protected void onUnregistered(Context context, String registrationId) {
    Log.i(TAG, "Device unregistered");
    displayMessage(context, getString(R.string.gcm_unregistered));
    ServerUtilities.unregister(context, registrationId);
}

/**
 * Method called on Receiving a new message
 * */
@Override
protected void onMessage(Context context, Intent intent) {
    Log.i(TAG, "Received message");
    String message = intent.getExtras().getString("message");

    displayMessage(context, message);
    // notifies user
    generateNotification(context, null, message, (long) 01);
}

/**
 * Method called on receiving a deleted message
 * */
@Override
protected void onDeletedMessages(Context context, int total) {
    Log.i(TAG, "Received deleted messages notification");
    String message = getString(R.string.gcm_deleted, total);
    displayMessage(context, message);
    // notifies user
    generateNotification(context, null, message, (long) 00);
}

/**
 * Method called on Error
 * */
@Override
public void onError(Context context, String errorId) {
    Log.i(TAG, "Received error: " + errorId);
    displayMessage(context, getString(R.string.gcm_error, errorId));
}

@Override
protected boolean onRecoverableError(Context context, String errorId) {
    // log message
    Log.i(TAG, "Received recoverable error: " + errorId);
    displayMessage(context, getString(R.string.gcm_recoverable_error,
            errorId));
    return super.onRecoverableError(context, errorId);
}

/**
 * Issues a notification to inform the user that server has sent a message.
 */
private static void generateNotification(Context context, String title, String message, Long extra) {
    int icon = R.drawable.ic_launcher;

    Integer i = (int) (long) extra;

    if(title == null){
     title = context.getString(R.string.app_name);
    }

    Intent notificationIntent  = new Intent(context, MainActivity.class);

    PendingIntent Int = PendingIntent.getActivity(context, i, notificationIntent, 0);
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
            .setSmallIcon(icon)
            .setContentTitle(title)
            .setContentIntent(Int)
            .setContentText(message)
            .setAutoCancel(true) 
            .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS);
        NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(i, mBuilder.build());


}
}

AppConfig.java

public static final String DISPLAY_MESSAGE_ACTION = "com.jampez.smalltalk.DISPLAY_MESSAGE";

public static final String TAG = "GCM";

static final String EXTRA_MESSAGE = "message";

/**
 * Notifies UI to display a message.
 * <p>
 * This method is defined in the common helper because it's used both by
 * the UI and the background service.
 *
 * @param context application's context.
 * @param message message to be displayed.
 */
public static void displayMessage(Context context, String message) {
    Intent intent = new Intent(DISPLAY_MESSAGE_ACTION);
    intent.putExtra(EXTRA_MESSAGE, message);
    context.sendBroadcast(intent);
}

ServerUtilities.java

public final class ServerUtilities {
private static final int MAX_ATTEMPTS = 5;

/**
 * Register this account/device pair within the server.
 *
 */
public static void register(final Context context, final String regId) {
    Log.i(TAG, "registering device (regId = " + regId + ")");


    // Once GCM returns a registration id, we need to register on our server
    // As the server might be down, we will retry it a couple
    // times.
    for (int i = 1; i <= MAX_ATTEMPTS;) {
        Log.d(TAG, "Attempt #" + i + " to register");
        displayMessage(context, context.getString(R.string.server_registering, i, MAX_ATTEMPTS));
        GCMRegistrar.setRegisteredOnServer(context, true);
        String message = context.getString(R.string.server_registered);
        AppConfig.displayMessage(context, message);
        return;
    }
    String message = context.getString(R.string.server_register_error,
            MAX_ATTEMPTS);
    AppConfig.displayMessage(context, message);
}

/**
 * Unregister this account/device pair within the server.
 */
public static void unregister(final Context context, final String regId) {
    Log.i(TAG, "unregistering device (regId = " + regId + ")");
    Map<String, String> params = new HashMap<String, String>();
    params.put("regId", regId);
    //post(serverUrl, params);
    GCMRegistrar.setRegisteredOnServer(context, false);
    String message = context.getString(R.string.server_unregistered);
    AppConfig.displayMessage(context, message);
}

}

2 个答案:

答案 0 :(得分:0)

我不知道这是否是主要原因,但您错过了许可。由于GCM需要Google帐户,因此您也应声明以下权限:

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

另外,也声明service

<service android:name=".GCMIntentService" />

编辑:

如果您的错误仍然存​​在,请尝试以下操作:

转到项目/属性/ Java构建路径/订单和导出 - 如果您使用它,请确保在Android Dependencies和支持库前面进行检查。标记所有复选框。单击“应用”并清除项目。

答案 1 :(得分:0)

GCM register()已被弃用,建议使用InstanceID执行常规GCM注册管理。

请尝试this

示例实施是here