Android update ListFragment's listView from another fragment - android

I have a question about updating my ListView in ListFragment from my Map fragment. Each time I will call this method I will assign different values to String Array. And what should I put into that Update method to refresh the listview ?

In ListFragment create and register BroadcastReceiver :
static final String ACTION_CUSTOM = "action";
BroadcastReceiver mReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReceiver = new BroadcastReceiver(){
public void onReceive(android.content.Context context, Intent intent) {
//Check for action you need
if (intent.getAction() == ACTION_CUSTOM ){
//Do stuff with data from intent
intent.getExtras().getString("data");
}
}
};
}
#Override
public void onResume() {
super.onResume();
getActivity().registerReceiver(receiver, new IntentFilter(ACTION_CUSTOM ));
}
#Override
protected void onPause() {
super.onPause();
getActivity().unregisterReceiver(receiver);
}
In MapFragment send broadcast intent, when you need to change data:
Intent intent = new Intent();
//Set action you need to send
intent.setAction(ACTION_CUSTOM);
//Add data to send
intent.putExtra("data", "data_value");
//Send broadcast intent
getActivity().sendBroadcast(intent);

Related

Android:How to send data Activity to Fragment using BroadcastReceiver

Send data from Activity to Fragment in Android using BroadcastReceiver. I know there is varies way to communicate Activity to Fragment.
But i don't know how to send data and receive using BroadcastReceiver.
From your Activity
Intent intent = new Intent("KEY");
sendBroadcast(intent);
In your fragment
private BroadcastReceiver mNotificationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUi();
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(mNotificationReceiver, new IntentFilter("KEY"));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mNotificationReceiver);
}

Activity cant find Bundle in Intent

I am using an IntentService (for the first time), and I intend to return the result of this service by using a Bundle. However, when I do this, the main activity does not find the Bundle, returning null. What could cause this? The string keys match!
The code bellow outputs:
I/System.out: It's null
Main Activity:
public class MainMenu extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
//Some stuff here...
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(StorageHandler.TRANSACTION_DONE);
registerReceiver(broadcastReceiver, intentFilter);
Intent i = new Intent(this, StorageHandler.class);
startService(i);
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extra = getIntent().getBundleExtra("bundle");
if(extra == null){
System.out.println("It's null");
}
else {
ArrayList<String> objects = (ArrayList<String>) extra.getSerializable("objects");
System.out.println(objects.get(0));
}
}
};
}
IntentService:
public class StorageHandler extends IntentService{
public static final String TRANSACTION_DONE = "xx.xxxxx.xxxxxx.TRANSACTION_DONE";
public StorageHandler() {
super("StorageHandler");
}
public void onCreate(){
super.onCreate();
}
#Override
protected void onHandleIntent(Intent intent) {
notifyFinished();
}
private void notifyFinished(){
ArrayList<String> objects = new ArrayList<String>();
objects.add("Resulting Array here");
Bundle extra = new Bundle();
extra.putSerializable("objects", objects);
Intent i = new Intent();
i.setAction(xx.xxxxx.xxxxxx.StorageHandler.TRANSACTION_DONE);
i.putExtra("bundle", extra);
StorageHandler.this.sendBroadcast(i);
}
You're attempting to retrieve the data from the wrong Intent.
Change:
Bundle extra = getIntent().getBundleExtra("bundle");
To:
Bundle extra = intent.getBundleExtra("bundle");
The Intent that contains your data is supplied as one of the parameters of the BroadcastReceiver's onReceive() method.
you are using getIntent() to retrieve the broadcasted intent. This is wrong. The intent you have to use is the former paramter of onReceive. Change
Bundle extra = getIntent().getBundleExtra("bundle");
with
Bundle extra = intent.getBundleExtra("bundle");
Simply use this in your Activity:
In onResume callback you should register registerReceiver(broadcastReceiver, intentFilter);
And in onPause callback you should unregister this receiver. In your receiver use this:
Bundle extra = intent.getBundleExtra("bundle");
In your service use this code:
Intent i = new Intent(TRANSACTION_DONE).putExtra("bundle", extra);
this.sendBroadcast(i);
More information , see This Answer
Dont forget this in your onCreate MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//All your code here
}
I say this because I dont see that code line in your method!

LocalBroadcastManager not working

I'm trying to sendMessage from service to activity, but for some reason it's not working.
Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barcode);
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("custom-event-name"));
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
Boolean state = intent.getBooleanExtra("state",false);
if(state){
Toast.makeText(getApplicationContext(),"Данные успешно отправлены",Toast.LENGTH_SHORT).show();
}
}
};
#Override
protected void onDestroy() {
// Unregister since the activity is about to be closed.
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
Service
private void sendMessage(boolean state) {
Log.d("sender", "Broadcasting message");
Intent intent = new Intent("custom-event-name");
// You can also include some extra data.
intent.putExtra("state", state);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
Log.d "broadcasting message" is shown and then nothing happens
PROBLEM SOLVED
In android manifest
<service
android:name=".service.TerminalService"
android:process=":update_service" >
</service>
It seems when android:process is specified localbroadcastmanager is not working. I just deleted android:process line and it worked
Nothing wrong with your code .only update your receive method else clause
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
Boolean state = intent.getBooleanExtra("state",false);
if(state){
Toast.makeText(getApplicationContext(),"Данные успешно отправлены",Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getApplicationContext(),"else message ",Toast.LENGTH_SHORT).show();
}
}
};
com.android.support:localbroadcastmanager -> change
androidx.localbroadcastmanager:localbroadcastmanager:1.0.0

