problem updating location every 5 seconds with xamarin essentials - xamarin.forms

I have an application with xamarin essentials. This takes the information every 5 seconds with a waiting time of 3 seconds of GPS
Device.StartTimer(TimeSpan.FromMilliseconds(Timmer), () => { RunPoint(); return isRunningTimer; });
public async void RunPoint()
{ try
{
DateTime dateLanch = DateTime.Now;
var request = new GeolocationRequest(accuracy, TimeSpan.FromSeconds(TimeOutGps));
var location = await Geolocation.GetLocationAsync(request);
if (location != null)
{
point = new GPSPoint
{
Status = StatusGPS.OK,
Point = new Cerezasoft.Geo.Points.Point { Latitude = location.Latitude, Longitude = location.Longitude },
Stamp = location.Timestamp.LocalDateTime,
StampSystem = DateTime.Now,
StampLanch = dateLanch,
StampUniversal = location.Timestamp.UtcDateTime,
Speed = 0,
SpeedGPS = location.Speed.HasValue ? location.Speed.Value : 0,
Elevation = location.Altitude.HasValue ? location.Altitude.Value : 0
};
}
else
{
point.Status = StatusGPS.ErrorCalculo;
}
}
catch (FeatureNotSupportedException fnsEx)
{
point.Status = StatusGPSRallySystem.NoSensor;
point.MessageError = fnsEx.Message;
}
catch (PermissionException pEx)
{
point.Status = StatusGPS.NoAcces;
point.MessageError = pEx.Message;
}
catch (Exception ex)
{
point.Status = StatusGPS.ErrorSensor;
point.MessageError = ex.Message;
}
}
when application use with another application with gps. The capture of gps information works very well but if you execute the precision and the quality of the data, the location becomes erratic.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="true" />
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
}
I do a comparison with another app in split screen and it works fine. when my app works alone, the operating system returns the position in a different way. when my app runs by itself. the operating system returns the position more erratically.both tests are carried out in the same place with the same conditions and the same cell phone. I do not know what services and what additional elements are activating the other app for the optimal functioning of the gps
Thanks for the collaboration

"I do a comparison with another app in split screen and it works fine. when my app works alone, the operating system returns the position in a different way. when my app runs by itself. the operating system returns the position more erratically."
I am running into the exact same issue as explained above
This is my code
locator = CrossGeolocator.Current;
if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
{
locator.DesiredAccuracy = 10;
await locator.StartListeningAsync(TimeSpan.FromSeconds(15), 10, false, new Plugin.Geolocator.Abstractions.ListenerSettings()
{
AllowBackgroundUpdates = true,
ActivityType = Plugin.Geolocator.Abstractions.ActivityType.Fitness,
PauseLocationUpdatesAutomatically = false
});
locator.PositionChanged += Postion_Changed;
}
public void Postion_Changed(object sender, Plugin.Geolocator.Abstractions.PositionEventArgs e)
{
if (e.Position.Accuracy < 75)
{
LocationService.SaveGpsLocation(e.Position.Latitude, e.Position.Longitude, e.Position.Timestamp.DateTime);
}
}
When running it with another GPS app it's pinpoint accurate, but when running alone it jumps around A LOT.
"I presume the other app has done some custom "filtering", their own code, to get a more stable result. There is no "simple" answer anyone can tell you, AFAIK. Hence my links above."
This cannot be true, because that would not affect our apps at all. They are simply managing to request a much finer location which in turn helps our app somehow - we are just trying to figure out why.

I am using the Geolocation functionality of Xamarin Essentials in my app as a background service and I have the same bad coordinates accuracy problem.
If I detect the coordinates every 5-10 seconds standing still, most of them are 20-30 meters from the correct position even if the returned accuracy is 6-8 meters.
I tried to disable the "Improve Location Accuracy" option with no success.
Other apps are much more accurate under the same conditions.

Related

Google Cloud Vision crashes without exception caught

