2017-03-02 89 views
4

我已在我的应用程序中实施gcm推送通知。一切工作正常,我也收到通知。当应用程序关闭或应用程序在后台时获取两次GCM PUSH通知

问题:

  • 当应用程序是在背景或终止状态我在一个时间得到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

+0

您可以显示您的日志是什么错误?如果可能,请使用[FCM](https://firebase.google.com/docs/cloud-messaging/)而不是GCM。 –

+0

@JaydipUmaretiya其实它的工作很好的问题是,当我在前面的应用程序获得通知一次,但是当应用程序在后台或未打开我得到相同的通知两次先生 –

+0

嗨。你能否展示一个有效载荷?目前,我认为原因是你在'onMessageReceived()'中调用了两个'sendNotification()'。我不确定的是为什么它只发生在后台。 –

回答

0

onMessageReceived函数内部GCMPushReceiverService一旦你从GCM收到消息类被称为。

使用这种

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

+0

我i个留言 sendNotification(this,message,“Traccar App”); sendNotification(message); 但结果是一样的。 –

+0

看到我已经更新了答案。尝试点2,并告诉 – Ash

+0

其仍然是兄弟 –

0

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

相关问题