Save Pictures To Different Folder / Camera Click Context

875 views
Skip to first unread message

Richard Davis

unread,
Dec 12, 2012, 9:45:15 PM12/12/12
to tas...@googlegroups.com

If you search the group you will find this has this been asked several times and a few work around have been developed.  I have made a camera folders/browser app (App factory) and along the way have tried most of them. So i thought I would post this for others and hopefully get some input...

The one I found to work the best was to use the 'file modified' context  on DCIM/CAMERA.  And then get the picture path from %FOTO. There have been reports in the past of the 'file modified ' context  not working correctly on some devices but I found it to work every time on my device and 4 others (that's with a whole lot of testing).

However I hit a road block when I found out that one of the newer devices now saves its pictures on DCIM/100MEDIA.  Not being able to use a variable in the 'file modified' context I now needed another work around. In addition with this method I was not able to have the user be able switch there camera path setting from internal to external memory ( again because of the 'no variable' restriction.

So I came up the the following profile and so far it seems to be working perfectly,  however I have never used such a closed loop in tasker before and was hoping for some input from others as to any problems that might arise or suggestions. I set the priority high with the thinking that the only time this will be running is when the camera is on and I really do not think I need or want any other tasker tasks running at that time. I think there would be a remote chance of missing a picture if another task was running and I took a few pictures rapidly. In addition this is really just for the app where there will not be any other (unscheduled ) tasks competing .  

Please post any comments or suggestions...

Thanks,    Rich

I could not find any way to use %FOTO in a context so I put it in a task and basically set %FOTO to a variable (%Photo )then do a continuous loop checking to see if %FOTO has changed by setting it to another variable (%foto) then checking for %Photo !~ %foto.   I needed to remove all of the '/' symbols from both variables in order to perform the match..

Profile: Photo (363)
Priority: 8 CoolDown: 0
State: Variable Value [ Name:%WIN Op:Matches Value:%Cameralabel ]
Enter: Photo (365)
<start>
A1: Anchor // start
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: ]

// this removes all of the '/' from the variable to allow matching //


A5: Wait [ MS:542 Seconds:0 Minutes:0 Hours:0 Days:0 ]

// The profile works without this wait but it thought it was a good idea???  //

A6: Goto [ Type:Action Label Number:1 Label:start ] If [ %foto ~ %Photo ]

// It will stay in this loop until the %FOTO has changed or the %WIN value changes //

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 X  [ Text: Pic saved ]
A11: End If
A12: Variable Set [ Name:%Photo To:%FOTO Do Maths:Off Append:Off ]
A13:
A14:
A15: Variable Search Replace [ Variable:%Photo Search:/ Ignore Case:On Multi-Line:On One Match Only:Off Store Matches In: Replace Matches:On Replace With: ]

// Again remove all '/'   //

A16: Goto [ Type:Action Label Number:1 Label:start ]


Darijo Gospić

unread,
May 3, 2015, 10:20:54 AM5/3/15
to tas...@googlegroups.com
I've modified this profile a little bit..
I've inserted a new action at A8, so now a new
A8 processes some variables and "prepares" the new pic name (I check time and date of latest pic, so it looks like this: Taken at 12:55, New York, 05.03.2015),
and then
A9 copies from %FOTO to: Pictures/Photos/%Last_Pic_name.jpg

Everything else is the same.
But the profile stopped working. I've been reading here for a whole day, but I just can't figure it..
Any ideas?

Rich D

unread,
May 3, 2015, 10:05:18 PM5/3/15
to Tasker Google Groups Post


> Everything else is the same.
> But the profile stopped working. I've been reading here for a whole day, but I just can't figure it..

Did it work at all after the changes?

Could you post the exported profile description of your changes?

To post your profile or task here...  Long press on the profile or task name / ( 3 dot menu with 4.0+ ) export / export "DESCRIPTION" to clipboard (not XML)

Any linked tasks will be exported with the profile they are linked to..

To be able to export, The beginner mode needs to be off and the profile needs to be named by you (Not the Tasker listed name.  Tasker will list your profile with the context name if you have not given it one).

Rich D

unread,
May 3, 2015, 10:48:35 PM5/3/15
to Tasker Google Groups Post


so it looks like this: Taken at 12:55, New York, 05.03.2015),

