扩展执行似乎在 Windows 10 个通用 JavaScript 应用程序中不起作用
Extended execution does not seem to work in Windows 10 Universal JavaScript apps
我有一个用 JavaScript 编写的 Windows 10 通用应用程序。该应用程序是一个位置跟踪器,需要在后台 运行,我正在尝试使用 ExtendedExecution API 来实现这一点。不过,我发现这与 C#/XAML 应用程序中宣传的一样有效,但在 JavaScript 应用程序中不起作用。
作为实验,在 Visual Studio 2015 年,我通过 File -> New -> Project -> Visual C# -> Blank App (Universal Windows)
创建了一个新的 C# 项目,并按如下方式对其进行了配置:
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
private Geolocator locator;
private ObservableCollection<string> coordinates = new ObservableCollection<string>();
private ExtendedExecutionSession session;
public MainPage()
{
this.InitializeComponent();
// Start geo locating
locator = new Geolocator();
locator.DesiredAccuracy = PositionAccuracy.High;
locator.DesiredAccuracyInMeters = 0;
locator.MovementThreshold = 0;
locator.PositionChanged += positionChanged;
coords.ItemsSource = coordinates;
// Request extended execution
RequestExtendedExecution();
}
private async void RequestExtendedExecution()
{
// Request extended execution via the ExtendedExecution API
session = new ExtendedExecutionSession();
session.Description = "Location Tracker";
session.Reason = ExtendedExecutionReason.LocationTracking;
session.Revoked += ExtendedExecutionSession_Revoked;
var result = await session.RequestExtensionAsync();
if (result == ExtendedExecutionResult.Allowed)
coordinates.Insert(0, "Extended execution SUCCESS");
else if (result == ExtendedExecutionResult.Denied)
coordinates.Insert(0, "Extended execution DENIED");
else
coordinates.Insert(0, "Extended execution unexpected return code");
}
private async void EndExtendedExecution()
{
if (session != null)
{
session.Dispose();
session = null;
}
}
private void ExtendedExecutionSession_Revoked(object sender, ExtendedExecutionRevokedEventArgs args)
{
var _ = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
coordinates.Insert(0, "Extended execution REVOKED: " + ((args.Reason == ExtendedExecutionRevokedReason.Resumed) ? "Resumed" : (args.Reason == ExtendedExecutionRevokedReason.SystemPolicy) ? "Resources" : "Unknown reason"));
});
EndExtendedExecution();
}
private void positionChanged(Geolocator sender, PositionChangedEventArgs args)
{
var coord = args.Position;
string position = string.Format("{0},{1}",
args.Position.Coordinate.Point.Position.Latitude,
args.Position.Coordinate.Point.Position.Longitude);
var _ = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
coordinates.Insert(0, position);
});
}
}
标记很简单:
<ListView x:Name="coords" />
这绝对符合预期。当我请求扩展会话时,我得到 "Extended execution SUCCESS",当最小化应用程序继续向 ListView 添加坐标时,当返回到前台时我得到 "Extended execution REVOKED: Resumed"。超级骗子。回到 Visual Studio 2015,然后我通过 File -> New -> Project -> JavaScript -> Blank App (Universal Windows)
创建了一个新的 JavaScript 项目并实现了以下相同的功能:
(function () {
"use strict";
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var extendedExecution = Windows.ApplicationModel.ExtendedExecution;
var session = null;
var geolocator = null;
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize your application here.
// Start geo tracking
Windows.Devices.Geolocation.Geolocator.requestAccessAsync().done(
function (accessStatus) {
switch (accessStatus) {
case Windows.Devices.Geolocation.GeolocationAccessStatus.allowed:
geolocator = new Windows.Devices.Geolocation.Geolocator();
geolocator.ReportInterval = 1000;
// Subscribe to PositionChanged event to get updated tracking positions
geolocator.addEventListener("positionchanged", function (e) {
var coord = e.position.coordinate;
log("app.onactivated: coord = " + coord.point.position.latitude + ", " + coord.point.position.longitude, false, true, false);
});
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.denied:
log("Geolocator.requestAccessAsync: Access to location is denied.", false, true, false);
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.unspecified:
log("Geolocator.requestAccessAsync: Unspecified error.", false, true, false);
break;
}
},
function (err) {
log("Geolocator.requestAccessAsync: error " + err, false, true, false);
}
);
// Request extended execution
requestExtendedExecution();
} else {
// TODO: This application was suspended and then terminated.
// To create a smooth user experience, restore application state here so that it looks like the app never stopped running.
}
args.setPromise(WinJS.UI.processAll());
}
};
app.oncheckpoint = function (args) {
// TODO: This application is about to be suspended. Save any state that needs to persist across suspensions here.
// You might use the WinJS.Application.sessionState object, which is automatically saved and restored across suspension.
// If you need to complete an asynchronous operation before your application is suspended, call args.setPromise().
log("app.oncheckpoint: application is about to be suspended");
};
function requestExtendedExecution() {
// If we already have an extended session, close it before requesting a new one.
if (session != null) {
session.close();
session = null;
}
// Request extended execution via the ExtendedExecution API
session = new extendedExecution.ExtendedExecutionSession();
session.description = "Background location tracking";
session.reason = extendedExecution.ExtendedExecutionReason.locationTracking;
session.onrevoked = function (args) {
log("requestExtendedExecution: Background mode revoked: " + args.reason);
requestExtendedExecution();
};
session.requestExtensionAsync().done(
function success() {
log("requestExtendedExecution: Successfully enabled background mode");
},
function error(error) {
log("requestExtendedExecution: Could not enable background mode: " + error);
}
);
}
function log (text) {
var now = new Date();
var timestamp = now.toLocaleDateString() + " " + now.toLocaleTimeString();
var outputDiv = document.getElementById("divOutput");
outputDiv.innerHTML = timestamp + " " + text + "<br/>" + outputDiv.innerHTML;
}
app.start();
})();
标记是:
<div id="divOutput"></div>
当我请求扩展会话时,我仍然得到 "Extended execution SUCCESS",是的,但是当我最小化应用程序时,app.oncheckpoint 被调用,应用程序被暂停并且没有进一步的 activity 直到它 returns 到前台。我也曾尝试从 app.oncheckpoint 中请求延长会话,但这也没有效果。
有人对此有所了解吗?提前致谢。
有效。实际问题是您的代码没有监听撤销事件。它应该被撤销。 :)
而且你的代码也有一些小问题。
尝试以下操作:
function requestExtendedExecution() {
// Request extended execution via the ExtendedExecution API
session = new extendedExecution.ExtendedExecutionSession();
session.description = "Background location tracking";
session.reason = extendedExecution.ExtendedExecutionReason.locationTracking;
session.onrevoked = function (args) {
log("requestExtendedExecution: Background mode revoked: " + args.reason);
};
session.requestExtensionAsync().done(
function success() {
log("requestExtendedExecution: Successfully enabled background mode");
},
function error(error) {
log("requestExtendedExecution: Could not enable background mode: " + error);
}
);
}
我有一个用 JavaScript 编写的 Windows 10 通用应用程序。该应用程序是一个位置跟踪器,需要在后台 运行,我正在尝试使用 ExtendedExecution API 来实现这一点。不过,我发现这与 C#/XAML 应用程序中宣传的一样有效,但在 JavaScript 应用程序中不起作用。
作为实验,在 Visual Studio 2015 年,我通过 File -> New -> Project -> Visual C# -> Blank App (Universal Windows)
创建了一个新的 C# 项目,并按如下方式对其进行了配置:
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
private Geolocator locator;
private ObservableCollection<string> coordinates = new ObservableCollection<string>();
private ExtendedExecutionSession session;
public MainPage()
{
this.InitializeComponent();
// Start geo locating
locator = new Geolocator();
locator.DesiredAccuracy = PositionAccuracy.High;
locator.DesiredAccuracyInMeters = 0;
locator.MovementThreshold = 0;
locator.PositionChanged += positionChanged;
coords.ItemsSource = coordinates;
// Request extended execution
RequestExtendedExecution();
}
private async void RequestExtendedExecution()
{
// Request extended execution via the ExtendedExecution API
session = new ExtendedExecutionSession();
session.Description = "Location Tracker";
session.Reason = ExtendedExecutionReason.LocationTracking;
session.Revoked += ExtendedExecutionSession_Revoked;
var result = await session.RequestExtensionAsync();
if (result == ExtendedExecutionResult.Allowed)
coordinates.Insert(0, "Extended execution SUCCESS");
else if (result == ExtendedExecutionResult.Denied)
coordinates.Insert(0, "Extended execution DENIED");
else
coordinates.Insert(0, "Extended execution unexpected return code");
}
private async void EndExtendedExecution()
{
if (session != null)
{
session.Dispose();
session = null;
}
}
private void ExtendedExecutionSession_Revoked(object sender, ExtendedExecutionRevokedEventArgs args)
{
var _ = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
coordinates.Insert(0, "Extended execution REVOKED: " + ((args.Reason == ExtendedExecutionRevokedReason.Resumed) ? "Resumed" : (args.Reason == ExtendedExecutionRevokedReason.SystemPolicy) ? "Resources" : "Unknown reason"));
});
EndExtendedExecution();
}
private void positionChanged(Geolocator sender, PositionChangedEventArgs args)
{
var coord = args.Position;
string position = string.Format("{0},{1}",
args.Position.Coordinate.Point.Position.Latitude,
args.Position.Coordinate.Point.Position.Longitude);
var _ = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
coordinates.Insert(0, position);
});
}
}
标记很简单:
<ListView x:Name="coords" />
这绝对符合预期。当我请求扩展会话时,我得到 "Extended execution SUCCESS",当最小化应用程序继续向 ListView 添加坐标时,当返回到前台时我得到 "Extended execution REVOKED: Resumed"。超级骗子。回到 Visual Studio 2015,然后我通过 File -> New -> Project -> JavaScript -> Blank App (Universal Windows)
创建了一个新的 JavaScript 项目并实现了以下相同的功能:
(function () {
"use strict";
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var extendedExecution = Windows.ApplicationModel.ExtendedExecution;
var session = null;
var geolocator = null;
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize your application here.
// Start geo tracking
Windows.Devices.Geolocation.Geolocator.requestAccessAsync().done(
function (accessStatus) {
switch (accessStatus) {
case Windows.Devices.Geolocation.GeolocationAccessStatus.allowed:
geolocator = new Windows.Devices.Geolocation.Geolocator();
geolocator.ReportInterval = 1000;
// Subscribe to PositionChanged event to get updated tracking positions
geolocator.addEventListener("positionchanged", function (e) {
var coord = e.position.coordinate;
log("app.onactivated: coord = " + coord.point.position.latitude + ", " + coord.point.position.longitude, false, true, false);
});
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.denied:
log("Geolocator.requestAccessAsync: Access to location is denied.", false, true, false);
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.unspecified:
log("Geolocator.requestAccessAsync: Unspecified error.", false, true, false);
break;
}
},
function (err) {
log("Geolocator.requestAccessAsync: error " + err, false, true, false);
}
);
// Request extended execution
requestExtendedExecution();
} else {
// TODO: This application was suspended and then terminated.
// To create a smooth user experience, restore application state here so that it looks like the app never stopped running.
}
args.setPromise(WinJS.UI.processAll());
}
};
app.oncheckpoint = function (args) {
// TODO: This application is about to be suspended. Save any state that needs to persist across suspensions here.
// You might use the WinJS.Application.sessionState object, which is automatically saved and restored across suspension.
// If you need to complete an asynchronous operation before your application is suspended, call args.setPromise().
log("app.oncheckpoint: application is about to be suspended");
};
function requestExtendedExecution() {
// If we already have an extended session, close it before requesting a new one.
if (session != null) {
session.close();
session = null;
}
// Request extended execution via the ExtendedExecution API
session = new extendedExecution.ExtendedExecutionSession();
session.description = "Background location tracking";
session.reason = extendedExecution.ExtendedExecutionReason.locationTracking;
session.onrevoked = function (args) {
log("requestExtendedExecution: Background mode revoked: " + args.reason);
requestExtendedExecution();
};
session.requestExtensionAsync().done(
function success() {
log("requestExtendedExecution: Successfully enabled background mode");
},
function error(error) {
log("requestExtendedExecution: Could not enable background mode: " + error);
}
);
}
function log (text) {
var now = new Date();
var timestamp = now.toLocaleDateString() + " " + now.toLocaleTimeString();
var outputDiv = document.getElementById("divOutput");
outputDiv.innerHTML = timestamp + " " + text + "<br/>" + outputDiv.innerHTML;
}
app.start();
})();
标记是:
<div id="divOutput"></div>
当我请求扩展会话时,我仍然得到 "Extended execution SUCCESS",是的,但是当我最小化应用程序时,app.oncheckpoint 被调用,应用程序被暂停并且没有进一步的 activity 直到它 returns 到前台。我也曾尝试从 app.oncheckpoint 中请求延长会话,但这也没有效果。
有人对此有所了解吗?提前致谢。
有效。实际问题是您的代码没有监听撤销事件。它应该被撤销。 :)
而且你的代码也有一些小问题。
尝试以下操作:
function requestExtendedExecution() {
// Request extended execution via the ExtendedExecution API
session = new extendedExecution.ExtendedExecutionSession();
session.description = "Background location tracking";
session.reason = extendedExecution.ExtendedExecutionReason.locationTracking;
session.onrevoked = function (args) {
log("requestExtendedExecution: Background mode revoked: " + args.reason);
};
session.requestExtensionAsync().done(
function success() {
log("requestExtendedExecution: Successfully enabled background mode");
},
function error(error) {
log("requestExtendedExecution: Could not enable background mode: " + error);
}
);
}