Add list item in RecyclerView Adapter on receiving

2019-06-01 03:39发布

问题:

I'm using the firebase messaging service for messaging and notifications. I can't seem to be able to pass an incoming message from the service to the adapter so that when the message is received it can be inserted into the RecycleView List.

I tried using BroacastIntent as follows :

public class messaging extends FirebaseMessagingService {

   @Override
   public void onMessageReceived(RemoteMessage m) {
      store(m.getData());
      broadcastIntent();
   }

   public void broadcastIntent() {
      Intent intent = new Intent();
      intent.setAction("com.myApp.CUSTOM_EVENT");
      sendBroadcast(intent);
   }
}

and in the Adpter

public class ConvoAdapter extends RecyclerView.Adapter<ConvoHolder> {

   private List<Message> list;
   private Activity      A;

   public ConvoAdapter(List<Message> data) {

   }

   @Override
   public ConvoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
      return new ConvoHolder(v);
   }

   @Override
   public void onBindViewHolder(ConvoHolder h, int Position) {
      final Message M = list.get(Position);
      h.config(A, M);
   }

    @Override
    public int getItemCount() {
       return list.size();
    }

    public class MyReceiver extends BroadcastReceiver {
          @Override
          public void onReceive(Context context, Intent intent) {
             Toast.makeText(context, "Intent Detected.",    Toast.LENGTH_LONG).show();
          }
    }
}

And manifest.

<receiver android:name=".fragments.chats.ConvoAdapter$MyReceiver"
                  android:enabled="true"
                  android:exported="false" >
            <intent-filter>
                <action android:name="android.intent.action.CUSTOM_EVENT">
                </action>
            </intent-filter>
        </receiver>

As is, the broadcast receiver is not receiving any messages.

I'd also use any other method that doesn't involve using broadcast receivers.

回答1:

The flow or architecture of your is not a standard practice.

The standard flow should be

  1. Firebase service
  2. Some activity or fragment with BroadcastReceiver using LocalBroadcastManager

1. Firebase Service

public class messaging extends FirebaseMessagingService {

   @Override
   public void onMessageReceived(RemoteMessage m) {
      store(m.getData());
      broadcastIntent();
   }

  public void broadcastIntent() {
      Intent intent = new Intent();
      intent.setAction("com.myApp.CUSTOM_EVENT");
      // We should use LocalBroadcastManager when we want INTRA app
      // communication
      LocalBroadcastManager.getInstance(YOUR_CONTEXT).sendBroadcast(intent);
  }
}

2. Activity

  1. Registering Receiver for broadcast from Service

     public void onCreate(Bundle savedInstance) {
           // REST OF YOUR CODE
           IntentFilter if= new IntentFilter("com.myApp.CUSTOM_EVENT");
           LocalBroadcastManager.getInstance(this).registerReceiver(onMessage, if);
      }
    
  2. Writing the Receiver in Activity

    private BroadcastReceiver onNotice= new BroadcastReceiver() {        
          @Override
          public void onReceive(Context context, Intent intent) {        
                 // Update your RecyclerView here using notifyItemInserted(position);
          }
    

    };

Summary: The Service sends local broadcast to Activity which in turn receives it and updates or add items using RecyclerView instance



回答2:

if in case you don't want to use BroadCaseReceiver for your task.Follow below steps:

There are two things to note here.

Firstly,Check whether the Activity is open(Activel visible) or not.

i. When your screen is active.(screen is visible).

1.In your onMessageReceived() store the received message in SQLiteDataBase with time. 2.create a method in your adapter which will update the screen by fetching the data from SQLiteDB. 3.Now whenever a new message is received call this method in Adapter class.

ii.in case the screen is not active:

1.store the received message in sqliteDb and show it as a notification.

note:

1.make sure you write all these in a try catch block. 2.make sure to sync your SQLiteDB on opening the screen for the first time. 3.in case if this does not help you please try this way.. Refreshing activity on receiving gcm push notification



回答3:

I think the above code didnt worked because the action name above given and the one registered in manifest is different

<action android:name="com.myApp.CUSTOM_EVENT">
                </action>

intent.setAction("com.myApp.CUSTOM_EVENT");

give same name i think the above code will work