0

I have two activities Activity A and Activity B inside of the same application and they need to be able to call methods on each other. A needs to communicate to B at the start (possibly see "code" below).

B will call a lot of methods on A (this means that I cannot use the startActivityForResult method for communication because this would close B (Activity B is a Bluetooth Client and Server because it is a Peer to Peer app)). I do use startActivityForResult to start B for more of a kill signal than anything as the result.

Activity A uses a SupportMapFragment and Activity B cannot be a fragment because I want to be able to switch from B to A and then never use B again.

Originally, I started with one activity and tried switching between views using a ViewFlipper and just a call to setContentView(R.layout.my_layout_A) or setContentView(R.layout.my_layout_B). The fragment of course caused a lot of problems for both.

Using Fragments were confusing. The SupportMapFragment is the code for a Google Map which is a Fragment.

When I click a menu option inside of the MapsActivity (Activity A), I would like to be able to start myBluetoothActivity (Activity B) with a reference to the MapsActivity (Activity A) OR start myBluetoothActivity and then be able to set a reference to the caller inside of myBluetoothActivity (but this option would require having a reference to the BluetoothActivity inside of the MapsActivity or having some way to obtain the started activity from the intent).

//the following code is in Kotlin, but this can easily be converted over to java:
//option A: (pass it inside of the constructor)
var mbta:myBluetoothActivity = myBluetoothActivity(this)
//line for intent that I am unsure of
//intent so that I can start the activity with the pointer to the caller already passed into the new activity
startActivity(mbta)

//option B: (set this reference after obtaining a reference from intent):
var mintent:Intent = Intent(this.applicationContext, myBluetoothActivity::class.java)
startActivity(mintent)
//obtain the reference to the BluetoothActivity from the intent (NOT SURE HOW TO DO THIS???)
mbta.setCallerReference(this)

How can I accomplish this communication between the two activities via reference between the two activities? Should I use an interface for communication? If I should use it, (which I did try) how should I?

In other words, I am trying to access the caller activity (Activity A) from (Activity B) directly via a reference to Activity A inside of B OR trying to get the reference to B from the intent that started it inside of Activity A. I am trying to get a reference to that, so I can use it for communication/method calling/member variable and UI modification purposes.

NOTES: 1. The BluetoothActivity and the MapsActivity are NOT SERIALIZABLE. I tried serializing it and then adding it to the extras Bundle in the Intent and it just crashed saying that that was impossible to serialize due to BroadCastReciever. As this also deals with WIFI. Which I am highly considering separating out to be put with the BluetoothActivity in a future release.

  1. I am also ASSUMING that Activity B will never just be started up by anything other than my MapsActivity class.

  2. I am also new to Kotlin, but I know Java.

  3. When I tried using an interface, I caused a StackOverflow error and I have no idea why.

  4. I have read the documentation for Intents on the website.

  5. I have done some research on here which gave me those ideas above. I am not sure how to implement them.

  • Only one activity is visible at a time, but their instances remain in memory (at least for the first few minutes after one starts the other). First Activity A the MapsActivity is visible, then Activity B for Bluetooth is Visible when it hides A (assuming that it starts). Activity A is the main activity for the application. Activity B just serves as a helper. I want to be able to make changes to the main activity even when it resides in the background as well as when it is visible to the user and when it is interacting with the user. – user2675933 May 22 '18 at 07:11

1 Answers1

0

You are using the wrong approach. The solution requires a bit more work than you would think. The correct approach is to:

First, realize that these activities Activity A and Activity B (and any other activities) are activities that are specific to your application and you want to establish direct communication between them.

Second, realize that you are trying to get the current (or a previous) activity's context. The context will help serve the reference.

Third, you can create your own Activity and Application classes by extending the desired classes. The Application class is a low-level class used for the activities.

From here, you will be able to make use of the getApplicationContext() which will return your custom Application class.

Design: It is inside of your CustomApplication class that you must track the references to the activities that you want. From there all that you have to do is cast the getApplicationContext() to your CustomApplication class and then call your methods that access the Activity(ies). You must of course cast your Activities if you want to access certain instances of a specific activity that you created to its "type." For example:

MapsActivity mact = (MapsActivity)(((MyApplication)(this.getApplicationContext())).getCurrentActivity())

You must of course note that this activity must be already created (the onCreate method was already called) for this to return the current activity. The same of course goes for the other life-cycle methods for the activity as you will make a baseActivity which will deal with these as well as you will also have an Application life-cycle that will help deal with this too.

To answer the question: "How to get the current foreground activity context in android?" I turned to StackOverflow and found user: gezdy 's answer to be exactly what I needed at: How to get current foreground activity context in android?.

(BEGIN QUOTATION FROM: GEZDY)

You should manage activities references. Add the name of the application in the manifest file :

 <application
    android:name=".MyApp"
    ....
 </application>

Your application class :

public class MyApp extends Application {
     public void onCreate() {
          super.onCreate();
     }

     private Activity mCurrentActivity = null;
     public Activity getCurrentActivity(){
          return mCurrentActivity;
     }
     public void setCurrentActivity(Activity mCurrentActivity){
          this.mCurrentActivity = mCurrentActivity;
     }
}

Create a new Activity :

public class MyBaseActivity extends Activity {
    protected MyApp mMyApp;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mMyApp = (MyApp)this.getApplicationContext();
    }
    protected void onResume() {
        super.onResume();
        mMyApp.setCurrentActivity(this);
    }
    protected void onPause() {
        clearReferences();
        super.onPause();
    }
    protected void onDestroy() {        
        clearReferences();
        super.onDestroy();
    }
    private void clearReferences(){
        Activity currActivity = mMyApp.getCurrentActivity();
        if (this.equals(currActivity))
            mMyApp.setCurrentActivity(null);
    }
}

So, now instead of extending Activity class for your activities, just extend MyBaseActivity. Now, you can get your current activity from application or Activity context like that :

Activity currentActivity = ((MyApp)context.getApplicationContext()).getCurrentActivity();

(END OF QUOTATION FROM: GEZDY)

Note: All code is written in java for this answer.