I have a BroadcastReceiver which receives broadcast sent to a Fragment.
I'm getting the broadcast but how can I call a method from the Fragment itself?
I basically need to update a List once the broadcast arrives, the List & update method are part of the Fragment.
public class FragmentReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action != null && action.equals("AllTasksFragmentUpdate"))
{
//
}
}
}
Registering the receiver:
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getActivity().registerReceiver(new FragmentReceiver(), new IntentFilter("AllTasksFragmentUpdate"));
}
How can I call the method from the Fragment?
You can implement your broadcast reciever in the following way:
import android.app.Fragment;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.adobe.libs.connectors.R;
public class YourFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
//Start listening for refresh local file list LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mYourBroadcastReceiver,
new IntentFilter(<YOUR INTENT FILTER>));
return inflater.inflate(R.layout.your_fragment_layout, null, true);
}
#Override
public void onDestroyView() {
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mYourBroadcastReceiver);
}
private final BroadcastReceiver mYourBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Now you can call all your fragments method here
}
};
}
In your onReceive() method, you can find your fragment by its tag name (the name using which you instantiated your fragment) and call its public method.
SampleFragment fragment = (SampleFragment) getSupportFragmentManager().findFragmentByTag(<fragment_tag_name>);
if (fragment != null && fragment.isAdded()) {
fragment.method(); //Call any public method
}
Hope this helps !
Supposing that you have an Activity named MyActivity and at some point in your code, you want to make a broadcast to be received by a Fragment named MyFragment. You can do it like this:
In MyActivity, use LocalBroadcastManager to make the broadcast with a filter:
String filter = "thisIsForMyFragment";
Intent intent = new Intent(filter); //If you need extra, add: intent.putExtra("extra","something");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
In MyFragment, inside onCreateView() add this to register the receiver:
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(myBroadcastReceiver,
new IntentFilter("thisIsForMyFragment"));
Following, In MyFragment (outside onCreateView()) create the receiver method to receive the broadcast:
private final BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, android.content.Intent intent) {
Toast.makeText(getActivity(), "Broadcast received!", Toast.LENGTH_SHORT).show();//Do what you want when the broadcast is received...
}
};
Finally, in MyFragment add this to unregister the receiver onDestroyView:
#Override
public void onDestroyView()
{
super.onDestroyView();
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(myBroadcastReceiver);
}
activity!!.registerReceiver(receiver, IntentFilter(DataKeys.STATUS))
Related
i am trying to initiate a service from a tab, i have created the buttons in onCreateView method but i startService method doesn't seem to appear anywhere
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final Button startServiceButton = (Button) view.findViewById(R.id.strtserviceBtn);
startServiceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(),MyService.class);
startService(intent);
}
});
return view;
}
The startService just tries to create another method of this name.
My Service class is as follows:.
package com.example.a786computer1.mytryfyp;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;
public class MyService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"Service started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
And i have created the service in my manifest as well, Pls help me regarding this!!
In Fragment you need to call getActivity().startService();.
So replace,
Intent intent = new Intent(getActivity(),MyService.class);
startService(intent);
with
Intent intent = new Intent(getActivity(),MyService.class);
getActivity().startService(intent);
I have a class which doesn't extend Activity or Fragment. It is a independent class. I would like to use that class to control an Activity start and finish.
public class MyActivityManager() {
public MyActivityManager(Context context) {
mContext = context;
}
public void startMainActivity() {
Intent intent = new Intent(mContext, MainActivity.class);
mContext.startActivity(intent);
}
public void closeMainActivity() {
// how can I close the started main activity from the other function here?
}
}
As you can see, I started MainActivity from one function, and in another function, I would like to close the MainActivity started. But how can I have a reference to the started MainActivity?
(My main purpose is to let upper caller to use this MyActivityManager to start and close MainActivity)
If the current way is not possible, how to achieve what I want?
//Try the below code and let me know if any issues.
package com.example.raghavendrapai.myapplication;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(mCloseReceiver, new IntentFilter("close_main_activity"));
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mCloseReceiver);
}
private BroadcastReceiver mCloseReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("close_main_activity")) {
finish();
}
}
};
}
// And in your class
package com.example.raghavendrapai.myapplication;
import android.content.Context;
import android.content.Intent;
/**
* Created by raghavendra.pai on 08/03/18.
*/
public class MyActivityManager {
private Context mContext;
public MyActivityManager(Context context) {
mContext = context;
}
public void startMainActivity() {
Intent intent = new Intent(mContext, MainActivity.class);
mContext.startActivity(intent);
}
public void closeMainActivity() {
Intent intent = new Intent("close_main_activity");
mContext.sendBroadcast(intent);
}
}
I have a broadcast receiver in my app which is fired every time the user gets an incoming call. Now, when it happens, I need the broadcast receiver to invoke a specific method in a specific activity. Now, I tried to make this method static and therefore available, but something tells me it is a very bad idea.
Accordingly, I tried to instantiate the broadcast receiver inside my activity without declaring it in my manifest but the problem is - when the app is off, the activity dosn't exist and therefore I can't invoke my method.
So my question is - How can I invoke this method when the broadcast receiver is fired up, without making it "public static"?
Here is my activity code(I have deleted the irrelevant parts)
package com.silverfix.ringo.activities;
import com.silverfix.ringo.R;
import com.silverfix.ringo.activities.fragments.DataManagerFragment;
import android.app.ActionBar;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
public class RingtonesActivity extends Activity{
private DataManagerFragment dataManagerFragment;
private IntentFilter filter;
private BroadcastReceiver phoneCall;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ringtones);
ActionBar ab = getActionBar();
ab.setDisplayShowTitleEnabled(false);
ab.setDisplayHomeAsUpEnabled(true);
dataManagerFragment = new DataManagerFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(dataManagerFragment, "DataManagerFragment");
ft.commit();
filter = new IntentFilter();
filter.addAction("android.intent.action.PHONE_STATE");
phoneCall = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
dataManagerFragment.act();
}
};
registerReceiver(phoneCall, filter);
}
}
You can use observers , like
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
ObservableObject.getInstance().updateValue(intent);
}
}
public class MainActivity extends Activity implements Observer {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ObservableObject.getInstance().addObserver(this);
}
#Override
public void update(Observable observable, Object data) {
Toast.makeText(this, String.valueOf("activity observer " + data), Toast.LENGTH_SHORT).show();
}
}
public class ObservableObject extends Observable {
private static ObservableObject instance = new ObservableObject();
public static ObservableObject getInstance() {
return instance;
}
private ObservableObject() {
}
public void updateValue(Object data) {
synchronized (this) {
setChanged();
notifyObservers(data);
}
}
}
Receiver can be used via manifest.
ObservableObject - must be singleton.
This might help: how can I notify a running activity from a broadcast receiver?
Also, you can try using Observers
Something like:
public class BroadcastObserver extends Observable {
private void triggerObservers() {
setChanged();
notifyObservers();
}
public void change() {
triggerObservers();
}
}
In your broadcast receiver:
#Override
public void onReceive(Context context, Intent intent) {
BroadcastObserver bco = new BroadcastObserver();
bco.change();
}
and the Activity:
public class YourActivity extends Activity implements
Observer {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BroadcastObserver bco = new BroadcastObserver();
bco.addObserver(this);
}
#Override
public void update() {
//TODO: call your desired function
}
}
If anyone needs two-way communication between a BroadcastReceiver and a Activity, I wrote this utility class which simplifies invoking Methods on each other while still being memory-safe.
https://gist.github.com/Jenjen1324/4a0c03beff827082cb641fc8fe2c4e71
I have fragmentActivity class which implements OnTabChangeListener and acts as a host for other fragment classes. Every fragment classes is defined in different XML layout files for their own Layout.
I want to get the View from that fragment class inside the fragmentActivity class.
I have tried :
View view = myFragment.getView();
Button myButton = (Button) view.findViewById(R.id.my_button);
myButton.setOnClickListener(new MyClickListener());
But doesn't seem to work.
So does anyone know?
If you want you can use the BroadcastReciver to send event notification to your activity from your fragment.
To register a broadcast reciver in your FragmentActivity do something like this :
public class MyActivity extends FragmentActivity {
private BroadcastReceiver myBroadcastReceiver =
new BroadcastReceiver() {
#Override
public void onReceive(...) {
//YOU WILL RECEIVE YOUR BROADCAST HERE. WRITE YOUR CODE HERE TO ADD NEW TAB
}
});
...
public void onResume() {
super.onResume();
....
registerReceiver(myBroadcastReceiver, intentFilter);
}
public void onPause() {
super.onPause();
...
unregisterReceiver(myBroadcastReceiver);
}
...
}
Now to send Broadcast from your fragment do like this :
Intent intent=new Intent();
intent.setAction("ANY_UNIQUE_NAME");
intent.putExtra("data",EXTRA_DATA_IF_YOU_WANT);
sendBroadcast(intent);
You will receive this broadcast on your activity's on Receive Event. Do whatever you want to do there.
If you want to acces your component and set some data, I suggest you to make a method inside the fragment like this:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
public class DetailFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.details, container, false);
return view;
}
public void setSettings(){
Button button = (Button) getView().findViewById(R.id.my_button);
button.setOnClickListener(new MyClickListener());
}
}
Anyone know if I can receive my main Activity's onStop, onPause and onResume callbacks inside another class / object?
I've got a broadcast receiver that lives inside another class (a WebView). I use the receiver to detect when the network goes down and switch to a local copy of my page with some useful content. I need to un-register the broadcast receiver when onStop/onPause are called and re-register it during onResume.
I can do this by hand (I added a couple public methods to a class that extends WebView to do just that) , but it'd be nice to have Android just call it for me.
edit: Sure, here's the class, I'd like it to be able to receive get a callback from Android when my main activity's onStop gets called without having to call startInternetMonitoring() / stopInternetMonitoring():
package com.glimmersoft.spent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.util.AttributeSet;
import android.util.Log;
import android.webkit.WebSettings;
import android.webkit.WebView;
/**
* #author Jer
*
*/
public class OfflineWebView extends WebView {
private BroadcastReceiver receiver;
private IntentFilter filter;
private Context myContext;
public OfflineWebView(Context context,AttributeSet attrs) {
super(context, attrs);
WebSettings webSettings = this.getSettings();
webSettings.setJavaScriptEnabled(true);
myContext = context;
}//END CLASS CONSTRUCTTOR
/**
* #param internetOn The URL to display in this OfflineWebView when there is an active Internet connection.
* #param internetOff The URL to display in this OfflineWebView if there is no active Internet connection.
*/
public void setPages(final String internetOn, final String internetOff){
final OfflineWebView finalThisRef = this;
filter = new IntentFilter();
filter.addAction(SpendConstants.ANDROID_CONNECTIVITY_CHANGED);
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm=(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if(cm.getActiveNetworkInfo()!=null&&cm.getActiveNetworkInfo().isConnected()){// TODO: THIS FAILES IF
finalThisRef.loadUrl(internetOn);
}else{
finalThisRef.loadUrl(internetOff);
}
}//END IF/ELSE
};
myContext.registerReceiver(receiver, filter);
}//END FUNCTION SETPAGES
public void startInternetMonitoring(){
myContext.registerReceiver(receiver, filter);
}//END METHOD STARTINTERNETMONITORING
public void stopInternetMonitoring(){
myContext.unregisterReceiver(receiver);
}//END METHOD STOPINTERNETMONITORING
}//END CLASS OfflineWebView
Thanks all!
Instead of putting your BroadcastReceiver inside your OfflineWebView, make it a static class you register maybe in a base Activity and have it a hold a reference to your OfflineWebView. When onReceive is called, you can then reference your OfflineWebView to load your online/offline content.
file: MyBaseActivity.java
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.webkit.WebView;
public class MyBaseActivity extends Activity {
private static final String ANDROID_CONNECTIVITY_CHANGED = "android.net.conn.CONNECTIVITY_CHANGE";
protected static final ConnectivityBroadcastReceiver sReceiver = new ConnectivityBroadcastReceiver();
private static final IntentFilter sFilter = new IntentFilter(ANDROID_CONNECTIVITY_CHANGED);
static class ConnectivityBroadcastReceiver extends BroadcastReceiver {
private String internetOnUrl = "your online url";
private String internetOffUrl = "your offline url";
WebView offlineWebView;
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
// only do your online/offline loading if we have a webview set
if (offlineWebView != null) {
if (cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isConnected()) {
offlineWebView.loadUrl(internetOnUrl);
} else {
offlineWebView.loadUrl(internetOffUrl);
}
}
}
}
#Override
public void onStart() {
super.onStart();
// register receiver
registerReceiver(sReceiver, sFilter);
}
#Override
public void onStop() {
super.onStop();
// unregister receiver
unregisterReceiver(sReceiver);
}
}
file: MyActivity.java
import android.R;
import android.os.Bundle;
import android.webkit.WebView;
public class MyActivity extends MyBaseActivity {
private WebView mWebView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// load your content root
setContentView(R.layout.main_layout);
// find your webview
mWebView = (WebView)findViewById(R.id.webView);
}
#Override
public void onStart() {
super.onStart();
// set your webview in the OfflineBroadcastReceiver
sReceiver.offlineWebView = mWebView;
}
#Override
public void onStop() {
super.onStop();
// clear your webview from the OfflineBroadcastReceiver
sReceiver.offlineWebView = null;
}
}