How to refresh a ListView from a BroadcastReceiver?

If I call notifyDataSetChanged() on the custom adapter associated to my ListView, all the views should refresh themself (getView() will be called).
Now I have a BroadcastReceiver that is listening to an event. When the event fires, the ListView must be refreshed. How can I achieve this?
Thanks!
If you refresh listview from receiver you'll have code like this:
BroadcastReceiver br;
public final static String BROADCAST_ACTION = "BROADCAST_ACTION";
br = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//code refreshing...
}
};
IntentFilter intFilt = new IntentFilter(BROADCAST_ACTION);
registerReceiver(br, intFilt);
And you call it with code:
Intent intent = new Intent(BROADCAST_ACTION);
sendBroadcast(intent);
If you need the refresh to be another action you just need to add (after action):
Intent intent = new Intent(BROADCAST_ACTION);
sendBroadcast(intent);
As requested, please see the sample code below:
public interface OnDataUpdateListener {
void onDataAvailable(ArrayList<String> newDataList);
}
public class MyTestReceiver extends BroadcastReceiver {
public static final String DATA_LIST = "DATA_LIST";
private OnDataUpdateListener mDataUpdateListener = null;
public MyTestReceiver(OnDataUpdateListener dataUpdateListener) {
mDataUpdateListener = dataUpdateListener;
}
#Override
public void onReceive(Context ctx, Intent intent) {
// assuming data is available in the delivered intent
ArrayList<String> dataList = intent.getSerializableExtra(DATA_LIST);
if (null != mDataUpdateListener) {
mDataUpdateListener.onDataAvailable(dataList);
}
}
}
public class MyActivity extends FragmentActivity implements OnDataUpdateListener {
public static final String ACTION_DATA_UPDATE_READY = "ACTION_DATA_UPDATE_READY";
private MyTestReceiver mTestReceiver = null;
private <SomeAdapterClass> mAdapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// other required initialization
mTestReceiver = new MyTestReceiver(this);
}
#Override
public void onResume() {
super.onResume();
if (null != mTestReceiver) {
registerReceiver(mTestReceiver, new IntentFilter(ACTION_DATA_UPDATE_READY));
}
}
void onDataAvailable(ArrayList<String> newDataList) {
// assuming you want to replace existing data and not willing to append to existing dataset
mAdapter.clear();
mAdapter.addAll(newDataList);
mAdapter.notifyDataSetChanged();
}
}
In the code where your data is updated, fire off a message signalling that data has been changed...
(You will need access to either the Activity or the Application context to do this)
Intent intent = new Intent("ListViewDataUpdated");
LocalBroadcastManager.getInstance(context.sendBroadcast(intent));
Then just catch the catch the message using the following code in your activity, and tell your ListAdapter to update...
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
myListAdapter.notifyDataSetChanged();
}
};
#Override
public void onResume(){
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("ListViewDataUpdated"));
myListAdapter.notifyDataSetChanged();//in case our data was updated while this activity was paused
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}
Credit: adapted from Vogella
LocalBroadcastManager.getInstance(context.sendBroadcast(intent));
change to
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
I might be wrong but it works for me...

LocalBroadcastManager for multiple intents

I'm working in an app where I have just implemented the ViewPager. I was first working with tabs but when I made the change to ViewPager I started having an issue with the data transfer from Activity to fragments.
I finally found this post where this issue was explained and where recomends to use LocalBroadcastManager to send data from Activity to Frament when using ViewPager. I have implemented this code and works fine:
Fragment1.java
public class Fragment1 extends Fragment {
public static final String ACTION_INTENT = "fragment1.action.BOX_UPDATE";
/*Register the receiver*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter(ACTION_INTENT);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(ActivityDataReceiver, filter);
}
/*Broadcast Receiver*/
protected BroadcastReceiver ActivityDataReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(ACTION_INTENT.equals(intent.getAction())) {
String text = intent.getStringExtra("TEXT");
witeOnBox(text);
}
}
};
/*Method which changes the text with the icoming value*/
public void witeOnBox(String text) {
tv_log.setText(text);
}
/*Unregister receiver*/
#Override
public void onDestroy() {
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(ActivityDataReceiver);
super.onDestroy();
}
Now, in MainActivity I send the data to the fragment this way:
protected void sendValueToFragment1(String text) {
Intent intent = new Intent("fragment1.action.BOX_UPDATE");
intent.putExtra("TEXT", text);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
Now I need to send other data from MainActivity to the same Fragment1, and my question is, how do I manage in the fragment the incoming of another intent?
Do I have to create another BroadcastReceiver to manage a new Intent, or can I manage a new intent in the same BroadcastRecevier? I see that I can check using an if inside the onReceive() method of the BroadcastReceiver for the incoming intent filter, but If I declare two diferent intent filters in the same fragment, how do I asign them to the BroadcastReceiver?
I finally solved adding an Action to the previously defined IntentFilter:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter(ACTION_INTENT);
filter.addAction(ACTION_INTENT2);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(ActivityDataReceiver, filter);
}
Then in the BroadcastReceiver I manage the incoming actions:
protected BroadcastReceiver ActivityDataReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(ACTION_INTENT.equals(intent.getAction())) {
//Do
}
if(ACTION_INTENT2.equals(intent.getAction())) {
//DO
}
}
};
Much better ways than using broadcast receiver,
Fragment frag = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + mPager.getCurrentItem());
if(frag!=null && mPager.getCurrentItem()==1){
((Fragment1) frag).setText(text);
}
If you navigate to the Fragment after this has been called you can have it get the variables from the Activity using getActivity();

Categories

Resources