【问题标题】:Best way to show a passcode screen everytime an app is launched/activated每次启动/激活应用程序时显示密码屏幕的最佳方式
【发布时间】:2013-11-03 14:38:31
【问题描述】:

我正在开发应使用密码保护的 Windows Phone 8 应用程序。每次启动或激活应用时显示密码屏幕的最佳方式是什么?

我认为行动的中心点应该是 App.xaml.cs 及其 Launch 和 Activation 事件处理程序。但是如何才能显示密码屏幕呢?

问题是,人们永远不知道应用程序启动或重新激活时会显示哪些页面。它是应用程序停用时最后显示的主页或任何其他页面。

我试图拦截到第一页的导航,取消它并改为显示密码页面:

// App.xaml.cs
private void InitializePhoneApplication() {
   ...
   RootFrame.Navigating += HandleFirstNavigation;
   ...
}

private void HandleFirstNavigation(object sender, NavigatingCancelEventArgs e) {
   RootFrame.Navigating -= HandleFirstNavigation;       
   e.Cancel = true;
   RootFrame.Dispatcher.BeginInvoke(new Action(this.OpenPasscodePage));
}

private void OpenPasscodePage() {
   RootFrame.Navigate(PasscodePageUri);
}

这有效,但仅当应用程序启动时。当应用程序重新激活(休眠或墓碑)时,将忽略 e.Cancel。虽然导航到密码页面被称为原始页面。

将密码页面的导航从 Navigating 移动到 Navigated 也不值得:

private void InitializePhoneApplication() {
   ...
   RootFrame.Navigated += PasscodePageAfterFirstNavigation;
   ...
}

private void PasscodePageAfterFirstNavigation(object sender, EventArgs e) {
   RootFrame.Navigated-= PasscodePageAfterFirstNavigation;       
   RootFrame.Navigate(PasscodePageUri);
}

这似乎是某种竞争条件:有时显示密码页面,有时显示原始页面。即使出现密码页面,这看起来也很糟糕,因为在应用程序进一步导航到密码页面之前,人们首先会在几分之一秒内看到原始页面。

两种解决方案都不起作用。知道实现这一点的正确方法是什么吗?

编辑: 同时我尝试了第三种解决方案,但它也不起作用。此解决方案使用 Uri Mapper:

App.xaml.cs

public bool PasscodeWasConfirmed; private void Application_Launching(object sender, LaunchingEventArgs e) { 
   ... 
   PasscodeWasConfirmed = false; 
   ... 
} 

private void Application_Activated(object sender, ActivatedEventArgs e) { 
   ... 
   PasscodeWasConfirmed = false; 
   ... 
}

public Uri InitialPageUri; 
public bool ShouldRedirectToPasscodePage(Uri uri) {
   if (PasswordWasConfirmend == false) {
      InitialPageUri = uri;
      return true;
   }
   return false; 
}

UriMapper

public class AppUriMapper : UriMapperBase {
    public override Uri MapUri(Uri uri) {
        App app = (Application.Current as App);
        if (app != null) {
            if (app.ShouldRedirectToPasscodePage(uri))
                return PasscodeQueryPage.PageUri;
        }

        // default
        return uri;
    }
}

密码页

public partial class PasscodePage : PhoneApplicationPage {
    ...
    private void PasscodeConfirmed() {
        App app = (Application.Current as App);
        app.PasscodeWasConfirmed = true;

        NavigationService.Navigate(app.InitialPageUri);
    }
}

逻辑正常工作,但在确认密码后应用程序未导航到 InitialPageUri。 Uri Mapper 被正确调用并返回 InitialPageUri(不再重定向)。但是没有导航发生...

没有错误、异常或调试输出。根本没有任何事情发生......

使用 Uri Mapper 时最大的问题: 当应用程序从休眠状态重新激活时,没有可以映射或重定向的导航...