The symbols
: , .

Are not valid for file names.   

Darijo Gospić

unread,
May 4, 2015, 11:10:23 AM5/4/15
to tas...@googlegroups.com
<TaskerData sr="" dvi="1" tv="4.7b1m">
<Profile sr="prof4" ve="2">
<cdate>1430559500045</cdate>
<edate>1430751986895</edate>
<id>4</id>
<limit>true</limit>
<mid0>5</mid0>
<mid1>6</mid1>
<nme>Photo Taken Modified</nme>
<State sr="con0" ve="2">
<code>9039</code>
<Bundle sr="arg0">
<Vals sr="val">
<com.kanetik.active_app_condition.extra.BOOLEAN_App_STATE>true</com.kanetik.active_app_condition.extra.BOOLEAN_App_STATE>
<com.kanetik.active_app_condition.extra.BOOLEAN_App_STATE-type>java.lang.Boolean</com.kanetik.active_app_condition.extra.BOOLEAN_App_STATE-type>
<com.kanetik.active_app_condition.extra.BOOLEAN_INCLUDE_PERCEPTIBLE>false</com.kanetik.active_app_condition.extra.BOOLEAN_INCLUDE_PERCEPTIBLE>
<com.kanetik.active_app_condition.extra.BOOLEAN_INCLUDE_PERCEPTIBLE-type>java.lang.Boolean</com.kanetik.active_app_condition.extra.BOOLEAN_INCLUDE_PERCEPTIBLE-type>
<com.kanetik.active_app_condition.extra.INT_VERSION_CODE>2220</com.kanetik.active_app_condition.extra.INT_VERSION_CODE>
<com.kanetik.active_app_condition.extra.INT_VERSION_CODE-type>java.lang.Integer</com.kanetik.active_app_condition.extra.INT_VERSION_CODE-type>
<com.kanetik.active_app_condition.extra.STRING_PACKAGE_NAME>com.google.android.GoogleCamera</com.kanetik.active_app_condition.extra.STRING_PACKAGE_NAME>
<com.kanetik.active_app_condition.extra.STRING_PACKAGE_NAME-type>java.lang.String</com.kanetik.active_app_condition.extra.STRING_PACKAGE_NAME-type>
<com.kanetik.active_app_condition.extra.UUID_PROFILE_ID>95d481a4-f054-428c-b141-242a2dbcf29e</com.kanetik.active_app_condition.extra.UUID_PROFILE_ID>
<com.kanetik.active_app_condition.extra.UUID_PROFILE_ID-type>java.lang.String</com.kanetik.active_app_condition.extra.UUID_PROFILE_ID-type>
<com.twofortyfouram.locale.intent.extra.BLURB>Camera: Foreground</com.twofortyfouram.locale.intent.extra.BLURB>
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">com.kanetik.active_app_condition</Str>
<Str sr="arg2" ve="3">App Detection</Str>
</State>
</Profile>
<Task sr="task5">
<cdate>1430559503246</cdate>
<edate>1430751958249</edate>
<id>5</id>
<pri>10</pri>
<Action sr="act0" ve="7">
<code>300</code>
<label>start</label>
</Action>
<Action sr="act1" ve="7">
<code>137</code>
<Int sr="arg0" val="0"/>
<Str sr="arg1" ve="3"/>
<ConditionList sr="if">
<Condition sr="c0" ve="3">
<lhs>%Camera</lhs>
<op>3</op>
<rhs>Cameralabel</rhs>
</Condition>
</ConditionList>
</Action>
<Action sr="act10" ve="7">
<code>548</code>
<Str sr="arg0" ve="3">Pic saved</Str>
<Int sr="arg1" val="0"/>
</Action>
<Action sr="act11" ve="7">
<code>38</code>
</Action>
<Action sr="act12" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%Photo</Str>
<Str sr="arg1" ve="3">%FOTO</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
</Action>
<Action sr="act13" ve="7">
<code>598</code>
<Str sr="arg0" ve="3">%Photo</Str>
<Str sr="arg1" ve="3">/</Str>
<Int sr="arg2" val="1"/>
<Int sr="arg3" val="1"/>
<Int sr="arg4" val="0"/>
<Str sr="arg5" ve="3"/>
<Int sr="arg6" val="1"/>
<Str sr="arg7" ve="3"/>
</Action>
<Action sr="act14" ve="7">
<code>135</code>
<Int sr="arg0" val="1"/>
<Int sr="arg1" val="1"/>
<Str sr="arg2" ve="3">start</Str>
</Action>
<Action sr="act2" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%foto</Str>
<Str sr="arg1" ve="3">%FOTO</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
</Action>
<Action sr="act3" ve="7">
<code>598</code>
<Str sr="arg0" ve="3">%foto</Str>
<Str sr="arg1" ve="3">/</Str>
<Int sr="arg2" val="1"/>
<Int sr="arg3" val="1"/>
<Int sr="arg4" val="0"/>
<Str sr="arg5" ve="3"/>
<Int sr="arg6" val="1"/>
<Str sr="arg7" ve="3"/>
</Action>
<Action sr="act4" ve="7">
<code>30</code>
<Int sr="arg0" val="500"/>
<Int sr="arg1" val="0"/>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
</Action>
<Action sr="act5" ve="7">
<code>135</code>
<Int sr="arg0" val="1"/>
<Int sr="arg1" val="1"/>
<Str sr="arg2" ve="3">start</Str>
<ConditionList sr="if">
<Condition sr="c0" ve="3">
<lhs>%foto</lhs>
<op>2</op>
<rhs>%Photo</rhs>
</Condition>
</ConditionList>
</Action>
<Action sr="act6" ve="7">
<code>37</code>
<ConditionList sr="if">
<Condition sr="c0" ve="3">
<lhs>%foto</lhs>
<op>3</op>
<rhs>Photo</rhs>
</Condition>
</ConditionList>
</Action>
<Action sr="act7" ve="7">
<code>130</code>
<Str sr="arg0" ve="3">Rename Photo</Str>
<Int sr="arg1">
<var>%priority</var>
</Int>
<Str sr="arg2" ve="3"/>
<Str sr="arg3" ve="3"/>
<Str sr="arg4" ve="3"/>
<Int sr="arg5" val="0"/>
</Action>
<Action sr="act8" ve="7">
<code>404</code>
<Str sr="arg0" ve="3">%FOTO</Str>
<Str sr="arg1" ve="3">Pictures/Camera/Taken at Last_Photo_Name.jpg</Str>
<Int sr="arg2" val="0"/>
</Action>
<Action sr="act9" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%Apicname</Str>
<Str sr="arg1" ve="3">%FOTO</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
</Action>
</Task>
<Task sr="task6">
<cdate>1430560672128</cdate>
<edate>1430609412951</edate>
<id>6</id>
<Action sr="act0" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%Camera</Str>
<Str sr="arg1" ve="3">Not_Cameralabel</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
</Action>
</Task>
</TaskerData>