I recently encountering an annoying bug that only happen in 1 out of our 3 environments (Amazon EC2 to be specific). When I send a request to the Cloud API to receive tags about the picture. The function crashes but I don't see any exception caught by the try catch. The function works fine until June 1st but I don't know why it doesn't anymore (other 2 environments work just fine).
Here are the code:
try {
GoogleCredentials cred = GoogleCredentials.fromStream(new FileInputStream(coreConfig.googleCreds()));
log.error("GoogleCredentials cred = GoogleCredentials.fromStream(new FileInputStream(coreConfig.googleCreds()));");
ImageAnnotatorSettings imageAnnotatorSettings = ImageAnnotatorSettings.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(cred))
.build();
ImageAnnotatorClient vision = ImageAnnotatorClient.create(imageAnnotatorSettings);
log.error("ImageAnnotatorClient vision = ImageAnnotatorClient.create(imageAnnotatorSettings);");
byte[] data = IOUtils.toByteArray(is);
ByteString bs = ByteString.copyFrom(data);
// Builds the image annotation request
List<AnnotateImageRequest> requests = new ArrayList<>();
log.error("ByteString bs = ByteString.copyFrom(data);");
Image img = Image.newBuilder().setContent(bs).build();
log.error(" Image img = Image.newBuilder().setContent(bs).build();");
Feature feat = Feature.newBuilder().setType(Type.LABEL_DETECTION).build();
log.error("Feature feat = Feature.newBuilder().setType(Type.LABEL_DETECTION).build();");
AnnotateImageRequest request = AnnotateImageRequest.newBuilder()
.addFeatures(feat)
.setImage(img)
.build();
requests.add(request);
log.error("requests.add(request);");
// Performs label detection on the image file
BatchAnnotateImagesResponse response = vision.batchAnnotateImages(requests);
log.error("BatchAnnotateImagesResponse response = vision.batchAnnotateImages(requests);");
List<AnnotateImageResponse> responses = response.getResponsesList();
log.error("List<AnnotateImageResponse> responses = response.getResponsesList();");
for (AnnotateImageResponse res : responses) {
if (res.hasError()) {
throw new ServiceException(ServiceStatus.BAD_REQUEST, res.getError().getMessage());
}
for (EntityAnnotation annotation : res.getLabelAnnotationsList()) {
tags.append("===" + annotation.getDescription().replaceAll("\\s+",""));
log.error("tags.append(\"===\" + annotation.getDescription().replaceAll(\"\\\\s+\",\"\"));");
}
}
return tags;
}catch(Exception e) {
e.printStackTrace();
log.error(e.getMessage());
return null;
// throw new ServiceException(ServiceStatus.BAD_REQUEST, e.getMessage());
}
Here are the details about it:
It seems like an old version of guava (in this case 17.0-jdk) caused this crash.
You still have to remove the old version not only from the pom.xml but also in the lib folder of the .war file.

Android: ASyncTask's behavior contrary to documentation

