02-20-2011 04:40 PM
I found this previous post that should be helpful.
Bill
02-20-2011 05:24 PM
02-20-2011 05:27 PM
I'm finding the opposite is true. I tried saving to userDirectory and received permissions errors. When referencing the "applicationStorageDirectory" it is working, so far.
Bill
02-20-2011 08:54 PM
billfoust wrote:
I'm finding the opposite is true. I tried saving to userDirectory and received permissions errors. When referencing the "applicationStorageDirectory" it is working, so far.
It took a while for me to investigate this as I kept having that annoying problem where the sim can't talk to the debugger and keeps popping up the dialog asking for the IP. Took over an hour to fix, and I still don't know what the fix is.
Anyway, I think the 0.9.3 simulator may have broken userDirectory. Or maybe for some reason I can't fathom, this is how it will be. In any case, here's the updated mapping of folder aliases to local paths, for 0.9.3. Contrast with the way it was for 0.9.2.
| Alias | Path |
|---|---|
| File.applicationDirectory | /accounts/1000/appdata/(appdir)/app/air |
| File.applicationStorageDirectory | /accounts/1000/appdata/(appdir)/data |
| File.desktopDirectory | /accounts/1000/appdata/(appdir)/shared/documents |
| File.documentsDirectory | /accounts/1000/appdata/(appdir)/shared/documents |
| File.userDirectory | /accounts/1000/appdata/(appdir) |
Now, in that list, the (appdir) folder (which refers to a folder named for your app's Package Name and Package Id joined with a dot, as in "Foo.QXBwRXZlbnRzICAgICAgICA") is not writable by your app. The app has read/execute permission only, and only root can write to it.
That explains your permission problems.
The two that point to the shared/ folder are using a symbolic link to get up to subdirectories of /accounts/1000/shared. No app has write access to the shared folder either, but all apps have write access to all 9 subfolders of the shared folder. These folders are, for now:
Obviously we have to guess, for now, exactly what some of those are for. Anyway, it means your options are basically to use the desktopDirectory or documentsDirectory (which point the same place), or userDirectory.resolvePath('shared/somesubfolder') .. which is probably not a good idea.
So, if 0.9.3 is taken as representative of the final device configuration, File.userDirectory is now "out of bounds".
02-20-2011 11:59 PM
I switched up to using File.documentsDirectory, but I haven't been using any subpaths. I've been able to save into this location using the File.browseForSave method, and some hacking to work around its bugs.
This is my Event.SELECT handler for the browse.
var sel:File = e.target as File; var name2:File = File.documentsDirectory.resolvePath(sel.name); trace (sel.nativePath); trace (name2.nativePath); var data:ByteArray = PNGEncoder.encode(bitmapData); var file:FileStream = new FileStream(); file.open(name2, FileMode.WRITE); file.writeBytes(data); file.close();
If you try to use the target (which I renamed to 'sel' you get a path like:
/accounts/1000/appdata/qnx.systemtray/(filename)
What is "qnx.systemtray"??? garbage.
so I've instead built a path by just taking the name portion, which is what the user typed in. The result is a functioning path of:
/accounts/1000/appdata/(appdir)/shared/documents/(
Loading however is (apparently) a completely different beast.
Using File.browserForOpen method, I can see the files that I've previously saved, and this is a wonderful thing! However, I can't seem to OPEN any of them.
private function chooseFile(e:Event):void
{
trace(e.target.nativePath);
var name2:File = File.documentsDirectory.resolvePath(e.target.name) ;
trace(name2.nativePath);
img.setImage(name2.nativePath);
}
Again, the e.target returned from the browse dialog can't be trusted.This time, the path is:
\accounts\1000\shared\documents\(filename). Notice there is no (appdata) portion in the path! Maybe its some kind of shortcut that is supposed to be prettier than the paths with (appdata) in them. I don't know. It still doesn't work.
Again, I build up the proper path, but I still get permissions errors trying to load the file. I get
Error #2044: Unhandled ioError:. text=Error #2035: URL Not Found. URL:app:/accounts/1000/appdata/(appdir)/shared/doc
It at least confirms that the path is right, and that is has the "app:" prefix to make it a URL.
This is using the qnx.ui.display.Image class. I've been trying other ways to load the file, ie like Loader, but so far I can't seem to get it loaded at all. Any suggestions?
Bill
02-21-2011 09:12 AM - edited 02-21-2011 09:15 AM
billfoust wrote:
If you try to use the target (which I renamed to 'sel' you get a path like:
/accounts/1000/appdata/qnx.systemtray/(filename)
What is "qnx.systemtray"??? garbage.
That looks as though the app that manages the browse dialog is actually the qnx.systemtray app (which in concert with qnx.navigator is what provides your OS UI experience), and it's giving you a path relative to its app: folder, which is probably not what it should be doing.
billfoust wrote:
so I've instead built a path by just taking the name portion, which is what the user typed in. The result is a functioning path of:
/accounts/1000/appdata/(appdir)/shared/documents/(
filename) ...
Again, the e.target returned from the browse dialog can't be trusted.This time, the path is:
\accounts\1000\shared\documents\(filename). Notice there is no (appdata) portion in the path! Maybe its some kind of shortcut that is supposed to be prettier than the paths with (appdata) in them. I don't know. It still doesn't work.
Again, I build up the proper path, but I still get permissions errors trying to load the file. I get
Error #2044: Unhandled ioError:. text=Error #2035: URL Not Found. URL:app:/accounts/1000/appdata/(appdir)/shared/doc
uments/(filename)
It at least confirms that the path is right, and that is has the "app:" prefix to make it a URL.
The e.target path makes some sense too, as the shared/documents folder is not really under your app folder but, as I mentioned, is a symbolic link. That is, the two paths you show there are actually pointing exactly the same place, at least as far as the native path portion is concerned. It's not exactly a shortcut, but you could consider it to be one if you like.
The problem may be that you're using a URL that was built with an app: prefix. It may not be your fault, but it may be causing the trouble. If that's true, you can probably use the first workaround that I described in this post, to build a new File object that doesn't have the app: prefix.
Note that the setImage() call apparently requires a URL, and possibly it has trouble with one that does not start with file://. Using a File object that has an app: prefix in the URL may not work, or it may work only for paths that are really relative to the app folder, which the one shown in your error is not. The workaround I just pointed you to would let you build a File object that uses file: in the URL instead of app:.
I advise when troubleshooting this sort of thing to use trace() calls where you dump both the .url and the .nativePath portion of your File objects, so you can more easily identify weird behaviour in the current implementation. Also prepare for this stuff to change again in the next release... scary that it's still not stabilized, as that probably means all apps using this stuff will require a new release before the product comes out.
02-21-2011 02:31 PM
I've gotten it working! Thanks for the nudge Peter.
peter9477 wrote:
Note that the setImage() call apparently requires a URL, and possibly it has trouble with one that does not start with file://. Using a File object that has an app: prefix in the URL may not work, or it may work only for paths that are really relative to the app folder, which the one shown in your error is not. The workaround I just pointed you to would let you build a File object that uses file: in the URL instead of app:.
This was sort of right! When calling setImage() I was using the File.nativePath, which isn't a URL at all. The method was prepending ("app:") to it to make a URL. This worked fine when I was doing the initial load as an asset included in my project, but is completely wrong when trying to load an image from the filesystem. Insead of using the File.nativePath, I changed it to use File.url and it all started working!
Sometimes, you can get so bogged down in the details that you fail to see the obvious pattern, and being tired certainly doesn't help.
Bill