2017-03-02 44 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而不是上游

相關問題