【问题标题】:Why Could My Application Trial Not be Working in the Marketplace为什么我的应用程序试用版无法在市场中运行
【发布时间】:2013-10-31 22:37:03
【问题描述】:

我最近在 Windows Phone Marketplace 上发布了一个带有试用版的小应用程序,但我的应用程序没有按预期工作。我在试用时关注了http://code.msdn.microsoft.com/Trial-Experience-Sample-c58f21af,这样我就可以调用当前的“LicenseInformation”状态并根据当前应用程序的许可证状态是否阻止某个功能。根据示例应用程序,The LicenseMode property returns a value from the LicenseModes enum (Full, MissingOrRevoked, or Trial) so that your app code needs to check only a single value. There’s also a convenient Boolean IsFull property. Whenever the license mode has changed, or it is likely to have changed, TrialExperienceHelper raises its LicenseChanged event and your app code can handle that event to query LicenseMode or IsFull again. Then, your app can control the availability of features, ads, and your Buy UI as needed.

在我的应用程序中,我有一个单击事件,我想在其中执行基于当前 LicenseInformation 状态和计数的操作(计数是应用特定方面保存图像的次数)。

Settings.SavedCount.Value记录保存按钮被点击的次数,如果次数在100以上且应用处于试用模式我想问用户是否要升级,否则如果计数是当应用程序处于试用模式或许可证处于完整模式时小于 100,则允许用户继续保存过程(希望这符合逻辑)。

void saveButton_Click(object sender, EventArgs e)
{
    Settings.SavedCount.Value += 1;        

    if (TrialViewModel.LicenseModeString == "Trial" && Settings.SavedCount.Value > 100)
    {
        MessageBoxResult result = MessageBox.Show("You have saved over 100 items! Would you like to continue?", "Congratulations!", MeesageBoxButton.OKCancel);

        switch (result)
        {
            case MessageBoxResult.OK:
                //A command takes a parameter so pass null
                TrialViewModel.BuyCommand.Execute(null);
                break;
            case MessageBoxResult.Cancel:
                editPagePivotControl.SelectedIndex = 0;
                break;                  
        }
    }
    else if ((TrialViewModel.LicenseModeString == "Trial" && Settings.SavedCount.Value <= 100) || (TrialViewModel.LicenseModeString == "Full")
        {
            PerformSaveAsync();
        }
    }
}

在调试模式下使用 msdn 网站上的示例实现进行测试时,试用和完整实现工作正常,然后在发布模式下,许可证被列为 MissingOrRevoked,我认为在市场上会正确调用。当我在试用和完整模式下在市场上下载应用程序时,实际发生的情况是永远不会调用 PerformSaveAsync() 方法(最终保存新图像并禁用按钮),我可以在其他地方使用新图像.我无法弄清楚问题可能是什么?

编辑** 在研究中,我遇到了http://msdn.microsoft.com/en-us/library/aa691310(v=vs.71).aspx,它指出The operation x &amp;&amp; y corresponds to the operation x &amp; y, except that y is evaluated only if x is true. 和`•操作 x || y 对应于操作 x | y,除了仅当 x 为 false/' 时才评估 y。这会是问题的原因吗?如果是,应该如何解决?

编辑 2** 添加 TrialViewModel 和 TrialExperienceHelper.cs 以获取更多信息

试用视图模型

TrialViewModel

#region fields
private RelayCommand buyCommand;
#endregion fields

#region constructors
public TrialViewModel()
{
    // Subscribe to the helper class's static LicenseChanged event so that we can re-query its LicenseMode property when it changes.
    TrialExperienceHelper.LicenseChanged += TrialExperienceHelper_LicenseChanged;
}
#endregion constructors

#region properties        
/// <summary>
/// You can bind the Command property of a Button to BuyCommand. When the Button is clicked, BuyCommand will be
/// invoked. The Button will be enabled as long as BuyCommand can execute.
/// </summary>
public RelayCommand BuyCommand
{
    get
    {
        if (this.buyCommand == null)
        {
            // The RelayCommand is constructed with two parameters - the action to perform on invocation,
            // and the condition under which the command can execute. It's important to call RaiseCanExecuteChanged
            // on a command whenever its can-execute condition might have changed. Here, we do that in the TrialExperienceHelper_LicenseChanged
            // event handler.
            this.buyCommand = new RelayCommand(
                param => TrialExperienceHelper.Buy(),
                param => TrialExperienceHelper.LicenseMode == TrialExperienceHelper.LicenseModes.Trial);
        }
        return this.buyCommand;
    }
}

