C# 在后台(iOS和Android)上传数据在一段时间后以一种奇怪的方式失败
我正在努力改进我们划船社区使用的应用程序。其中一部分是网站上的地图,上面有船只最近的位置。到目前为止一切正常,但我想添加一个连续的背景跟踪作为应用程序功能 该应用程序工作了一段时间,但由于超时,无法上传。这些并不是来自API的限制,在我看来,应用程序只是无法访问网络了 我所有的事情都依赖于地理位置。该插件也在Android上使用 下面是我在收到手机的位置更新后所做的事情 事件处理程序设置:C# 在后台(iOS和Android)上传数据在一段时间后以一种奇怪的方式失败,c#,xamarin,C#,Xamarin,我正在努力改进我们划船社区使用的应用程序。其中一部分是网站上的地图,上面有船只最近的位置。到目前为止一切正常,但我想添加一个连续的背景跟踪作为应用程序功能 该应用程序工作了一段时间,但由于超时,无法上传。这些并不是来自API的限制,在我看来,应用程序只是无法访问网络了 我所有的事情都依赖于地理位置。该插件也在Android上使用 下面是我在收到手机的位置更新后所做的事情 事件处理程序设置: [...] TimeSpan span = new TimeSpan(0, 20,
[...]
TimeSpan span = new TimeSpan(0, 20, 0); // Prod: 0, 30, 0
double distance = 500; // Prod: 2700
bool includeHeading = false; //don't alert on heading changes
ListenerSettings listenerSettings = new ListenerSettings
{
AllowBackgroundUpdates = true,
DeferralDistanceMeters = distance, // adjustable in app 2-10 nautical Miles
DeferLocationUpdates = true,
DeferralTime = span, // adjustable in app 15-120 Minutes
ListenForSignificantChanges = false,
PauseLocationUpdatesAutomatically = false,
ActivityType = ActivityType.OtherNavigation
};
var success = await CrossGeolocator.Current.StartListeningAsync(span,distance,includeHeading,listenerSettings);
if (success)
{
CrossGeolocator.Current.PositionChanged += async (s, e) =>
{
Console.WriteLine("\n\n -_-_-_-_-_ Position Event -_-_-_-_-_-_ \n\n");
Trackpoint trackpoint = new Trackpoint(e.Position);
Trackpoint point = await Tracking(trackpoint);
};
}
[...]
事件处理程序调用:(在应用程序开发路线图的后面,还会发生更多的事情)
将多部分/formdata上载到现有API。在4-10个事件之后,所有进一步的上载都失败,因为发生网络超时而引发一个例外。
将应用程序带回前台时,它几乎没有响应
public bool UploadTrackPoint(Trackpoint location)
{
bool success = false;
if (CanUseData())
{
string posturl = settings.BlogURL + "(THE API URL)" + "(THE API KEY)";
string agent = "User-Agent: (MY APP NAME)/" + settings.Version + " (" + DeviceInfo.Platform + ", " + DeviceInfo.VersionString + ")";
Console.WriteLine("Uploading: {0} ", Trackpoint.ConvertToString(location));
try
{
var response = MessageUpload.MultipartFormDataPost(false, posturl, agent, location.Pairs);
Console.WriteLine("HTTP response StatusCode: " + response.StatusCode + "\n Content: " + response.ResponseUri);
if (response.StatusCode == System.Net.HttpStatusCode.OK) success = true;
}
catch (Exception ex)
{
Console.WriteLine("FAILED!!! \n\n({0})\n\n", ex);
}
}
return success;
}
完全相同的行为发生在iOS(物理iPhone6)和iOS模拟器上,也发生在Android模拟器上。
然而,我读了很多关于iOS和最近的Android API的背景限制的文章,但我怀疑这是问题所在,因为它在两种平台上都是一致的。
所以我假设我在这里做错了什么,在撞墙之前填充一些缓冲区。
然而,该应用程序并没有被任何操作系统终止,我可以在控制台上看到一些-\u-\ u-\ u-\ u-\ u-\ u-\ u-\ u-\ u-\ u-\ u-
事件,上传开始失败,积压工作正在增加。
最终,在一些超时发生后,甚至位置更新也会停止
您将从何处开始进一步调试?以防有人无意中发现这一点。除了@sushingover提到的缺少背景服务之外,更大的问题是对WebResponse的错误处理
事实证明,碰壁的直觉就在这里:只读取标题,在Http调用完成后从不处理响应对象。应用程序保持所有连接打开。在10点之后(在iOS上),应用程序无法打开新连接,导致超时 您可以显示实际的http客户端调用吗?您必须在每个平台中实现本机代码。在Android上,你必须实现一个“前台化”服务(至少),在iOS上,你必须授权它进行后台更新,并启用一个CLLocationManager实例进行后台更新。Xamarin的文档(还有一个老化的演示)就是这样的:(注意:一定要查看该链接中基于平台的链接)@SushiHangover-Thnks了解这一点。我可能错了,但从我的理解来看,这正是JamesMontemagno在Android第二个插件中所涵盖的内容,我确实看到了控制台上出现的位置事件。iOS权限已设置。@Stefan它们是常规的多部分/表单数据发布:我将使用example@HinnerkWeiler哪个插件
CurrentActivityPlugin
提供了一个简单的android活动参考,他的GeolocatorPlugin
不实现后台/前台服务。。。除非你说的是你没有列出的第三个插件,或者你写的实际的前景服务代码。。。
public async Task<Trackpoint> LogPoint(Trackpoint location = null)
{
if (location == null)
{
location = await GetCoordinates(); // Call GPS if no Trackpoint is given when Tracking is done fully manual
}
if (location != null)
{
Console.WriteLine("Trackpoint Queue was: {0}", track.Count);
track.Add(location); // Add current location to end of the list (defined as private in the class)
int trackpointQueue = track.Count;
int uploadedTrackpoints = 0;
Console.WriteLine("Trackpoint Queue now: {0}", trackpointQueue);
foreach (var position in track)
{
Console.WriteLine("Uploading Trackpoint: {0} | {1} | {2}", position.Timestamp, position.Latitude, position.Longitude);
if (App.api.UploadTrackPoint(track[track.Count - 1])) // upload first trackpoint in List (ideally current) and remove it from List, repeat with more items in queue.
{
uploadedTrackpoints++;
}
else
{
Console.WriteLine("Error uploading Trackpoint trying again next time");
// Because uploading attempt failed, we don't want to try again now leave the loop until next call.
break;
}
}
track.RemoveRange(0, uploadedTrackpoints); // remove all uploaded Trackpoints from Queue
}
return location;
}
public bool UploadTrackPoint(Trackpoint location)
{
bool success = false;
if (CanUseData())
{
string posturl = settings.BlogURL + "(THE API URL)" + "(THE API KEY)";
string agent = "User-Agent: (MY APP NAME)/" + settings.Version + " (" + DeviceInfo.Platform + ", " + DeviceInfo.VersionString + ")";
Console.WriteLine("Uploading: {0} ", Trackpoint.ConvertToString(location));
try
{
var response = MessageUpload.MultipartFormDataPost(false, posturl, agent, location.Pairs);
Console.WriteLine("HTTP response StatusCode: " + response.StatusCode + "\n Content: " + response.ResponseUri);
if (response.StatusCode == System.Net.HttpStatusCode.OK) success = true;
}
catch (Exception ex)
{
Console.WriteLine("FAILED!!! \n\n({0})\n\n", ex);
}
}
return success;
}