> Thanks for the info. I suppose I was thrown off by the part in the user manual that states: "If you want a particular task to always interrupt other tasks that may be executing, give it a high priority". But now that you mention it, it does make sense that a running action won't be interfered with.
Correct. It does say interrupt 'Tasks' not 'actions' and somewhere in the guide it states that once started a action will not get interupted.. :)
>
> Here's an interesting thing, though: I managed to get things working anyway, by selecting "Continue Task" like you suggested, but then—somewhat on a hunch
Nice hunch, that is exactly how to handle it.
I believe it has something to do with the special way in which "Wait" actions are handled in terms of task scheduling.
>
Correct. A wait action will always give other tasks a chance to run. Even tasks with lower priorities will run when a Higher priority task encounters a wait action.
Interesting project.. can I ask why not just start the 'get location' action as soon as the camera app is opened I would imagine that is how the camera app does it.
I believe you will face the same challenge I found when making a app that saves pics to predesignated folders. When you quickly take several pictures in a row there is not enough time to manipulate the %FOTO variable before it is reset to the next pic.
I tried many different approaches so to hopefully save you some time this is the one I found to work the best. I never missed a pic with it. It used a camera 'APP' context.
Pic Taken On (1006)
<start>
A1: Anchor
A2: Stop [ With Error:Off Task: ] If [ %WIN !~ %Cameralabel ]
A3: Variable Set [ Name:%foto To:%FOTO Do Maths:Off Append:Off ]
A4: Variable Search Replace [ Variable:%foto Search:/ Ignore Case:On Multi-Line:On One Match Only:Off Store Matches In: Replace Matches:On Replace With: ]
A5: Wait [ MS:542 Seconds:0 Minutes:0 Hours:0 Days:0 ]
A6: Goto [ Type:Action Label Number:1 Label:start ] If [ %foto ~ %Photo ]
A7: If [ %foto !~ %Photo ]
A8: Copy File [ From:%FOTO To:%Picfilename Use Root:Off ]
A9: Variable Set [ Name:%Apicname To:%FOTO Do Maths:Off Append:Off ]
A10: Flash [ Text:Pic saved Long:Off ]
A11: End If
A12: Variable Set [ Name:%Photo To:%FOTO Do Maths:Off Append:Off ]
A13: Variable Search Replace [ Variable:%Photo Search:/ Ignore Case:On Multi-Line:On One Match Only:Off Store Matches In: Replace Matches:On Replace With: ]
A14: Goto [ Type:Action Label Number:1 Label:start ]
Let me know if you have any questions about the task.
Just a suggestion but this is how I would see the flow working.
- Camera app starts
-- get location (continue task)
-- start monitoring loop for %FOTO
-- if %FOTO changes
-- push %FOTO into a local array
-- you could check here to see if the location has changed. This would be in case you stop taking pics and leave the camera app open and change locations then start taking pics again.
-- stop loop if camera app closes
-- end for loop
-- wait until you have a location fix
-- set the location to all pics in local array ( set the geo tags)
You will want to set this collision settings to ' run together' in case you open the camera and take more pics while setting the geo tags..
Rich...
can I ask why not just start the 'get location' action as soon as the camera app is opened
> Thanks for the info and tips, Rich. It's most appreciated.
>
> The way I solved the issue you mention is kind of clunky, but actually seems to work very well. I chose to eschew %FOTO completely and instead set the profile up to do something like this:
>
> Camera app starts
> - list files in DCIM/Camera
> - write list to Photos.txt
>
> Camera app exits
> - read Photos.txt into %photolist_old array
> - list files in DCIM/Camera to %photolist_new array
> - compare %photolist_old() with %photolist_new() and save differing (new) file paths to %photos_new array
> - if %photos_new1 is set
> - get location
> - geotag new photos
but for some strange reason, %FOTO has stopped updating on my end.
Huh.. the only reason I suggested the %FOTO approach was I saw you were already using it and assumed it was working for you. As I stated the above approach worked on my device for a long time. However I wanted to make a app out of my project and there are 2 issues with using %FOTO across multiple devices.
1. %FOTO will not work if you have your camera saving the pics to your external sd card.
2. Some users have reported %FOTO not working correctly on their particular device.
So I did change my approach to something similar to what you are using. It might be a bit simpler and more reliable (if you have "a LOT" of pics in DCIM camera)
It uses a shell find command. The way it works is I write to a file called 'timestamp.txt' when the camera app opens then to retrieve all the files in 'DCIM/Camera' that have been modified since that file was accessed I use the following shell find command.
This goes in the enter task
A1: Write File [ File:timestamp.txt Text:a Append:Off Add Newline:On ]
And this goes in the exit task
A2: Run Shell [ Command:find %DCIM_path -newer /storage/sdcard0/timestamp.txt Timeout (Seconds):0 Use Root:Off Store Output In:%picpath Store Errors In: Store Result In: ]
This will give you a line feed separated list of all the files from when 'timestamp.txt' was modified to the current time.
Here is the entire exit task.
Pic Taken 2 (1119)
Run Both Together
<start>
A1: Anchor
A2: Variable Set [ Name:%ret To:
Do Maths:Off Append:Off ]
<find files>
A3: Run Shell [ Command:find %DCIM_path -newer /storage/sdcard0/timestamp.txt Timeout (Seconds):0 Use Root:Off Store Output In:%picpath Store Errors In: Store Result In: ]
A4: Variable Add [ Name:%count Value:1 Wrap Around:0 ]
A5: Goto [ Type:Action Label Number:1 Label:find files ] If [ %picpath !Set & %count < 3 ]
/// I found it necessary to to loop this 3 times to give the camera time to save the pics//
A6: Stop [ With Error:Off Task: ] If [ %picpath !Set ]
//// This will stop the task if no pics were taken /////
A7: Variable Search Replace [ Variable:%picpath Search:%ret Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In: Replace Matches:On Replace With: ]
/// remove line feeds ///
A8: Variable Split [ Name:%picpath Splitter:/ Delete Base:Off ]
A9: Variable Set [ Name:%index To:%picpath(#?*jpg*) Do Maths:Off Append:Off ]
/// %index now contains the indices of the array elements that contain just the file name ( not the path) of all files with a jpg extension. ///
A10: Variable Split [ Name:%index Splitter:, Delete Base:Off ]
A11: For [ Variable:%item Items:%index(:) ]
<copy>
A12: Copy File [ From:%DCIM_path%picpath(%item) To:%Picfilename Use Root:Off Continue Task After Error:On ]
A13: Move [ From:%DCIM_path%picpath(%item) To:%camera_path_deleted Use Root:Off ]
A14: End For
It sounds like you might want to avoid %FOTO as well :)
!>> can I ask why not just start the 'get location' action as soon as the camera app is opened
>
>
> I prefer to only fire the resource-hungry location action if there actually are new photos to geotag. Sometimes you miss and delete shots, sometimes you record videos, etc.
>
Ah, I see your point..
> The timestamp + shell method works perfectly, thank you for that! Away goes both %FOTO and bulky file lists.
Glad its working for you..
While I was posting this I came across one issue with my approach. If I take 20 pics in a row then exit the camera and immediately re-open the camera and take another pic the enter task is not allowed to run so the time stamp file is not updated. The reason for this is a bit complex but the issue is that I had 'enforce task order' selected in the profile properties. You would think this would give the enter task priority over the exit task. However it only ensures the enter task will finish before the exit task can run "In this iteration of the profile" so it has no effect if a exit task is running and the profile fires again and starts the enter task. In this case the exit task has a much higher priority. To fix the problem I put in 2 wait actions in the exit task with a condition of %TRUN~'the name of my enter task' so when the profile goes active again it will 'start' the enter task (but it will not run because the exit task has a higher priority) however now the wait action will run and this will let the enter task run. Simple aye..... :)
If you do a search of this group for "Enforce Task Order, How Exactly Does It Work " it should shed some light on it. Here is my full exit task with the changes.
Pic Taken 2 (1171)
Run Both Together
<start>
A1: Anchor
A2: Flash [ Text:%priority Long:On ]
A3: Variable Set [ Name:%camera_path_deleted To:%DCIM_path Do Maths:Off Append:Off ]
A4: Variable Set [ Name:%camera_path_deleted To:Deleted pics/ Do Maths:Off Append:On ]
A5: Variable Set [ Name:%ret To:
Do Maths:Off Append:Off ]
A6: Destroy Scene [ Name:Camera Overlay ]
<find files>
A7: Run Shell [ Command:find %DCIM_path -newer /storage/sdcard0/timestamp.txt Timeout (Seconds):0 Use Root:Off Store Output In:%picpath Store Errors In: Store Result In: ]
A8: Wait [ MS:0 Seconds:1 Minutes:0 Hours:0 Days:0 ] If [ %TRUN ~ *,pic taken on,* ]
A9: Variable Add [ Name:%count Value:1 Wrap Around:0 ]
A10: Goto [ Type:Action Label Number:1 Label:find files ] If [ %picpath !Set & %count < 3 ]
A11: Stop [ With Error:Off Task: ] If [ %picpath !Set ]
A12: Variable Search Replace [ Variable:%picpath Search:%ret Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In: Replace Matches:On Replace With: ]
A13: Variable Split [ Name:%picpath Splitter:/ Delete Base:Off ]
A14: Variable Set [ Name:%index To:%picpath(#?*jpg*) Do Maths:Off Append:Off ]
A15: Variable Split [ Name:%index Splitter:, Delete Base:Off ]
A16: For [ Variable:%item Items:%index(:) ]
A17: Wait [ MS:0 Seconds:1 Minutes:0 Hours:0 Days:0 ] If [ %TRUN ~ *,pic taken on,* ]
<copy>
A18: Copy File [ From:%DCIM_path%picpath(%item) To:%Picfilename Use Root:Off Continue Task After Error:On ]
A19: Move [ From:%DCIM_path%picpath(%item) To:%camera_path_deleted Use Root:Off ]
A20: End For
Correction...
It was a bit late when I was posting last knight..... :)
However it only ensures the enter task will finish before the exit task can run "In this iteration of the profile" so it has no effect if a exit task is running and the profile fires again and starts the enter task.
This is incorrect. If a exit task is running from a previous activation of a profile and the profile goes active again, the 'enforce task order' will not allow the new enter task to run until the exit task has finished.
So I had to de-selected the 'enforce task order' for the profile. You still need the waits in the exit task because a exit task will have a higher priority then a enter task.
Sorry for the confusion....