如何在Android中发布消息时向用户发送通知

时间:2017-07-05 18:26:14

标签: android firebase firebase-realtime-database notifications android-notifications

我想在管理员发布消息后立即向用户发送通知。

我目前面临的目标:

  • 每次打开应用程序时,即使没有新消息,通知声音也会到达(是否因为代码是用onCreate()方法编写的?)
  • 当我点击通知时,我正确地重定向到MainActivity并再次发出通知声音。它有点讨厌:(

我在addChildEventListener中写了通知代码。任何人都可以指导我修复上述事情。请查看我的以下代码。

我的应用的MainActivity代码。

public class MainActivity extends AppCompatActivity {

    ...

    // [Start of onCreate Method]
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ...

        // NOTIFICATIONS
        mBuilder =
                (NotificationCompat.Builder) new NotificationCompat.Builder(MainActivity.this)
                        .setSmallIcon(R.drawable.bcm_logo)
                        .setContentTitle("BCM")
                        .setDefaults(Notification.DEFAULT_SOUND)
                        .setContentText("You have a new message")
                        .setAutoCancel(true); // clear notification when clicked

        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pi = PendingIntent.getActivity(this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
        mBuilder.setContentIntent(pi);

        messagesDatabaseReference.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                Log.d(TAG, "Child ADDED !");

                Log.d(TAG, "D: " + dataSnapshot);

                    mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                    mNotifyMgr.notify(mNotificationId, mBuilder.build());

            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {
                Log.d(TAG, "Child Changed");
            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
                Log.d(TAG, "CHILD REMOVED!");
            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {
                Log.d(TAG, "Child Moved");
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.d(TAG, "Child Cancelled");
            }
        });
    }    // [End of onCreate Method]


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RC_SIGN_IN) {
            if (resultCode == RESULT_OK) {

                Log.d(TAG, "User Signed in");

            } else if (resultCode == RESULT_CANCELED) {
                finish();
            }

        } 
    }

    ...

    // WHAT IF SIGNED IN
    private void onSignedInitialize(String userDisplayName) {
        mUserName = userDisplayName;
        Message.setSenderName(mUserName);
        attachDatabaseReadListener();
    }

    // ATTACH AND DETACH THE DATABASE READ LISTENERS
    private void attachDatabaseReadListener() {
        if (childEventListener == null) {
            childEventListener = new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    Message message = dataSnapshot.getValue(Message.class);
                    mMessageAdapter.add(message);
                }

                public void onChildChanged(DataSnapshot dataSnapshot, String s) {

                }

                public void onChildRemoved(DataSnapshot dataSnapshot) {
                }

                public void onChildMoved(DataSnapshot dataSnapshot, String s) {
                }

                public void onCancelled(DatabaseError databaseError) {
                }
            };
            messagesDatabaseReference.addChildEventListener(childEventListener);
        }
    }
    ...
} // [END of Main Activity]

1 个答案:

答案 0 :(得分:0)

这里的问题是,只要将监听器附加到DatabaseReference,就会使用数据库中的每个消息调用onChildAdded()。由于数据库中没有数据流的开始或结束,因此无法确定消息何时为“新”以及何时显示通知。有两种可能的解决方案:

1.使用ValueEventListener:

    databaseReference.addValueEventListener(new ValueEventListener() {

            Boolean showNotification = false;

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                if(showNotification) {
                    mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                    mNotifyMgr.notify(mNotificationId, mBuilder.build());
                }
                //use your Data here
                showNotification = true;  
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

这种方法的缺点是,每当有新消息时,您将获得完整的消息列表。

2.在数据结构中使用时间戳: 在消息中保存创建的时间戳。 然后你可以像这样扩展现有的ChildEventListener:

messagesDatabaseReference.addChildEventListener(
new ChildEventListener() {

    //set to the time when the listener is created
    private long attachTime = System.currentTimeMillis();

    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        Log.d(TAG, "Child ADDED !");
        Message message = dataSnapshot.getValue(Message.class);
        //if the message is newer then then the creation of the ChildEventListener -> show notification
        if(message.getCreationTime > attachTime) {
            mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            mNotifyMgr.notify(mNotificationId, mBuilder.build());
            attachTime = message.getCreationTime;
        }
        //use your Data here
    }

    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String s) {
        Log.d(TAG, "Child Changed");
    }

    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {
        Log.d(TAG, "CHILD REMOVED!");
    }

    @Override
    public void onChildMoved(DataSnapshot dataSnapshot, String s) {
        Log.d(TAG, "Child Moved");
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.d(TAG, "Child Cancelled");
    }
});

完整示例:

public class MainActivity extends AppCompatActivity {

    public static final String TAG = "MessagesActivity";
    private static final int mNotificationId = 1;
    private DatabaseReference messagesDatabaseReference;
    private ChildEventListener childEventListener;
    private NotificationCompat.Builder mBuilder;
    private NotificationManager mNotifyMgr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
                        .setSmallIcon(R.drawable.bcm_logo)
                        .setContentTitle("BCM")
                        .setDefaults(Notification.DEFAULT_SOUND)
                        .setContentText("You have a new message")
                        .setAutoCancel(true); // clear notification when clicked

        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(pi);
    }

    @Override
    public void onResume() {
        super.onResume();
        messagesDatabaseReference = FirebaseDatabase.getInstance().getReference();
        attachDatabaseReadListener();
    }

    @Override
    public void onPause() {
        super.onPause();
        detachDatabaseReadListener();
    }

    private void attachDatabaseReadListener() {
        if (childEventListener == null) {
            childEventListener = new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    Log.d(TAG, "Child ADDED !");
                    Message message = dataSnapshot.getValue(Message.class);
                    //if the message is newer then then the creation of the ChildEventListener -> show notification
                    if(message.getCreationTime > attachTime) {
                        mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                        mNotifyMgr.notify(mNotificationId, mBuilder.build());

                    }
                    mMessageAdapter.add(message);
                }

                public void onChildChanged(DataSnapshot dataSnapshot, String s) {

                }

                public void onChildRemoved(DataSnapshot dataSnapshot) {
                }

                public void onChildMoved(DataSnapshot dataSnapshot, String s) {
                }

                public void onCancelled(DatabaseError databaseError) {
                }
            };
            messagesDatabaseReference.addChildEventListener(childEventListener);
        }
    }

    private void detachDatabaseReadListener() {
        messagesDatabaseReference.removeEventListener(childEventListener);
    }
}
相关问题