First time writing an AsyncTask and I seem to have a subtle design flaw that prevents both ProgressDialog, ProgressBar, and even Log.d() from working properly. I suspect that somehow I am not actually creating a new thread/task.
Short: the symptoms
A ProgressDialog is created in the constructor, and the code orders Android to show it in onPreExecute(), but the dialog never shows.
onProgressUpdate() is supposed to execute whenever I call publishProgress() from within doInBackground(), correct? Well, it doesn't. Instead, it executes when doInBackground() completes.
Long: investigations
Things I have verified through the emulator and, when possible, on a phone:
onPreExecute() is definitely called
the progress bar is not reset until after doInBackground() completes
update_dialog.show() is definitely executed, but the dialog does not appear unless I remove the .dismiss() in onPostExecute(); I imagine dialog is, like the progress bar, not shown until after doInBackground() completes, but is naturally immediately dismissed
the code will happily show dialogs when no computation is involved
doInBackground() definitely invokes publishProgress()
when it does, onProgressUpdate() does not execute immediately! that is, I have a breakpoint in the function, and the debugger does not stop there until after doInBackground() completes! (perhaps this is a phenomenon of the debugger, rather than doInBackground(), but I observe the same symptoms on a mobile device)
the progress bar gets updated... only after doInBackground() completes everything
similarly, the Log.d() data shows up in Android Monitor only after doInBackground() completes everything
and of course the dialog does not show up either in the emulator or on a device (unless I remove .dismiss() from onPostExecute())
Can anyone help find the problem? Ideally I'd like a working dialog, but as Android has deprecated that anyway I'd be fine with a working progress bar.
Code
Here are the essentials, less the details of computation &c.:
Where I call the AsyncTask from the main thread:
if (searching) { // this block does get executed!
Compute_Task my_task = new Compute_Task(overall_context, count);
my_task.execute(field, count, max_x, max_y);
try { result = my_task.get(); } catch (Exception e) { }
}
The AsyncTask itself:
private class Compute_Task extends AsyncTask<Object, Integer, Integer> {
public Compute_Task(Context context, int count) {
super();
current_positions = 0;
update_dialog = new ProgressDialog(context);
update_dialog.setIndeterminate(true);
update_dialog.setCancelable(false);
update_dialog.setTitle("Thinking");
update_dialog.setMessage("Please wait");
}
protected void onPreExecute() {
super.onPreExecute();
update_dialog.show();
ProgressBar pb = ((ProgressBar) ((Activity) overall_context).findViewById(R.id.progress_bar));
pb.setMax(base_count);
pb.setProgress(0);
}
protected void onPostExecute() {
super.onPostExecute();
update_dialog.dismiss();
}
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
ProgressBar pb = ((ProgressBar) ((Activity) overall_context).findViewById(R.id.progress_bar));
pb.setMax(base_count);
pb.incrementProgressBy(1);
Log.d(tag, values[0].toString());
}
protected Integer doInBackground(Object... params) {
Integer result = compute_scores(
(boolean[][]) params[0], (Integer) params[1], (Integer) params[2], (Integer) params[3], 0)
);
return result;
}
public int compute_scores(boolean[][] field, int count, int max_x, int max_y, int level) {
int result, completed = 0;
switch(count) {
// LOTS of computation goes on here,
// including a recursive call where all params are modified
if (level == 0)
publishProgress(++completed);
}
}
ProgressDialog update_dialog;
}
Turns out this is basically the same issue as the one given here. The "fatal" line is this one:
try { result = my_task.get(); } catch (Exception e) { }
Apparently this puts the UI thread into deep sleep. One should not use get() with an AsyncTask unless one is willing to suspend the UI thread. We have to perform a little magic in onPostExecute() instead.
Although it turns out that this was a duplicate, I didn't find it until after I wrote it, because I didn't realize the thread was blocking.

CodenameOne filter optimization on set of containers

In my app, I have a searchbox which allows users to filter as they type. For some reason I can't get an InfinteProgress to properly display while the filtering is being executed.
Here's my code:
Pass 1
public void renderForumList(){
try{
magnify = mStateMachine.findForumSearchIcon(form);
}catch(NullPointerException ex){
System.out.println("User typed additional character in search term before previous term finished executing");
}
InfiniteProgress infi = new InfiniteProgress();
magnify.getParent().replace(magnify, infi, null);
Display.getInstance().invokeAndBlock(new Runnable() {
#Override
public void run() {
for (int i = 0;i < containerStates.length;i++){
if(containerStates[i] != listItems[i].isVisible()){
listItems[i].setHidden(!containerStates[i]);
listItems[i].setVisible(containerStates[i]);
}
}
Display.getInstance().callSerially(new Runnable() {
#Override
public void run() {
mStateMachine.findForumsListComponent(form).animateLayout(200);
mStateMachine.findContainer2(form).replace(infi, magnify, null);
}
});
}
});
}
In this version, the infinite progress shows up in the proper position, but it doesn't spin.
Pass 2
public void renderForumList(){
try{
magnify = mStateMachine.findForumSearchIcon(form);
}catch(NullPointerException ex){
System.out.println("User typed additional character in search term before previous term finished executing");
}
InfiniteProgress infi = new InfiniteProgress();
magnify.getParent().replace(magnify, infi, null);
for (int i = 0;i < containerStates.length;i++){
if(containerStates[i] != listItems[i].isVisible()){
listItems[i].setHidden(!containerStates[i]);
listItems[i].setVisible(containerStates[i]);
}
}
mStateMachine.findForumsListComponent(form).animateLayout(200);
mStateMachine.findContainer2(form).replace(infi, magnify, null);
}
}
}
In this version, the magnifier icon just flashes briefly, but the InfiniteProgress spinner is never visible.
I get the same results on the simulator and on an Android device.
How can I get the InfiniteProgress to spin while the search is taking place?
invokeAndBlock opens a new thread and thus violates the EDT as you access UI components on a separate thread.
Try using callSerially instead to postpone the following code into the next EDT cycle although I'm not sure that will help as everything is still happening on the EDT.
Alternatively I'm guessing the method isVisible takes time, so you can enclose that call alone in invokeAndBlock.
To understand invokeAndBlock check out the developer guide https://www.codenameone.com/manual/edt.html