Darijo Gospić

unread,
May 4, 2015, 11:16:40 AM5/4/15
to tas...@googlegroups.com
I've noticed it copies and renames only the latest pic, eg. if I open camera and take 3 photos, I can find only the last one in the folder set as destination folder..


On Thursday, December 13, 2012 at 3:45:15 AM UTC+1, Rich D wrote:

Robert Ryan

unread,
May 4, 2015, 11:22:26 AM5/4/15
to tas...@googlegroups.com

PLEASE don't post XML in the body of your post. No one here can read it. If you need to include the XML, attach it as a file.

Is this a working version or does it still have issues?

Rich D

unread,
May 4, 2015, 12:36:09 PM5/4/15
to Tasker Google Groups Post


> I've noticed it copies and renames only the latest pic, eg. if I open camera and take 3 photos, I can find only the last one in the folder set as destination folder..
>

That would make sense if the pics are taken in the minute of time because  your naming scheme looks like it would give all three  the same name..

, so it looks like this: Taken at 12:55, New York, 05.03.2015)

This is a fairly old post but this method worked flawlessly for me for a long time. I have since changed my approach because i found that if you have your camera app save the pics on the external sd card the %FOTO will not work.  I will post my new approach here when i get a chance. 

Rich D

unread,
May 4, 2015, 7:59:20 PM5/4/15
to Tasker Google Groups Post


