应用程序关闭或应用程序处于后台时,获取两次GCM PUSH通知

时间:2017-03-02 10:24:59

标签: android push-notification google-cloud-messaging

我已在我的应用程序中实现了gcm推送通知。一切都很好,我也收到通知。

问题:

  • 当应用处于后台或终止状态时,我一次收到2个通知。
  • 当应用程序在前台时,只能获得我想要的1个通知。
  

应用程序应该只获得1个通知作为要求,但不幸的是面临未定义的情况。

我的代码如下:

GCMPushReceiverService用于接收消息的课程。

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
    Log.e("MeSs",""+message);
    sendNotification(this,message, "Traccar App");
    sendNotification(message);

}

//This method is generating a notification and displaying the notification  //When in front
private void sendNotification(Context context, String notificationText,
                              String notificationTitle) {

    PowerManager pm = (PowerManager) context
            .getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wakeLock = pm.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK, "");
    wakeLock.acquire();

    Intent intent = new Intent(this, Home.class);
    intent.putExtra("ChatFragment", "newChatFound");
    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 notificationBuilder = new NotificationCompat.Builder(
            context)
            .setSmallIcon(R.drawable.bug_log_two)
            .setColor(Color.RED)
            .setContentTitle(notificationTitle)
            .setContentText(notificationText)
            .setDefaults(Notification.DEFAULT_ALL)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent);


    NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

    notificationManager.notify(0, notificationBuilder.build()); //0 = ID of notification

    wakeLock.release();
}

private void sendNotification(String message) {
    Intent intent = new Intent(this, Home.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
}

}

manifest文件代码:

 <!-- GCM -->

    <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="com.vk.trackeruser" />
        </intent-filter>
    </receiver>

    <!-- GCM Receiver Service -->
    <service
        android:name=".Notification.GCMPushReceiverService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>

    <!-- GCM Registration Intent Service -->
    <service
        android:name=".Notification.GCMRegistrationIntentService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.gms.iid.InstanceID" />
        </intent-filter>
    </service>

GCMRegistrationIntentService上课:

public class GCMRegistrationIntentService extends IntentService {
//Constants for success and errors
public static final String REGISTRATION_SUCCESS = "RegistrationSuccess";
public static final String REGISTRATION_ERROR = "RegistrationError";
public static final String SenderId = "my id with numeric number ex 9897979";
//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(SenderId, 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);
      String  tokan = 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上课:

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

获取GCM令牌的类:

   in oncreate {
    //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");
                StaticContents.Gcm_token=token;
                Log.e("Token",""+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();

LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);

}
  

输出1:当应用程序处于可见(前景)时,仅收到一个通知。

enter image description here

  

输出2:当应用关闭或应用在后台获取2个通知时。

enter image description here

2 个答案:

答案 0 :(得分:0)

从GCM收到消息后,会调用 GCMPushReceiverService 类中的 1。 onMessageReceived 函数。

使用此

String message = data.getString("message");

您正在将消息解析并存储在名为消息的变量中。

问题在于您将消息传递给两个功能

sendNotification(this,message, "Traccar App");
sendNotification(message);

这两个函数正在构建通知,并将您传递给这两个函数的消息显示为2个单独的通知。

只需注释掉这两个功能中的任何一个并进行检查。

2。为了避免重复通知,我们可以采用一种方法来处理它。 尝试更改此内容 -

PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);

PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT);

如果问题仍然存在,请发布您获得的有效负载。我建议使用FCM而不是GCM

答案 1 :(得分:0)

您可以使用FCM下游而不是上游