Flex Mobile 4.6 StageVideo not removing from stage

When I instantiate a new StageVideo instsance with stage.stageVideos[0] everything works great, but when i leave my view that's displaying the video it sticks on the stage. So when i goto another view it's still showing on the stage in the background. I tried setting sv = null, removing event listeners...etc.
I've created a StageVideoDisplay class which is instantiated in mxml like: and on view initialization i call a play() method:
if ( _path )
{
//...
// Connections
_nc = new NetConnection();
_nc.connect(null);
_ns = new NetStream(_nc);
_ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
_ns.client = this;
// Screen
_video = new Video();
_video.smoothing = true;
// Video Events
// the StageVideoEvent.STAGE_VIDEO_STATE informs you whether
// StageVideo is available
stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY,
onStageVideoState);
// in case of fallback to Video, listen to the VideoEvent.RENDER_STATE
// event to handle resize properly and know about the acceleration mode running
_video.addEventListener(VideoEvent.RENDER_STATE, videoStateChange);
//...
}
On video stage event:
if ( stageVideoInUse ) {
try {
_rc = new Rectangle(0,0,this.width,this.height);
_sv.viewPort = _rc;
} catch (e:Error) {}
} else {
try {
_video.width = this.width;
_video.height = this.height;
} catch (e:Error) {}
}
And on stage video availability event:
protected function toggleStageVideo(on:Boolean):void
{
// To choose StageVideo attach the NetStream to StageVideo
if (on)
{
stageVideoInUse = true;
if ( _sv == null )
{
try {
_sv = stage.stageVideos[0];
_sv.addEventListener(StageVideoEvent.RENDER_STATE, stageVideoStateChange);
_sv.attachNetStream(_ns);
_sv.depth = 1;
} catch (e:Error) {}
}
if (classicVideoInUse)
{
// If you use StageVideo, remove from the display list the
// Video object to avoid covering the StageVideo object
// (which is always in the background)
stage.removeChild ( _video );
classicVideoInUse = false;
}
} else
{
// Otherwise attach it to a Video object
if (stageVideoInUse)
stageVideoInUse = false;
classicVideoInUse = true;
try {
_video.attachNetStream(_ns);
stage.addChildAt(_video, 0);
} catch (e:Error) {}
}
if ( !played )
{
played = true;
_ns.play(path);
}
}
What happens is in the view when i navigator.popView(), the stageVideo remains on the stage, even in other views, and when returning to that view to play a different stream the same stream is kind of "burned" on top. I can not figure out a way to get rid of it! Thanks in advance!
In Flash Player 11, Adobe added the dispose() method to the NetStream class.
This is useful to clear the Video or StageVideo object when you're done with it.
When you call the dispose() method at runtime, you may get an exception indicating that there is no property named dispose on the NetStream object.
This occurs because Flash Builder is not compiling the app with the proper SWF version. To fix that, just add this to your compiler directives:
-swf-version=13
In the new Flash Builder 4.7, we hopefully won't have to specify the SWF version to use the newer Flash Player features.
This seems to be the best solution, but if you can't use Flash 11 (or the latest Adobe AIR), some other work arounds would be:
set the viewPort of stage video object to a rectangle that has width=0 and height=0
since stage video appears underneath your app, you can always cover the viewport (with a background color or some DisplayObject)
Ok the issue was actually that, even though it seemed like stage video was in use since i got the "Accelerated" message in status, that it was actually the video render even running and classic video was actually in use. The only thing I needed to do was add stage.removeChild( _video ) to the close() event in the class!!

