I am using the following code to request current location:
private void RequestCurrentLocation()
{
Criteria locationCriteria = new Criteria () { Accuracy = Accuracy.NoRequirement, PowerRequirement = Power.NoRequirement };
this.mgr = GetSystemService (Context.LocationService) as LocationManager;
String locationProvider = this.mgr.GetBestProvider (locationCriteria, true);
this.mgr.RequestLocationUpdates (locationProvider, 0, 0, this);
}
As I need location only once, so I call RemoveUpdates() as soon as OnLocationChanged is raised and then carry on with rest of the working:
public void OnLocationChanged (Location location)
{
this.mgr.RemoveUpdates (this);
//Rest of the method
}
I face two issues:
1) Although I have provided zero in the distance and time parameters of RequestLocationUpdates but it still needs at least 2-3 seconds before the OnLocationChanged is triggered. How can I make it instantaneous?
2) I intermittently face the issue that the OnLocationChanged event does not fire at all. Yesterday I spent the whole day to get my code working which was flawlessly working a day earlier. It's really strange that something works properly one day and the next day it simply stops even with the very same source code! Can somebody give me an idea?
Thanks.
There's no way to get an accurate, up-to-date location instantly.
For a device to determine location it needs to track GPS, WiFi, 3G towers and that depends on radio signal strength, transmission speed and other little stuff like that. You can trick the parameters of your request to try to have a faster update (for example, instead of best provider, try to use any provider available).
As a alternative approach you can request to getLastKnownLocation, this method is synchronous and replies instantly with the last location that the system found. The issue is that the "last known location" might be null (if the system never found any location), or might be very old (if the last location was days ago).
Related
I am currently on an adventure with my sanity at stake where I try to simply play an mp3 file on my web-application. This mp3 is loaded chunk-wise in order to make the experience more responsive.
Even though the documentation of the MediaSource API is just remarkably, almost violently, useful and hundreds of well explained examples pave the way towards salvation, I find myself not able to make everything work properly.
The last issue I am facing is the seeking-functionality. The simple idea I had for this feature is to simply kill everything that's alive, burn everything down and revive again. To be more precise, if the user seeks, I stop the machinery and start playing everything from scratch, but with the desired offset (in seconds).
Everything is working so far except one last thing: currentTime, gets set to a different value after I have set it to the time that the user requested.
The track continues playing as expected but the problem is that currentTime is what's being used to visualize the current location within the track for the user.
This is how the events take place before and after the user seeks
[play-click] <--- User clicks play button
:
[timeupdate] currentTime: 00.01
[timeupdate] currentTime: 00.02
[timeupdate] currentTime: 00.03
[seek-click] <--- User seeks, stop() is called and then playFrom(seconds)
[loadstart] currentTime: 33.33 # This is the (correct) time set in playFrom(seconds)
[loadmetadata] currentTime: 10.12 # Now the time gets set to this (wrong) value
[seek] currentTime: 10.12 # The triggered seek event comes in
[seeked] currentTime: 10.12
[canplay] currentTime: 10.12
[playing] currentTime: 10.12
[timeupdate] currentTime: 10.13 # Track continues to play correctly but this value is still wrong
:
This is how seeking takes place:
public play(track: Track) {
this.track = track;
this.playFrom(0);
}
public seekTo(seconds: number) {
this.stop();
this.playFrom(seconds);
}
public stop() {
this.logger.debug('Stop ..');
this.sourceBuffer.abort();
this.audioObj.pause();
this.removeEvents(this.audioObj, this.audioEvents, this.audioEventsHandler);
this.audioObj = null;
this.sourceBuffer = null;
this.mediaSource = null;
}
Now, the playFrom(seconds) method is a bit more complicated than that but all it really does is re-create everything that I just destroyed:
private playFrom(seconds: number) {
this.logger.debug(`Start playing from ${seconds.toFixed(2)} seconds`)
// [:] (collapsed some less important code here)
// Create the media source object
this.mediaSource = new MediaSource();
this.mediaSource.addEventListener('sourceopen', this.onSourceOpen);
// Create audio element
this.audioObj = document.createElement('audio');
this.audioObj.src = URL.createObjectURL(this.mediaSource);
this.audioObj.currentTime = seconds;
this.addEvents(this.audioObj, this.audioEvents, this.audioEventsHandler);
this.logger.debug(`Object-url: ${this.audioObj.src}`);
this.state = {currentTime: seconds, playing: true};
}
How can I get the correct current-time here?
I tried another idea where I was tring to create and add a new SourceBuffer to the MediaSource and let it play the audio from there but I wasn't able to do that either.
What is the duration reported by the MediaSource (or by the media element) at the time of issuing the seek to the media element? If it is infinite, you may need to use the {set,clear}LiveSeekableRange APIs in MSE to let the implementation know if you wish to let the player seek beyond the currently buffered media's highest presentation end time. Alternatively, you could possibly set the MediaSource duration before seeking to be something finite, but at least as high as the highest currently buffered media presentation end time.
I have successfully implemented the tutorial:
http://developer.android.com/reference/android/support/v4/view/ViewPager.html, as a Tab'ed viewpager activity with fragments on each tab. Each Fragment maintains various UI TextFields etc and everything is working fine with the exception of getActivity(), which returns null when called from any of the fragments.
UPDATE: Read this, then please see my own answer below that broadens the scope regarding the cause of this error. Continued:
BUT, the null status appears after a while. Initially, in fragment.onStart(), the getActivity() is working so that the default UI setup may be performed. But the first time the user has made changes, getActivity() already returns null.
Strange to say, in the same moment, it is still possible to make any change to the fragment UI fields from the Activity, which means that as the context=activity is passed to the fragment in a setSomeText(this, ...), this will enable the fragment to make the corresponding changes. Of course, the design should be such that the Fragment takes care of it's own detailed task.
It does not help to save the context in the onStart(), because that reference will point to a null after a while.
It is explicitely stated in the tutorial that the feature is in early development, but as this "null" problem has become quite a timethief here, and as I see that "getActivity returns null" is a very common problem, I wanted to muse aloud whether there could be a bug in the getActivity() when combined with ViewPager and/or Tab?
What took me so long to detect the problem was that it is hard to guess that a fragment would EVER loose knowledge of its activity. Anyway, I am on the next hurdle and just wanted to share this finding: Don't trust getActivity(), but pass on context from Activity to its Fragments as a parameter in the set/get methods or other api.
This is not an answer, but I needed the space to explain and I am circeling in the problem:
It seems there is more general problem than just getActivity(). Because variable declarations of the fragments are also "vanishing" to null. A new instance of the fragment has "taken over". This happens when current tab is shifted more than one tab to either side.
EXAMPLE: I define 5 tabs. I have a tab 2 that can be manipulated from UI. After a change of 2 content, I move between tabs, either with tab click or fingersweep. Either way.
RESULTS? As long as I visit the next tab on left or right side, and then move back, the changed data are still there on tab 2. As soon as I move two or more tabs away from tab 2 and then return, the fragment instance of tab 2 is always reset. Does not matter how many tabs are present. Whether I hit last or first tab during this process is not significant. The code? it is the same as in the referenced tutorial, and in addition:
//add tabs (notice the once only saving of the fragment into profileViewer)
mTabsAdapter.addTab(actionBar.newTab()
//.setText(R.string.action_favorite)
.setIcon(R.drawable.ic_action_favorite),
TabFragmentDemo.class, null);
mTabsAdapter.addTab(actionBar.newTab()
//.setText(R.string.new_profile)
.setIcon(R.drawable.ic_action_add_person),
ProfileViewer.class, null);
profileViewer = (ProfileViewer) mTabsAdapter.getItem(NEW_PROFILE);
mTabsAdapter.addTab(actionBar.newTab()
//.setText(R.string.action_select)
.setIcon(R.drawable.ic_action_view_as_list),
TabFragmentDemo.class, null);
mTabsAdapter.addTab(actionBar.newTab()
//.setText(R.string.action_select)
.setIcon(R.drawable.ic_action_view_as_list),
TabFragmentDemo.class, null);
mTabsAdapter.addTab(actionBar.newTab()
//.setText(R.string.action_select)
.setIcon(R.drawable.ic_action_view_as_list),
TabFragmentDemo.class, null);
Then a simple dialogFragment selecting a date and then this date is set (Does not help to omit the datepicker and just set a date directly)
public void showDatePickerDialog(View v) {
dateOfBirthPicker = new DateOfBirthPicker();
dateOfBirthPicker.show(fragmentManager, datePickerTag);
}
//the callback from datepicker:
#Override
public void onDateSet(DatePicker view, int year, int month, int day) {
//update the fragment
profileViewer.setCardFromDate (this, day, month, year);
Notice that "this" is passed on as forced context to the fragment. The big question here is why the tab looses its original fragment as long as there is nothing in my code requesting that ?
What is the difference between getCurrentPosition() and watchPosition(). I read several articles about getCurrentPosition() and watchPosition(). But none of was clear to me. As far as I'm understand getCurrentPosition() update location only one time But watchPosition() continuously update location. I'm I right??
getCurrentPosition() gives currentPosition latitude and longtitude values,which fires only once. Where as watchPosition() gives currentPosition latitude and longtitude values continuously. If position changed(assume you are in a moving vehicle,then watchPosition() will give result.Then you will come to know the result of this )
You are correct. The getCurrentPosition() callback is fired once and watchPosition() callback is fired continuously. Good reading on this here.
watchPosition fired each time your device position changes (with interval specified in fn params). getCurrentPostion only once.
watchPosition actually analogue of setInterval fn and also returns id that can be used to stop iterative process by using clearWatch.
I have just been trying to fix a few memory leaks in my project and have discovered an interesting problem. It seems like a vast majority of my 'Point' objects are not being picked up by the Garbage Collector. Each frame it creates about 5000 new Point objects and less than 10% of them seem to ever get picked up. Even when you use code like this:
var tempPoint :Point = new Point();
tempPoint = null;
Even if I repeat it over 500 times, only a tiny fraction seem to be erased. This is really stating to get on my nerves now and I was wondering if anyone has encountered this before, knows how to solve it / get around it, or cares to enlighten me on what exactly I am doing wrong.
Would love to know anyone's thoughts on this
ps. I am using The Miner to check the resource usage
Edit: Have now done a quick check where I had the program running for about an hour and although the memory usage went up about 140MB it did start garbage collecting at this point and did not go past that. So they will be picked up but not until you have several million created ;)
How long are you waiting for them to be erased?
If you are creating 5000 new objects per frame, it's probably a good idea to use an object pool.
class PointPool {
private var _points:Vector.<Point>;
public function PointPool() {
_points = new Vector.<Point>();
}
public function createPoint(x:Number, y:Number):Point {
var p:Point = null;
if( _points.length > 0 )
p = _points.pop();
else
p = new Point();
p.x = x;
p.y = y;
return p;
}
public function returnPoint(point:Point):void {
_points.push(point);
}
}
Just a thought :)
I will quote Grant Skinner to answer your question:
A very important thing to understand about the Garbage Collector in FP9 is that it’s operations are deferred. Your objects will not be removed immediately when all active references are deleted, instead they will be removed at some indeterminate time in the future (from a developer standpoint).
[...]
It’s very important to remember that you have no control over when your objects will be deallocated, so you must make them as inert as possible when you are finished with them.
So, what's happened with your code? FP created something near 5000 instances of Point. If you look the memory usage over time you may notice that it will drop to the initial value after a few seconds.
The best way to avoid this behaviour is to pool the created objects and reuse them instead of creating a new one.
I'm doing a little research on possible application of EWS in our existing project which is written with heavy use of MAPI and I found out something disturbing about performance of LoadPropertiesForItems() method.
Consider such scenario:
we have 10000 (ten thousands) messages in Inbox folder
we want to get approximately 30 properties of every message to see if they satisfy our conditions for further processing
messages are retrieved from server in packs of 100 messages
So, code looks like this:
ItemView itemsView = new ItemView(100);
PropertySet properties = new PropertySet();
properties.Add(EmailMessageSchema.From);
/*
add all necessary properties...
*/
properties.Add(EmailMessageSchema.Sensitivity);
FindItemsResults<Item> findResults;
List<EmailMessage> list = new List<EmailMessage>();
do
{
findResults = folder.FindItems(itemsView);
_service.LoadPropertiesForItems(findResults, properties);
foreach (Item it in findResults)
{
... do something with every items
}
if (findResults.NextPageOffset.HasValue)
{
itemsView.Offset = findResults.NextPageOffset.Value;
}
}while(findResults.MoreAvailable);
And the problem is that every increment of itemsView.Offset property makes LoadPropertiesForItems method longer to execute. For first couple of iterations it is not very noticeable but around 30th time loop makes that call time increases from under 1 second to 8 or more seconds. And memory allocation hits physical limits causing out of memory exception.
I'm pretty sure that my problems are "offset related" because I changed a code a little to that:
itemsView = new ItemView(100, offset, OffsetBasePoint.Beginning);
...rest of loop
if (findResults.NextPageOffset.HasValue)
{
offset = findResults.NextPageOffset.Value;
}
and I manipulated offset variable (declared outside of loop) in that way that I set its value on 4500 at start and than in debug mode after first iteration I changed its value to 100. And according to my suspicions first call of LoadPropertiesForItems took veeeery long to execute and second call (with offset = 100) was very quick.
Can anyone confirm that and maybe propose some solution for that?
Of course I can do my work without using an offset but why should I? :)
Changing the offset is expensive because the server has to iterate through the items from the beginning -- it isn't possible to have an ordinal index for messages because new messages can be inserted into the view in any order (think of a view over name or subject).
Paging through all the items once is the best approach.