【问题讨论】:

    标签: windows-phone-8


    【解决方案1】:

    (我已经编辑了以前的答案,而不是添加新答案)
    我花了一些时间试图找到解决方案,但我不明白为什么您的代码无法运行。 就我而言,如果我在 App.xaml 中进行这样的更改就足够了:

      private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
      {
         // Set the root visual to allow the application to render
         if (RootVisual != RootFrame)
            RootVisual = RootFrame;
    
         // Remove this handler since it is no longer needed
         RootFrame.Navigated -= CompleteInitializePhoneApplication;
         App.RootFrame.Navigate(new Uri("/passPage.xaml", UriKind.RelativeOrAbsolute));
      }
    

    这适用于链接http://sdrv.ms/1ajH40E 下的示例
    但是 - 当用户按下按钮并选择返回哪个应用程序时,我无法阻止用户看到最后一个屏幕,然后眨眼间他可以在离开应用程序之前看到最后一页。
    不知道点击MS按钮后是否可以改变这种行为:
    windows phone change deactivated app image

    第二次修改
    好的-也许我已经找到了解决方案,为什么它有时可以工作,有时却不在您的代码中。按开始或搜索按钮后,应用程序可以转到两种情况:墓碑和非墓碑。返回后会发生不同的事件。上面的代码适用于 Tombstone 案例,但不适用于非 tombstone。要使用第二个,您需要添加(因为页面没有再次初始化)-(当然它可以是不同的解决方案):

      bool afterActivation = false;
      private void Application_Activated(object sender, ActivatedEventArgs e)
      {
         afterActivation = true;
      }
      private void CheckForResetNavigation(object sender, NavigationEventArgs e)
      {
         // If the app has received a 'reset' navigation, then we need to check
         // on the next navigation to see if the page stack should be reset
         if (e.NavigationMode == NavigationMode.Reset)
            RootFrame.Navigated += ClearBackStackAfterReset;
    
         if (afterActivation)
         {
            afterActivation = false;
            App.RootFrame.Navigate(new Uri("/passPage.xaml", UriKind.RelativeOrAbsolute));
         }
      }
    

    还请确保您在 VS 中的调试属性:项目->属性->调试->停用复选框时的墓碑。
    你也可以在这里找到一些信息(如果你以前没有看过的话):
    http://blogs.msdn.com/b/ptorr/archive/2010/12/11/how-to-correctly-handle-application-deactivation-and-reactivation.aspx

    【讨论】:

    • 我不明白这应该如何工作。我的例子有什么不同? CompleteInitializePhoneApplication 和 CheckForResetNavigation 都是 RootFrame.Navigated 的处理程序。我在示例中使用的 PasscodePageAfterFirstNavigation 有何不同?
    • 我在上面写了一个特殊的例子,它可以工作——激活应用程序后,我看到的第一件事就是每次都通过页面。我必须承认我没有时间分析你的代码(我会在晚上尝试) - 我刚刚编写了适合我的代码。你试过了吗?
    • 是的,我尝试了您的代码(在我第一次发表评论之前已经尝试过),但它不起作用。请注意,问题不是应用程序启动,而是应用程序重新激活。从休眠状态重新激活时,没有可以重定向的导航,因此您的代码不起作用。当从 Tombstone 状态重新激活时,应用程序会自动导航到最后一个活动页面。似乎这种重新激活导航的工作方式与启动时的导航有所不同。在这种情况下,我的帖子中描述了竞态条件:有时应用程序导航到 PasscodePage,有时它不会...
    • 正如我所说,我已经编写了一段代码。请检查它是否按预期运行:sdrv.ms/1ajH40E 这是一个简短的一页 - 两页并通过页面。当我 luch 应用程序时,显示通过页面(很好),接下来我转到第二页,然后按开始按钮导航离开,当我返回时,我看到通过页面。你在用 XNA 吗?
    • 非常感谢您的反馈和示例项目。我会看看它试图找出为什么我的代码不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    相关资源
    最近更新 更多