> This is a fairly old post but this method worked flawlessly for me for a long time. I have since changed my approach because i found that if you have your camera app save the pics on the external sd card the %FOTO will not work.  I will post my new approach here when i get a chance. 

Ok, here is my latest version, and a explanation of how it works.

Profile: Pic Taken 2 (793)
Priority: 8
Application: Camera
Enter: Pic Taken On (786)
A1: Write File [ File:timestamp.txt Text:a Append:Off Add Newline:On ]

Exit: Pic Taken 2 (776)
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 ]
A6: Stop [ With Error:Off Task: ] If [ %picpath !Set ]
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: ]
A8: Variable Split [ Name:%picpath Splitter:/ Delete Base:Off ]
A9: Variable Set [ Name:%index To:%picpath(#?*jpg*) Do Maths:Off Append:Off ]
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: End For

Explanation:   The issue I had the most difficulty with was getting this to work for pictures taken in rapid succession.  This was what I came up with.  It uses the shell command "find" in the exit task to get a list of the file names that have been created since the enter task ran.  This has been tested and so far works flawlessly..

Profile: Pic Taken 2 (793)
Priority: 8
Application: Camera
Enter: Pic Taken On (786)
A1: Write File [ File:timestamp.txt Text:a Append:Off Add Newline:On ]

///  This action is used to make a time stamp of when the enter task was run. The contents of the file are not used,  just the creation time is used. The "find" command in the exit task uses the creation time of this file as the start time of its search and the current time as the end time of its search. //

Exit: Pic Taken 2 (776)
Run Both Together

/// It is important to set the task collision to "Run Both Together"  in the task properties.  (When in the task edit screen it is the three slider icon in the lower right)///

<start>
A1: Anchor
A2: Variable Set [ Name:%ret To:


Do Maths:Off Append:Off ]

/// This sets %ret to a 'carriage return' or 'line feed' . Just type a actual return in the TO: option. ///

<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: ]

///  this gets a list of file names created since the enter task ran and puts it in %picpath

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 ]

///  these 2 actions just loop the "find" command 3 times if the variable is not set. This gives the camera time to save all of the taken pictures.  ///

A6: Stop [ With Error:Off Task: ] If [ %picpath !Set ]

/// This will stop the task if there are no pictures 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: ]

/// The list has multiple return in it. This removes the returns. ///

A8: Variable Split [ Name:%picpath Splitter:/ Delete Base:Off ]

/// This splits the file names into an array ///

A9: Variable Set [ Name:%index To:%picpath(#?*jpg*) Do Maths:Off Append:Off ]

/// this gets the indices of the file names that are pictures. To rule out any videos ect.  ///

A10: Variable Split [ Name:%index Splitter:, Delete Base:Off ]

/// this splits the indices to be used in the for loop ///

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: End For

/// the for loop copies the files from the DCIM camera file to the folder name in %:Picfilename  ///

Hope someone finds some of this helpfull....  

Pic_Taken_2.prf.xml

Darijo Gospić

unread,
May 5, 2015, 11:01:07 AM5/5/15
to tas...@googlegroups.com
The seconds thing did the trick - I just added seconds to my new pic name and it works 100 %.
I've now tried to take pics as fast as I can (it seems Nexus 4 using Google camera takes pics in 2 seconds interval minimum) and it works flawlessly.
I'll import this profile since you argue it's better than the old one.
Many thanks.



On Thursday, December 13, 2012 at 3:45:15 AM UTC+1, Rich D wrote:
Reply all
Reply to author
Forward
Message has been deleted
0 new messages