获取当前活动 - Xamarin Android

40
我正在为 Android 和 iOS 开发一款可移植的应用程序。 我目前的功能是拍摄屏幕截图并在代码中使用该图像。 因此,我在可移植库中有一个接口。
public interface IFileSystemService
{
    string GetAppDataFolder();
}

我正在使用以下代码在便携式库中进行截屏:

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

这会调用 Android 或 iOS 版本。

Android:

这将调用 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;
    }

现在的问题是从我的应用中获取当前的Activity。


你需要在oncreate方法中将活动分配给服务。 - Krishna
5个回答

51

更好的方法是使用独立 Current Activity Plugin或者在Xamarin Essentials Plugin中使用当前活动属性。然后你可以这样做:

  • 独立: CrossCurrentActivity.Current.Activity
  • Xamarin Essentials: Platform.CurrentActivity

如果您不想使用插件且应用程序中只有1个Activity,则可以在MainActivity中分配一个静态变量,并在需要引用它的任何位置引用其内容,如下所示:

public class MainActivity : FormsApplicationActivity {
    public static Context Context;

    public MainActivity () {
        Context = this;
    }
}

如果你需要在自定义渲染器中使用Context,你应该使用传递给构造函数的Context,像这样:

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)
}

旧的过时方式是Context view = (Activity)Xamarin.Forms.Forms.Context

Xamarin会自动将Activity分配给Forms.Context


3
Xamarin Essentials现在已经内置了当前活动插件,请参见下面的答案。 - James Westgate

34

自从Xamarin 2.5发布以来,Xamarin.Forms.Forms.Context已经被弃用。现在可以通过以下方式获取Context:

var currentContext = Android.App.Application.Context;

21
var activity = (Activity)Forms.Context;

或者,如果您正在使用MainActivity

var activity = (MainActivity)Forms.Context;

1
是的!我在发布我的评论后阅读了你的评论,意识到我做得过头了。我已经点赞了,但它不会显示。 - Will Faulkner

19
如果您使用的是 Xamarin Essentials 1.5 或更高版本,则可以使用 Platform.CurrentActivity。这基本上相当于使用 CurrentActivity 插件。
请根据说明正确地初始化它,即在 MainActivity 的 OnCreate 中添加以下行。
Xamarin.Essentials.Platform.Init(this, savedInstanceState);

4
如果有人找不到 Platform.CurrentActivity 可能会感到困惑,请确保你已经安装了最新版本的 Xamarin.Essentials。如果你安装的是 1.3 版本,可能无法看到它,在更新到 1.5 版本后问题得以解决。 - Jayden Meyer

0

我正在尝试在Xamarin 5中做类似的事情,并且在我的Android和iOS版本中都有一些成功,使用

Shell.Current.CurrentPage 

所以当发生像截图或登录这样的事件时,该方法(无论是什么)可以触发一个静态事件,以便任何感兴趣的活动都可以查找自己是否为活动视图,如果是,则消耗由事件传输的数据(字节数组等)。

class FileChooserPage : ContentPage
{
    public FileChooserPage()
    {
        InitializeComponent();
        GoogleDriveService.Authenticated += GoogleDriveService_Authenticated;
    }

    private void GoogleDriveService_Authenticated(object sender, EventArgs e)
    {
        if (ReferenceEquals(this, Shell.Current.CurrentPage))
        {
            Populate(e);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接