- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在我的应用程序中,我需要在后台扫描 Wi-Fi 接入点。我能够启动任务并初始化 Wi-Fi 适配器,但下一个执行扫描的异步调用“await scanner.ScanForNetworks()”似乎永远无法完成任务。会不会是大量嵌套异步调用的结果?如果是这样,有什么可能的解决方法?
扫描任务.cs
namespace BackgroundTaskLibrary
{
public sealed class ScanningTask : IBackgroundTask
{
private BackgroundTaskDeferral deferral;
private WiFiScanner scanner = new WiFiScanner();
private Windows.Storage.ApplicationDataContainer localSettings;
private DispatcherTimer timer;
public async void Run(IBackgroundTaskInstance taskInstance)
{
deferral = taskInstance.GetDeferral();
taskInstance.Canceled += TaskInstance_Canceled;
await scanner.InitializeFirstAdapter();
ShowToastNotification("Hi", "Hello from background"); //notification is shown
await scanner.ScanForNetworks();
ShowToastNotification("Hi", "Hello from background1"); //this one never gets shown
deferral.Complete();
}
private void TaskInstance_Canceled(IBackgroundTaskInstance sender,
BackgroundTaskCancellationReason reason)
{
deferral.Complete();
}
private void ShowToastNotification(string title, string stringContent)
{
ToastNotifier ToastNotifier = ToastNotificationManager.CreateToastNotifier();
Windows.Data.Xml.Dom.XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
Windows.Data.Xml.Dom.XmlNodeList toastNodeList = toastXml.GetElementsByTagName("text");
toastNodeList.Item(0).AppendChild(toastXml.CreateTextNode(title));
toastNodeList.Item(1).AppendChild(toastXml.CreateTextNode(stringContent));
Windows.Data.Xml.Dom.IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
Windows.Data.Xml.Dom.XmlElement audio = toastXml.CreateElement("audio");
audio.SetAttribute("src", "ms-winsoundevent:Notification.SMS");
ToastNotification toast = new ToastNotification(toastXml);
toast.ExpirationTime = DateTime.Now.AddSeconds(10);
ToastNotifier.Show(toast);
}
}
}
WiFi适配器.cs
namespace BackgroundTaskLibrary
{
class WiFiScanner
{
//WiFi adapter instance
public WiFiAdapter WiFiAdapter { get; private set; }
public Geolocator _geolocator = new Geolocator();
public Geoposition Location { get; set; }
/// <summary>
/// Find the fisrts available WiFi adapter and initialise it
/// </summary>
/// <returns></returns>
public async Task InitializeFirstAdapter()
{
var access = await WiFiAdapter.RequestAccessAsync();
if (access != WiFiAccessStatus.Allowed)
{
throw new Exception("WiFiAccessStatus not allowed");
}
else
{
var wifiAdapterResults =
await DeviceInformation.FindAllAsync(WiFiAdapter.GetDeviceSelector());
if (wifiAdapterResults.Count >= 1)
{
this.WiFiAdapter =
await WiFiAdapter.FromIdAsync(wifiAdapterResults[0].Id);
}
else
{
var dialog = new MessageDialog("WiFi Adapter not found.");
await dialog.ShowAsync();
throw new Exception("WiFi Adapter not found.");
}
}
}
public async Task ScanForNetworks()
{
if (WiFiAdapter != null)
{
await WiFiAdapter.ScanAsync();
}
else
{
throw new Exception("No Wi-Fi adapter");
}
Location = await _geolocator.GetGeopositionAsync();
List<AccessPoint> accessPoints = new List<AccessPoint>();
foreach(var network in WiFiAdapter.NetworkReport.AvailableNetworks)
{
AccessPoint ap = new AccessPoint()
{
SSID = network.Ssid,
Mac = network.Bssid,
SignalStrength = network.NetworkRssiInDecibelMilliwatts,
Open = (int)network.SecuritySettings.NetworkAuthenticationType
};
accessPoints.Add(ap);
}
await SaveData(accessPoints);
}
public async Task SaveData(List<AccessPoint> accessPoints)
{
string info = DateTime.Now + "|" + Location.Coordinate.Point.Position.Latitude
+ "|" + Location.Coordinate.Point.Position.Longitude + "|";
for (int i = 0; i < accessPoints.Count; i++)
{
info += accessPoints[i].ToString();
}
info += Environment.NewLine;
// Get the logical root folder for all external storage devices.
StorageFolder externalDevices = Windows.Storage.KnownFolders.RemovableDevices;
// Get the first child folder, which represents the SD card.
StorageFolder sdCard = (await externalDevices.GetFoldersAsync()).FirstOrDefault();
StorageFile infoFile;
if (sdCard != null)
{
//check if info file exists
try
{
infoFile = await sdCard.GetFileAsync("wifiScanInfo.txt");
}
catch
{
infoFile = await sdCard.CreateFileAsync("wifiScanInfo.txt");
}
await FileIO.AppendTextAsync(infoFile, info);
}
}
}
}
如果您需要整个项目:https://www.dropbox.com/sh/1v9mbr3xhgr3283/AACDbB7skZUI7Z5fiu0HT8r4a?dl=0
编辑:
通过随后简化 ScanningTask,我能够确定问题出在调用“await WiFiAdapter.ScanAsync();”
我终于设法从“await WiFiAdapter.ScanAsync();”捕获了一个异常,这里是堆栈跟踪:
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at BackgroundTaskLibrary.WiFiScanner.<ScanForNetworks>d__10.MoveNext()
但是扫描已完成并且结果按预期保存在文本文件中。我可能缺少哪些权限?我已声明互联网、位置和可移动存储权限。
最佳答案
它认为异常来自在没有调用 requestAccessAsync 的情况下使用 GeoLocator :
Starting in Windows 10, call the RequestAccessAsync before accessing the user’s location. At that time, your app must be in the foreground and RequestAccessAsync must be called from the UI thread. Until the user grants your app permission to their location, your app can't access location data.
关于c# - 后台任务中的异步调用不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40606322/
Task.WaitAll 方法等待所有任务,Task.WaitAny 方法等待一个任务。如何等待任意N个任务? 用例:下载搜索结果页面,每个结果都需要一个单独的任务来下载和处理。如果我使用 WaitA
我正在查看一些像这样的遗留 C# 代码: await Task.Run(() => { _logger.LogException(LogLevel.Error, mes
如何在 Linux 中运行 cron 任务? 关注此Q&A ,我有这个 cron 任务要运行 - 只是将一些信息写入 txt 文件, // /var/www/cron.php $myfile = fo
原谅我的新手问题,但我想按顺序执行三个任务并在剧本中使用两个角色: 任务 角色 任务 角色 任务 这是我到目前为止(任务,角色,任务): --- - name: Task Role Task ho
我有一个依赖于 installDist 的自定义任务 - 不仅用于执行,还依赖于 installDist 输出: project.task('run', type: JavaExec, depends
从使用 Wix 创建的 MSI 运行卸载时,我需要在尝试删除任何文件之前强行终止在后台运行的进程。主要应用程序由一个托盘图标组成,它反射(reflect)了 bg 进程监控本地 Windows 服务的
我想编写 Ant 任务来自动执行启动服务器的任务,然后使用我的应用程序的 URL 打开 Internet Explorer。 显然我必须执行 startServer先任务,然后 startApplic
使用 ASP.NET 4.5,我正在尝试使用新的 async/await 玩具。我有一个 IDataReader 实现类,它包装了一个特定于供应商的阅读器(如 SqlDatareader)。我有一个简
使用命令 gradle tasks可以得到一份所有可用任务的报告。有什么方法可以向此命令添加参数并按任务组过滤任务。 我想发出类似 gradle tasks group:Demo 的命令筛选所有任务并
除了sshexec,还有什么办法吗?任务要做到这一点?我知道您可以使用 scp 复制文件任务。但是,我需要执行其他操作,例如检查是否存在某些文件夹,然后将其删除。我想使用类似 condition 的东
假设我有字符串 - "D:\ApEx_Schema\Functions\new.sql@@\main\ONEVIEW_Integration\3" 我需要将以下内容提取到 diff 变量中 - 文档名
我需要编写一个 ant 任务来确定某个文件是否是只读的,如果是,则失败。我想避免使用自定义选择器来为我们的构建系统的性质做这件事。任何人都有任何想法如何去做?我正在使用 ant 1.8 + ant-c
这是一个相当普遍的计算机科学问题,并不特定于任何操作系统或框架。 因此,我对与在线程池上切换任务相关的开销感到有些困惑。在许多情况下,给每个作业分配自己的特定线程是没有意义的(我们不想创建太多硬件线程
我正在使用以下 Ansible playbook 一次性关闭远程 Ubuntu 主机列表: - hosts: my_hosts become: yes remote_user: my_user
如何更改 Ant 中的当前工作目录? Ant documentation没有 任务,在我看来,最好的做法是不要更改当前工作目录。 但让我们假设我们仍然想这样做——你会如何做到这一点?谢谢! 最佳答案
是否可以运行 cronjob每三天一次?或者也许每月 10 次。 最佳答案 每三天运行一次 - 或更短时间在月底运行一次。 (如果上个月有 31 天,它将连续运行 2 天。) 0 0 */3 * *
如何在 Gradle 任务中执行托管在存储库中的工具? 在我的具体情况下,我正在使用 Gradle 构建一个 Android 应用程序。我添加了一项任务,将一些 protobuf 数据从文本编码为二进
我的项目有下一个结构: Root |- A |- C (depends on A) \- B (depends on A) 对于所有子项目,我们使用自己的插件生成资源:https://githu
我设置了一个具有4个节点的Hadoop群集,其中一个充当HDFS的NameNode以及Yarn主节点。该节点也是最强大的。 现在,我分发了2个文本文件,一个在node01(名称节点)上,一个在node
在 TFS 2010 中为多个用户存储任务的最佳方式是什么?我只能为一项任务分配一个。 (例如:当我计划向所有开发人员演示时) (这是一个 Scrum Msf 敏捷项目,其中任务是用户故事的一部分)
我是一名优秀的程序员,十分优秀!