public string LicenseModeString
{
    get
    {
        return TrialExperienceHelper.LicenseMode.ToString()/* + ' ' + AppResources.ModeString*/;
    }
}
#endregion properties

#region event handlers
// Handle TrialExperienceHelper's LicenseChanged event by raising property changed notifications on the
// properties and commands that 
internal void TrialExperienceHelper_LicenseChanged()
{
    this.RaisePropertyChanged("LicenseModeString");
    this.BuyCommand.RaiseCanExecuteChanged();
}
#endregion event handlers

TrialExperienceHelper.cs

#region enums
    /// <summary>
    /// The LicenseModes enumeration describes the mode of a license.
    /// </summary>
    public enum LicenseModes
    {
        Full,
        MissingOrRevoked,
        Trial
    }
    #endregion enums

    #region fields
#if DEBUG
    // Determines how a debug build behaves on launch. This field is set to LicenseModes.Full after simulating a purchase.
    // Calling the Buy method (or navigating away from the app and back) will simulate a purchase.
    internal static LicenseModes simulatedLicMode = LicenseModes.Trial;
#endif // DEBUG
    private static bool isActiveCache;
    private static bool isTrialCache;
    #endregion fields

    #region constructors
    // The static constructor effectively initializes the cache of the state of the license when the app is launched. It also attaches
    // a handler so that we can refresh the cache whenever the license has (potentially) changed.
    static TrialExperienceHelper()
    {
        TrialExperienceHelper.RefreshCache();
        PhoneApplicationService.Current.Activated += (object sender, ActivatedEventArgs e) => TrialExperienceHelper.
#if DEBUG
            // In debug configuration, when the user returns to the application we will simulate a purchase.
OnSimulatedPurchase();
#else // DEBUG
            // In release configuration, when the user returns to the application we will refresh the cache.
RefreshCache();
#endif // DEBUG
    }
    #endregion constructors

    #region properties
    /// <summary>
    /// The LicenseMode property combines the active and trial states of the license into a single
    /// enumerated value. In debug configuration, the simulated value is returned. In release configuration,
    /// if the license is active then it is either trial or full. If the license is not active then
    /// it is either missing or revoked.
    /// </summary>
    public static LicenseModes LicenseMode
    {
        get
        {
#if DEBUG
            return simulatedLicMode;
#else // DEBUG
            if (TrialExperienceHelper.isActiveCache)
            {
                return TrialExperienceHelper.isTrialCache ? LicenseModes.Trial : LicenseModes.Full;
            }
            else // License is inactive.
            {
                return LicenseModes.MissingOrRevoked;
            }
#endif // DEBUG
        }
    }

    /// <summary>
    /// The IsFull property provides a convenient way of checking whether the license is full or not.
    /// </summary>
    public static bool IsFull
    {
        get
        {
            return (TrialExperienceHelper.LicenseMode == LicenseModes.Full);
        }
    }
    #endregion properties

    #region methods
    /// <summary>
    /// The Buy method can be called when the license state is trial. the user is given the opportunity
    /// to buy the app after which, in all configurations, the Activated event is raised, which we handle.
    /// </summary>
    public static void Buy()
    {
        MarketplaceDetailTask marketplaceDetailTask = new MarketplaceDetailTask();
        marketplaceDetailTask.ContentType = MarketplaceContentType.Applications;
        marketplaceDetailTask.Show();
    }

    /// <summary>
    /// This method can be called at any time to refresh the values stored in the cache. We re-query the application object
    /// for the current state of the license and cache the fresh values. We also raise the LicenseChanged event.
    /// </summary>
    public static void RefreshCache()
    {
        TrialExperienceHelper.isActiveCache = CurrentApp.LicenseInformation.IsActive;
        TrialExperienceHelper.isTrialCache = CurrentApp.LicenseInformation.IsTrial;
        TrialExperienceHelper.RaiseLicenseChanged();
    }

    private static void RaiseLicenseChanged()
    {
        if (TrialExperienceHelper.LicenseChanged != null)
        {
            TrialExperienceHelper.LicenseChanged();
        }
    }

#if DEBUG
    private static void OnSimulatedPurchase()
    {
        TrialExperienceHelper.simulatedLicMode = LicenseModes.Full;
        TrialExperienceHelper.RaiseLicenseChanged();
    }
#endif // DEBUG
    #endregion methods

    #region events
    /// <summary>
    /// The static LicenseChanged event is raised whenever the value of the LicenseMode property has (potentially) changed.
    /// </summary>
    public static event LicenseChangedEventHandler LicenseChanged;
    #endregion events

