You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android平台.NET MAUI应用截图检测及相关功能实现求助

.NET MAUI Android 截图检测实现方案

核心思路

Android平台下,截图文件通常会被系统媒体扫描器收录到MediaStore中,且大多存储在Screenshots目录、文件名包含「Screenshot」或「截图」关键词。我们可以通过监听MediaStore内容变化的方式检测截图,再通过MAUI的主线程更新UI。

实现步骤

1. 编写Android平台特定的截图检测器

在MAUI项目的Platforms/Android目录下创建ScreenshotDetector类,继承自Android的ContentObserver,用于监听媒体库图片变化并判断是否为截图:

using Android.Content;
using Android.Database;
using Android.Provider;
using System;

namespace YourAppNamespace.Platforms.Android
{
    public class ScreenshotDetector : ContentObserver
    {
        private readonly Context _androidContext;
        private readonly Action<string> _screenshotCallback;

        public ScreenshotDetector(Context context, Action<string> onScreenshotDetected) : base(null)
        {
            _androidContext = context;
            _screenshotCallback = onScreenshotDetected;
        }

        // 启动监听
        public void StartListening()
        {
            _androidContext.ContentResolver.RegisterContentObserver(
                MediaStore.Images.Media.ExternalContentUri, 
                true, 
                this);
        }

        // 停止监听(避免内存泄漏)
        public void StopListening()
        {
            _androidContext.ContentResolver.UnregisterContentObserver(this);
        }

        // 媒体库内容变化时触发
        public override void OnChange(bool selfChange)
        {
            base.OnChange(selfChange);
            CheckLatestImage();
        }

        // 查询最新添加的图片并判断是否为截图
        private void CheckLatestImage()
        {
            string[] queryColumns = {
                MediaStore.Images.Media.InterfaceConsts.Data,
                MediaStore.Images.Media.InterfaceConsts.DisplayName
            };

            // 按添加时间倒序,取最新的一条记录
            var cursor = _androidContext.ContentResolver.Query(
                MediaStore.Images.Media.ExternalContentUri,
                queryColumns,
                null,
                null,
                $"{MediaStore.Images.Media.InterfaceConsts.DateAdded} DESC");

            if (cursor == null || !cursor.MoveToFirst())
            {
                cursor?.Close();
                return;
            }

            int pathIndex = cursor.GetColumnIndex(MediaStore.Images.Media.InterfaceConsts.Data);
            int nameIndex = cursor.GetColumnIndex(MediaStore.Images.Media.InterfaceConsts.DisplayName);
            
            string imagePath = cursor.GetString(pathIndex);
            string imageName = cursor.GetString(nameIndex);

            // 判断是否为截图:路径包含Screenshots,或文件名含关键词
            bool isScreenshot = imagePath.IndexOf("Screenshots", StringComparison.OrdinalIgnoreCase) >= 0
                                || imageName.IndexOf("Screenshot", StringComparison.OrdinalIgnoreCase) >= 0
                                || imageName.IndexOf("截图", StringComparison.OrdinalIgnoreCase) >= 0;

            if (isScreenshot)
            {
                _screenshotCallback?.Invoke(imageName);
            }

            cursor.Close();
        }
    }
}

2. 在MAUI共享项目中集成检测器并更新UI

在你的主页面(比如MainPage.xaml.cs)中,处理权限申请、初始化检测器,并在检测到截图时更新Label:

using Microsoft.Maui.ApplicationModel;
using YourAppNamespace.Platforms.Android;
using System.Threading.Tasks;

namespace YourAppNamespace
{
    public partial class MainPage : ContentPage
    {
        private ScreenshotDetector _detector;

        public MainPage()
        {
            InitializeComponent();
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();
            _ = RequestStoragePermissions();
            InitScreenshotDetector();
        }

        protected override void OnDisappearing()
        {
            base.OnDisappearing();
            _detector?.StopListening();
        }

        // 动态申请存储权限(Android 6+ 必需)
        private async Task RequestStoragePermissions()
        {
            if (DeviceInfo.Platform != DevicePlatform.Android) return;

            PermissionStatus status;
            if (OperatingSystem.IsAndroidVersionAtLeast(13))
            {
                status = await Permissions.RequestAsync<Permissions.Media>();
            }
            else
            {
                status = await Permissions.RequestAsync<Permissions.StorageRead>();
            }
        }

        // 初始化截图检测器
        private void InitScreenshotDetector()
        {
            if (DeviceInfo.Platform != DevicePlatform.Android) return;

            _detector = new ScreenshotDetector(
                Android.App.Application.Context, 
                fileName =>
                {
                    // 必须在主线程更新UI
                    MainThread.BeginInvokeOnMainThread(() =>
                    {
                        ScreenshotTipLabel.Text = $"检测到截图:{fileName}";
                        // 调用你已实现的截图文件获取逻辑
                        // YourExistingGetScreenshotFileLogic(fileName);
                    });
                });
            _detector.StartListening();
        }
    }
}

对应的XAML中添加用于显示提示的Label:

<Label 
    x:Name="ScreenshotTipLabel" 
    Text="等待检测截图..." 
    HorizontalOptions="Center" 
    VerticalOptions="Center" />

关键注意事项

  • 权限适配:Android 13+ 使用Permissions.Media,旧版本使用Permissions.StorageRead,必须动态申请,不能仅依赖AndroidManifest.xml配置。
  • 设备兼容性:部分厂商的截图路径/命名可能有差异,可根据需要扩展isScreenshot的判断条件。
  • 内存泄漏:页面消失时务必调用StopListening()注销监听。
  • UI更新线程:MAUI的UI操作必须在主线程执行,所以要用MainThread.BeginInvokeOnMainThread包裹Label更新逻辑。

内容的提问来源于stack exchange,提问作者lamed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 06:17:37