so, what i'm trying to do is change some ui elements which are expanded in my main activity- and i want the changes to be triggered by the onReceive, which is from broadcastreceiver extended in a different separate class.
I'd like to do something like this
public class SmsReceiver extends BroadcastReceiver {
public void onReceive(context, intent){
MainActivity main = new MainActivity(); //this is my... main activity :)
main.button.setBackgroundColor(Color.green);
}//end onReceive
}//end class
in my MainActivity, i've set values to the GUI button element like this:
public class mainactivity extends activity... implements onclick... bla bla (){
Button button;
onCreate....{
button = (Button)findViewById(R.id.button);
so i'd like to know if when onReceive is activated, can i edit the state of a widget in ANOTHER activity by instantiating that activity and calling a setter method on it?
Your method will not work because you are creating a new instance of MainActivity. This will not reference your currently active main activity. One solution you may try is sending another intent to your activity and implementing onNewIntent(Intent newIntent) in your activity. That way you can update your main activity in that function, try passing extras in with the new information you have received.
Related
I have 4 Fragments and I am trying to click a button on FragmentA and call a method that changes the visibility of some views on FragmentB and populate it.
I tried an interface, but I can't seem to get it to work between 2 fragments. I can call the interface method from a fragment if I implement it in the activity, but I can't implement it in a fragment and call it in a fragment.
Is there a different way to do this? I don't think I can use the static keyword.
I am suggesting you can use broadcast receiver its, good to perform action anywhere and easy to use.
In your first fragment you can define receiver and from another fragment, you can send broadcast or action.
Example are following.
Write following code in your first fragment in which you want to update view,
private void registerReciver() {
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction().equals("UPDATE_FRAG_A")) {
// here you can fire your action which you want also get data from intent
}
}
};
IntentFilter intentFilter = new IntentFilter("UPDATE_FRAG_A");
getActivity().registerReceiver(broadcastReceiver, intentFilter);
}
And In your second fragment write following code for fire action,
Intent intent=new Intent();
// Here you can also put data on intent
intent.setAction("UPDATE_FRAG_A");
getActivity().sendBroadcast(intent);
Assume that all the fragments are in the same activity.
Define a interface in FragmentA, which is a Listener
Expose what you want to do in FragmentB via a public method
Implement FragmentA's interface in the parent activity by calling the public method of FragmentB
For more inforamtion,see Communicating with Other Fragments
Im trying to figure a way how to call an activity that an adapter has started. Is there a way to get the instance of the activity from startactivity and make a method call into the activity ?
I'ved got an adapter that has a list
public class LanguageDownloadRVAdapter extends RecyclerView.Adapter<LanguageDownloadRVAdapter.DownloadViewHolder>{
And in this adapter, it starts a particular activity called MainActivity
context.startActivity(new Intent(context, MainActivity.class));
((Activity)context).finish();
Here is the MainActivity that it starts
public class MainActivity extends AppCompatActivity implements IabBroadcastListener{
How can I make a call from the adapter to a method in the MainActivity. (im just trying to perform inapp purchase which is implemented in the MainActivity). so how can i do something like this.
mainactivity.perform_inapp_purchase();
Try to use EventBus for passing data between activity and list adapter. You can do it in the same way for passing data between activity and fragment.
This work the same way as storing data in global variable (in a fancier way)
In the adapter:
Add a new Field private Context mContext;
In the adapter Constructor add one more parameter as below, and assign it into class level variable:
public LanguageDownloadRVAdapter(......,Context context){
//your code.
this.mContext=context;
}
In the Adapter where you want to call Activity's perform_inapp_purchase() method:
if(mContext instanceof MainActivity){
((MainActivity) mContext).perform_inapp_purchase();
}
More Generalized Approach:
If you need to use this same adapter for more than one activity then :
Create an Interface
public interface InAppPerchaceInterface{
void perform_inapp_purchase();
}
Implement this interface in activities
Then in Adapter, call like below:
if(mContext instanceof InAppPerchaceInterface){
((InAppPerchaceInterface) mContext).perform_inapp_purchase();
}
You can store the instance in the application class, but you should be careful about the memory leaks.
In the onCreate of your activity
protected void onCreate(Bundle savedInstanceState)
{
// get the instance using this and store it in the application class or in the place that you want to call from it
}
From where will you call your method?
I didn't understand the situation.
I want to check some condtiton before the main activity starts and based on test result i have to either start a new activity or continue the same activity. How to do this?
you can check it in your OnCreate() method. It is called when your activity start.
onCreate(...){
....
if(want this){
//continue;
}else{
// start new activity
}
}
The default Activity to start is set in the manifest, so a better approach to your problem would be to use fragments. Keep in mind that fragments are faster/lighter, so instead of using Application as a "decision" class to start activities (bad practice), use your main activity. In your onCreate() method, check for your condition and attach the needed fragment.
I am using java annotation to handle this case:
Create the Annoation class
Create CustomContext.java with a startActivity method in it
Create the Interceptor.java
Create a class which implement Interceptor like this (named DemoInterceptor.java here)
Declare a static variable of DemoInterceptor in your activity. and the demo Activity should like this then, start the activity via the custom startActivity in step #2
enjoy and let me know if you have any further question.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(startNewActivity) {
// TODO Fire off intent to start new activity
finish(); // Closes the current activity
return;
}
// TODO Code for current activity.
}
startNewActivity is a boolean indicating whether to launch a new activity or not. It should be assigned a value depending on your condition.
There are multiple ways to register callbacks when a Button is clicked. If I go by the following way:
public class MainActivity extends Activity implements OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(this, "Hello onCLick", Toast.LENGTH_SHORT).show();
}
}
I don't understand how the method setOnClickListener(this) identifies that it should call onClick() method?
This refers to the activity. Because the Activity implements an OnClickListener calling button.setOnClickListener(this) gives the onClickListener that the Activity implements to setOnClickListener.
I recommend you look up info about implementing interfaces in Java if you want tot know more about this practise.
if you are aware about oops 'this' refer the reference of current object of class. a good explanation is define here
In above case MainActivity reference is refer as this here.
public void setOnClickListener(OnClickListener l)
is setter method define in class Button which hold the reference on "OnClickListener".
when you set setOnClickListener(this) it define you are passing OnClickListener reference as your activity so to make your activity as type on OnClickListener you have to implement the interface OnClickListener in your activity class as it is showing in your code.
public class MainActivity extends Activity implements OnClickListener
Its a callback listener which have method "onClick" you have to override that method
and when button is clicked that method is call by Button class so the event listener (which is you activity in current scenario) can listen to it.
I think I understand your confusion. When you read other SO answers or references like the View.OnClickListener, it feels like all the sentences are telling the same thing but nothing that really helps click.
What happens is, when a Button is clicked, it will notify all the objects that are listenning for it. You are subscribing your activity as a listener, to this event with the line
button.setOnClickListener(this);
So, on an event of a click, button knows that it should call the activity's onClick event.
I don't understand how the method setOnClickListener(this) identifies
that it should call onClick() method?
(Therefore, it s the button that calls the listener.onClick() method, in case there's a confusion there.)
Also, #nourikhalass has a point, you should first make sure that interfaces make sense to you.
Is it any clearer?
Your code has
MainActivity implements OnClickListener
but actually it is:
MainActivity implements View.OnClickListener
Maybe that is what confuses you.
"This" refers to current object.
To handle button clicks, an object must implement the "OnClickListener" interface and define what to do when clicks are received in "onClick" method. Then you can register that object as a listener for your button clicks.
In your case, your activity implements OnClickListener, and onClick shows a toast:
public class MainActivity extends Activity implements OnClickListener {
...
#Override
public void onClick(View v) {
Toast.makeText(this, "Hello onCLick", Toast.LENGTH_SHORT).show();
}
Therefore, your activity can handle button clicks, so you register it as a listener for your button:
button.setOnClickListener(this);
As "this" implements the required interface, is a valid listener.
There are 2 Fragments
I'm calling a service from Fragment 1. I have a ResultReceiver in Fragment 1 which listens to the result and onReceiveResult will call method1().
I want a ResultReceiver in Fragment 2 to listen to the same response but onReceiveResult will be calling method2()
How can I achieve this?
You could specify an interface:
interface Receiver {
void onResult();
}
Have your two Fragments implement this interface. Fragment1's implementation simply calls method1(), and Fragment2's implementation simply calls method2():
public class Fragment1 extends Fragment implements Receiver {
// Remember to register and remove the receiver (e.g. in onAttach and onDetach respectively).
private MyReceiver mBroadcast = new MyReceiver(this);
public void onResult() {
this.method1();
}
}
public class Fragment2 extends Fragment implements Receiver {
// Remember to register and remove the receiver (e.g. in onAttach and onDetach respectively).
private MyReceiver mBroadcast = new MyReceiver(this);
public void onResult() {
this.method2();
}
}
Then specify the BroadcastReceiver as a standalone (or inner static) class such that both Fragment1 and Fragment2 will be able to instantiate it:
public class MyReceiver extends BroadcastReceiver {
private Receiver mFragment;
public MyReceiver(Receiver fragment) {
mFragment = fragment;
}
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(YOUR_ACTION) {
mFragment.onResult();
}
}
}
I don't think that you can receive results in two different fragments simultaneously.
But there are many ways to achieve this..
1.
I believe the easiest way will be to use object reference..
There are two possibilities.. Either create a static method in Fragment 2 and call it from fragment 1 from onReceiveResult(). Or Create an object of Fragment 2 in fragment 1 and from fragment 2 , assign that it is the same as the instance created by fragment1. Then just call
object_of_frgament2.method2() from the onReceiveResult() of fragment 1.
2.
Using interface.Create a custom interface and make the Fragment 2 implement the interface and create an instance of the interface in Fragment 1.
and within onReceiveResult() of Fragment1 you can call the interface method.
While implementing the interface, you can get the result in fragment 2 in the interface method.
Just call method2() from the function....
3.Using Broadcast Receiver..
Create a custom broadcast receiver and make all the fragments/activities which need the results to listen to it. and within onReceiveResult() of Fragment1 just broadcast the result..
I believe there are still other ways to do it..
just pass into your service two different ResultReceiver's ... If the service is already started calling startService(Intent) again just makes you call onStartCommand(...) and then you can set your resultReciever each time. So you can keep an array of resultreciever's if you want.
saying that, i would never do it this way. Research Java Observer pattern. Java has a default implementation of the Observer pattern. Here is a link