Xamarin 表单:检查一段时间后用户是否处于非活动状态注销应用程序 [英] Xamarin forms: Check if user inactive after some time log out app

查看:15
本文介绍了Xamarin 表单:检查一段时间后用户是否处于非活动状态注销应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我正在尝试使用 PCL 以 xamarin 形式构建应用程序.如果应用程序空闲超过 10 分钟或更长时间,我正尝试从我的应用程序注销用户.我通过在应用程序即将进入睡眠状态时调用的事件进行了尝试.但是如果设备 screentimeout 设置为从不超时,那么它可能永远不会进入睡眠状态.那么我怎样才能做到这一点.我是 xamarin 表单的新手.当我为所有平台构建应用程序时,我很困惑如何管理此超时?

Hi I am trying to build an application in xamarin forms using PCL. I am trying to logout user from my app if the app is idle more than 10minute or more. I tried it by events that are called on the time when app is about to go to sleep state. But if the device screentimeout is set for never timeout then maybe It will never go to sleep. So how can I achieve this. I am new to xamarin forms. And as I am building the app for all the platforms I am confused how to manage this timeout?

推荐答案

现在我使用以下方法.可能需要进行一些额外的测试以确保一切都按预期进行.例如,我不确定如果应用程序(iOS 或 Android)长时间处于后台会发生什么.计时器是否仍会每秒被调用一次?也许当使用具有足够短到期时间(约 5 分钟)的计时器时,这没有任何问题?等等……

For now I use the following approach. Might need to do some additional testing to make sure everything works as expected. For example I am not sure what will happen if the app (iOS or Android) is in the background for extended amounts of time. Will the timer still be called every second or not? Perhaps when using timers with a short enough expiration time (~5 minutes) this is no issue whatsoever? Etc...

我的方法基于我在网上找到的几段代码(一些 Xamarin 代码,一些 Swift/Java 代码) - 似乎没有一个好的综合解决方案.

I've based my approach on several pieces of code I found on the web (some Xamarin code, some Swift / Java code) - there didn't seem to be a good comprehensive solution.

无论如何,一些初步测试表明这种方法很有效.

Anyways, some preliminary testing suggests this approach works fine.

首先,我创建了一个名为 SessionManager 的单例类.此类包含一个计时器(实际上只是一个每秒休眠的 while 循环)和启动、停止和延长计时器的方法.如果会话过期计时器过期,它也会触发一个事件.

First I've created a singleton class called SessionManager. This class contains a timer (actually just a while loop that sleeps every second) and methods to start, stop and extend the timer. It will also fire an event if the session expiration timer is expired.

public sealed class SessionManager
{
    static readonly Lazy<SessionManager> lazy =
        new Lazy<SessionManager>(() => new SessionManager());

    public static SessionManager Instance { get { return lazy.Value; } }

    SessionManager() { 
        this.SessionDuration = TimeSpan.FromMinutes(5);
        this.sessionExpirationTime = DateTime.FromFileTimeUtc(0);
    }

    /// <summary>
    /// The duration of the session, by default this is set to 5 minutes.
    /// </summary>
    public TimeSpan SessionDuration;

    /// <summary>
    /// The OnSessionExpired event is fired when the session timer expires.
    /// This event is not fired if the timer is stopped manually using 
    /// EndTrackSession.
    /// </summary>
    public EventHandler OnSessionExpired;

    /// <summary>
    /// The session expiration time.
    /// </summary>
    DateTime sessionExpirationTime;

    /// <summary>
    /// A boolean value indicating wheter a session is currently active.
    /// Is set to true when StartTrackSessionAsync is called. Becomes false if 
    /// the session is expired manually or by expiration of the session 
    /// timer.
    /// </summary>
    public bool IsSessionActive { private set; get; }

    /// <summary>
    /// Starts the session timer.
    /// </summary>
    /// <returns>The track session async.</returns>
    public async Task StartTrackSessionAsync() {
        this.IsSessionActive = true;

        ExtendSession();

        await StartSessionTimerAsync();
    }