【问题讨论】:

    标签: c# windows-phone-8 operators


    【解决方案1】:

    关于您的编辑,我认为您的条件没有任何问题,您的报价只是操作员很懒惰,只评估确定结果所需的内容(例如,当您执行 x&& y 时,如果 x 为假, x&& false=> false 和 x&& true==false 这是相同的结果,因此它不评估 y)。
    就像我在上一个问题中所说的那样,即使 windows phone 7 api 仍然可以在 windows phone 8 上运行,所以如果你为这两个平台创建代码,可能不需要专门为 wp8 使用新的 api。
    在这段代码中我没有看到任何问题,但是为什么要将 LicenseModes 枚举转换为字符串,使用枚举会增加一些类型安全性并防止您进行一些无效的比较。
    唯一的问题是您在哪里设置 LicenseModeString 或 PerformSaveAsync 内部有问题?

    【讨论】:

    • 我对 LicenseModes 枚举的表述一定是错误的,它是 public enum LicenseModes { Full, MissingOrRevoked, Trial }。我相信我会在检查TrialViewModel.LicenseModeString 之前更改我的条件顺序以检查Settings.SavedCount.Value。我还应该更改为逻辑运算符而不是条件运算符来检查整个 if else 语句吗? PerformSaveAsync 根本没有被调用,因为它更新了视图并禁用了一个按钮,所以我会看到这种变化。
    • 另外,我将更新我的解决方案,以使用 msdn.microsoft.com/en-us/library/vstudio/… 中的另一个字符串比较版本将 TrialViewModel.LicenseModeString 与其试用或完整状态进行比较,这可能会有所帮助吗?在这一点上,我会尝试任何事情。
    • @Matthew 就像我在回复中所说的那样,我认为更改顺序不会改变任何事情,无论响应顺序如何,响应仍然相同,只是某些部分不会被评估以保存一些时间(你想要什么)。您唯一需要确保的是括号在正确的位置,这在您粘贴的代码中似乎很好(即使第二个如果最后缺少括号但我想这只是一个错误的复制粘贴。另外,我仍然不明白为什么您不在 TrialViewModel 中保留 LicenseModes 枚举值而不是字符串...
    • 你说得对,这是一个复制和粘贴错误,老实说,我认为订单不会改变任何东西。但是,我确实将我的 TrialViewModel 和 TrialExperienceHelper 添加为编辑,这样您就可以看到我在确定TrialViewModel.LicenseModeString 时到底做了什么。 LicenseModeTrialExperienceHelper.cs 中调用,它应该返回许可证状态,但也许 isActiveCache 是 False,这在从 Marketplace 下载应用程序时不应该发生正确?
    • IsActive 仅在过期后设置为 false,如果您在商店中设置了一些基于时间的过期,否则它应该始终为 true。我在您的文章中看到您有一个带有一些附加文本的注释部分,如果您打算取消注释它在某些时候会破坏条件,这就是为什么最好创建另一个只返回 TrialExperienceHelper.LicenseMode 的属性确保您正在与正确的事物进行比较...
    【解决方案2】:

    如果您的开发构建工作正常,唯一的区别是应用通过商店发布,那么我认为这不太可能是您的逻辑。

    当您提交应用时,您确定选中了能够在应用中使用试用功能的选项吗?

    如果您没有选中此项,那么它将无法在已发布的应用中运行。

    【讨论】:

    • 是的,我相信我这样做了,因为商店中提供了试用版或购买版(尽管我在发现这些错误后从商店取消了该应用程序的发布,因此没有其他人会遇到同样的情况)。
    • 您认为可能是条件运算符没有在if else 中执行两个条件语句吗?阅读msdn.microsoft.com/en-us/library/aa691310(v=vs.71).aspx 让我三思而后行,我应该使用逻辑运算符还是条件运算符。另外,我正在考虑执行不同的字符串比较方法,并在此处发布了一个问题 stackoverflow.com/questions/19530857/… 。你有什么想法?
    • 好吧,看来我别无选择,只能尝试在市场上更新应用程序。我确实检查了,我确实检查了试用选项,并在所有市场以基本价格层(0.99 美元)提供应用程序。如果不是这样,我将更改 if 语句中检查项目的顺序,并可能使用逻辑运算符而不是条件运算符。如果不是这个,那么我不确定是什么,可能会恢复到 WP7 检查试用许可证的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多