Access the Current Android Activity from Anywhere!
In the world of Android one of my biggest pain points over the years is that often you need access to the apps current Activity when writing libraries or abstracting out common functionality. For years I have been hacking around the issue by setting special Intent flags or more than likely creating a BaseActivity with a static “CurrentActivity” that is set when the page is started up. While this works short term for MY app, it completely falls down when you want to create Plugins or abstract an API into an interface of some sort.
When it comes down to it you just need that Activity, and it should be easy! This is why I have solve the issue once and for all with a secret hidden API that Google snuck in during the release of Ice Cream Sandwich (API 14) called ActivityLifecycleCallbacks. This is super undocumented, but from what Jérémie and I can gather Google introduced this so you can at any time figure out what the current activity. It must be implemented on your apps “Application” class and call RegisterActivityLifecycleCallbacks. After this though, you are all done.
So, let me introduce to you my latest Plugin for Xamarin.Android called “CurrentActivity”.
You guessed it, this plugin does 1 thing, lets you get access to the current activity. In fact the entire API is just 1 property:
/// The Current Activity
Activity Activity { get; set; }
The magic of this NuGet package and Plugin is that when you install it or if you are using it as a dependency in your own Plugin is that it lays down a “MainApplication.cs” file that ties into and implements the ActivityLifecycleCallbacks. BOOM! Done! Here is what that looks like:
using System;
using Android.App;
using Android.OS;
using Android.Runtime;
using Plugin.CurrentActivity;
namespace $rootnamespace$
{
//You can specify additional application information in this attribute
[Application]
public class MainApplication : Application, Application.IActivityLifecycleCallbacks
{
public MainApplication(IntPtr handle, JniHandleOwnership transer)
:base(handle, transer)
{
}
public override void OnCreate()
{
base.OnCreate();
RegisterActivityLifecycleCallbacks(this);
//A great place to initialize Xamarin.Insights and Dependency Services!
}
public override void OnTerminate()
{
base.OnTerminate();
UnregisterActivityLifecycleCallbacks(this);
}
public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
{
CrossCurrentActivity.Current.Activity = activity;
}
public void OnActivityDestroyed(Activity activity)
{
}
public void OnActivityPaused(Activity activity)
{
}
public void OnActivityResumed(Activity activity)
{
CrossCurrentActivity.Current.Activity = activity;
}
public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
{
}
public void OnActivityStarted(Activity activity)
{
CrossCurrentActivity.Current.Activity = activity;
}
public void OnActivityStopped(Activity activity)
{
}
}
}
Then if you want to access the current activity anywhere in your Android application, library, or plugin simply call: CrossCurrentActivity.Current.Activity and you will have the current activity.
If you already have sub-classed Application, don’t worry as you can just copy and paste some code that I put in a readme text file in the project, or head over to my GitHub and learn more!