c# – Get current Activity – Xamarin Android-ThrowExceptions

Exception or error:

I am developing an portable App for Android and iOS. My current function is taking a Screenshot and use that image in the code. Therefor I have an Interface in the portable library.

public interface IFileSystemService
{
    string GetAppDataFolder();
}

I am taking the Screenshot also in the portable Library with the following code:

static public bool TakeScreenshot()
    {
        try
        {
            byte[] ScreenshotBytes = DependencyService.Get<Interface.IScreenshotManager>().TakeScreenshot();
            return true;
        }
        catch (Exception ex)
        {
        }
        return false;
    }

This either calls the Android or the iOS version.

Android:

class ScreenshotManagerAndroid : IScreenshotManager
{
    public static Activity Activity { get; set; }

    public byte[] TakeScreenshot()
    {

        if (Activity == null)
        {
            throw new Exception("You have to set ScreenshotManager.Activity in your Android project");
        }

        var view = Activity.Window.DecorView;
        view.DrawingCacheEnabled = true;

        Bitmap bitmap = view.GetDrawingCache(true);

        byte[] bitmapData;

        using (var stream = new MemoryStream())
        {
            bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
            bitmapData = stream.ToArray();
        }

        return bitmapData;
    }

The question now is to get the current Activity from my app.

How to solve:

Since the release of Xamarin 2.5, Xamarin.Forms.Forms.Context is obsolete. The Context can now be obtained as follows:

var currentContext = Android.App.Application.Context;

###

A better way would be to use the Standalone Current Activity Plugin or the Current Activity Property in the Xamarin Essentials Plugin. Then you could just do:

  • Standalone: CrossCurrentActivity.Current.Activity
  • Xamarin Essentials: Platform.CurrentActivity

If you do not want to use a plugin and you only have 1 Activity in your app, you could get away with assigning a static variable in MainActivity and referencing that where ever you needed it like this:

public class MainActivity : FormsApplicationActivity {
    public static Context Context;

    public MainActivity () {
        Context = this;
    }
}

If you needed Context within a custom renderer, you would want to use the Context passed into the constructor, like this:

public class MyEntryRenderer : EntryRenderer {

    private readonly Context _context;

    public MyEntryRenderer(Context context) : base(context) {
        _context = context;
    }

    // Now use _context or ((Activity)_context) any where you need to (just make sure you pass it into the base constructor)
}

The old deprecated way would be Context view = (Activity)Xamarin.Forms.Forms.Context

Xamarin automatically assigns the Activity to Forms.Context.

###

var activity = (Activity)Forms.Context;

or if you are using MainActivity

var activity = (MainActivity)Forms.Context;

###

If you are using Xamarin Essentials 1.5, then you can use Platform.CurrentActivity. This is basically the equivalent of using the CurrentActivity plugin.

Ensure you initialise this correctly as per the instructions ie. in MainActivity OnCreate add the following line

Xamarin.Essentials.Platform.Init(this, savedInstanceState);

Leave a Reply

Your email address will not be published. Required fields are marked *