    /// <summary>
    /// Stop tracking a session manually. The OnSessionExpired will not be 
    /// called.
    /// </summary>
    public void EndTrackSession() {
        this.IsSessionActive = false;

        this.sessionExpirationTime = DateTime.FromFileTimeUtc(0);
    }

    /// <summary>
    /// If the session is active, then the session time is extended based 
    /// on the current time and the SessionDuration.
    /// duration.
    /// </summary>
    public void ExtendSession()
    {
        if (this.IsSessionActive == false) {
            return;
        }

        this.sessionExpirationTime = DateTime.Now.Add(this.SessionDuration);
    }

    /// <summary>
    /// Starts the session timer. When the session is expired and still 
    /// active the OnSessionExpired event is fired. 
    /// </summary>
    /// <returns>The session timer async.</returns>
    async Task StartSessionTimerAsync() {
        if (this.IsSessionActive == false) {
            return;
        }

        while (DateTime.Now < this.sessionExpirationTime) {
            await Task.Delay(1000);                
        }

        if (this.IsSessionActive && this.OnSessionExpired != null) {
            this.IsSessionActive = false;

            this.OnSessionExpired.Invoke(this, null);
        }
    }
}

对于 Android 应用,我:

For the Android app I then:

  • 在 MainActivity 中配置 SessionManager 以在会话过期时注销.

  • Configure the SessionManager in the MainActivity to logout when the session expires.

覆盖 MainActivity 中的 OnUserInteraction 方法以扩展用户交互的会话计时器.

Override the OnUserInteraction method in the MainActivity to extend the session timer on user interaction.

public class MainActivity /* ... */ {
    protected override void OnCreate(Bundle bundle)
    {   
        // ...

        SessionManager.Instance.SessionDuration = TimeSpan.FromSeconds(10);
        SessionManager.Instance.OnSessionExpired = HandleSessionExpired;
    }

    public override void OnUserInteraction()
    {
        base.OnUserInteraction();

        SessionManager.Instance.ExtendSession();
    }

    async void HandleSessionExpired(object sender, EventArgs e)
    {
        await App.Instance.DoLogoutAsync();
    }    
}

对于 iOS,我执行以下操作:

For iOS I do the following:

  • 在 AppDelegate 中配置 SessionManager 以在会话过期时注销.

  • Configure the SessionManager in the AppDelegate to logout when the session expires.

向键窗口添加自定义手势处理程序,以在用户交互时延长会话计时器.

Add a custom gesture handler to the key window to extend the session timer on user interaction.

public partial class AppDelegate /* ... */
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        // ...

        var success = base.FinishedLaunching(app, options);

        if (success) {
            SessionManager.Instance.SessionDuration = TimeSpan.FromSeconds(10);
            SessionManager.Instance.OnSessionExpired += HandleSessionExpired;

            var allGesturesRecognizer = new AllGesturesRecognizer(delegate
            {
                SessionManager.Instance.ExtendSession();
            });

            this.Window.AddGestureRecognizer(allGesturesRecognizer);
        }

        return success;
    }

    async void HandleSessionExpired(object sender, EventArgs e)
    {
        await App.instance.DoLogoutAsync();
    }

    class AllGesturesRecognizer: UIGestureRecognizer {
        public delegate void OnTouchesEnded();

        private OnTouchesEnded touchesEndedDelegate;

        public AllGesturesRecognizer(OnTouchesEnded touchesEnded) {
            this.touchesEndedDelegate = touchesEnded;
        }

        public override void TouchesEnded(NSSet touches, UIEvent evt)
        {
            this.State = UIGestureRecognizerState.Failed;

            this.touchesEndedDelegate();

            base.TouchesEnded(touches, evt);
        }
    }
}

Bolo 在下面问了一个很好的问题,所以我会在这里添加它.用户登录后立即调用 StartTrackSessionAsync.当然,当用户退出应用程序时也应调用 EndTrackSession.

Bolo asked a good question below, so I'll add it here. StartTrackSessionAsync is called as soon as the user is logged in. EndTrackSession should be called when the user is logged out of the app as well of course.

这篇关于Xamarin 表单:检查一段时间后用户是否处于非活动状态注销应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