How to cancel 'seeking' state of Flex3 VideoDisplay class

I have a VideoDisplay instance playing some video. When I click on the video slider (also my component) the property videoDisplay.playheadTime is set and the videoDisplay.state goes from 'playing' into a 'seeking' state for a brief moment (the videoDisplay seeks for a new position and then plays the video again). Intended bevaiour.
But if I'm (or any random user) fast enough, I can set the playheadTime again while the player is still in 'seeking' state. When repeated several times every click is enqueued and the videoDisplay jump on every place of the video I have clicked(this is happening in an interval about 10-15 second after my last click). When I use live dragging the videoDisplay, overwhelmed by seekings, goes into 'error' state.
My question is - is there any way to cancel seeking state of the VideoDisplay class? For example player is in 'seeking' state, I set playheadTime, and the player forgets about last seeking and try to find the new place of the video.
I will downvote pointless answers like 'Use the Flex4 VideoPlayer class'!
One possible way is wrap the video display in a component and manage the seek a little better yourself. So if someone calls seek, make sure that the video is not currently seeking, if so, then wait till the current operation is complete before proceeding to the new one. If the user tries to seek again, discard all currently pending operations and make the latest one the next operation. Working on this exact problem right now.... Here's the code:
public function Seek(nSeconds:Number, bPlayAfter:Boolean):void
{
trace("Player Seek: "+ nSeconds);
var objSeekComand:VideoPlayerSeekCommand = new VideoPlayerSeekCommand(ucPlayer, nSeconds, bPlayAfter);
ProcessCommand(objSeekComand);
}
protected function ProcessCommand(objCommand:ICommand):void
{
if(_objCurrentCommand != null)
{
_objCurrentCommand.Abort();
}
_objCurrentCommand = objCommand
objCommand.SignalCommandComplete.add(OnCommandComplete);
objCommand.Execute();
}
Here's the Command
public class VideoPlayerSeekCommand extends CommandBase
{
private var _ucVideoDisplay:VideoDisplay;
private var _nSeekPoint:Number;
private var _bPlayAfterSeek:Boolean;
private var _bIsExecuting:Boolean;
public function VideoPlayerSeekCommand(ucVideoDisplay:VideoDisplay, nSeekPointInSeconds:Number, bPlayAfterSeek:Boolean, fAutoAttachSignalHandler:Function = null)
{
_ucVideoDisplay = ucVideoDisplay;
_nSeekPoint = nSeekPointInSeconds;
_bPlayAfterSeek = bPlayAfterSeek;
super(fAutoAttachSignalHandler);
}
override public function Execute():void
{
//First check if we are playing, and puase if needed
_bIsExecuting = true;
if(_ucVideoDisplay.playing == true)
{
_ucVideoDisplay.addEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, OnPlayerStateChangedFromPlay, false, 0, true);
_ucVideoDisplay.pause();
}
else
{
DoSeek();
}
}
protected function OnPlayerStateChangedFromPlay(event:MediaPlayerStateChangeEvent):void
{
_ucVideoDisplay.removeEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, OnPlayerStateChangedFromPlay);
if(_bIsExecuting == true)
{
if(_ucVideoDisplay.playing == false)
{
DoSeek();
}
else
{
throw new Error("VideoPlayerSeekAndPlayCommand - OnPlayerStateChangedFromPlay error");
}
}
}
private function DoSeek():void
{
if(_bIsExecuting == true)
{
_ucVideoDisplay.seek(_nSeekPoint);
CheckSeekComplete();
}
}
private function CheckSeekComplete():void
{
if(_bIsExecuting == true)
{
if (Math.abs( _ucVideoDisplay.currentTime - _nSeekPoint) < 2)
{
if(_bPlayAfterSeek == true)
{
_ucVideoDisplay.play();
}
DispatchAndDestroy();
}
else
{
CoreUtils.CallLater(CheckSeekComplete, .07);
}
}
}
override public function Abort():void
{
_bIsExecuting = false;
SignalCommandComplete.removeAll();
}
}
Im Using AS3 Signals here instead of events, and the CoreUtils.Call later you can use setInterval, or a Timer. But the idea is to not call seek until the video is paused, and to keep track of when the seek is complete.

Resources