2

Im my app based on QML I use Camera and CameraCapture to capture an image from the camera. After it was captured I want to store captured image in application data folder with CameraCapture.captureToLocation(). But I have no idea how to get path to this folder. So my question - how can I get path to application folder wit write permissions? Is there way in Qt to get it? It should be system specified folder, I guess. For example in Android it should be /data/data/AppName. As I see LocalStorage creates its files in some similar place.

László Papp
  • 51,870
  • 39
  • 111
  • 135
folibis
  • 12,048
  • 6
  • 54
  • 97

2 Answers2

3

/data/data/AppName is not mapped in QStandardPaths, but I think it would be better to use this one:

QStandardPaths::AppDataLocation 17 Returns a directory location where persistent application data can be stored. This is an application-specific directory. To obtain a path to store data to be shared with other applications, use QStandardPaths::GenericDataLocation. The returned path is never empty. On the Windows operating system, this returns the roaming path. This enum value was added in Qt 5.4.

or this one in earlier versions:

QStandardPaths::DataLocation 9 Returns the same value as AppLocalDataLocation. This enumeration value is deprecated. Using AppDataLocation is preferable since on Windows, the roaming path is recommended.

These will be set to DataLocation "<APPROOT>/files", "<USER>/<APPNAME>/files" underneath on Android.

But note that from 5.4 on, the latter is deprecated as documented. You can set it then as follows:

QString QStandardPaths::​writableLocation(StandardLocation type)

Returns the directory where files of type should be written to, or an empty string if the location cannot be determined.

Note: The storage location returned can be a directory that does not exist; i.e., it may need to be created by the system or the user.

So, you would write something like this:

QString dataPath = QStandardPaths::​writableLocation(QStandardPaths::AppDataLocation);
// Do not need to check against empty string for this value as per documentatio
CameraCapture.captureToLocation(dataPath);

Note: Please do not use QStandardPaths::ApplicationsLocation for this purpose since that is the non-dedicated location. In addition, it is even unsupported on Android:

ApplicationsLocation not supported (directory not readable)

If you want to share the image across applications, you would need to use this with minor adjustment to the code above. While I think you wanted the one above, it is a bit unclear which one you wanted, so I am mentioning both:

StandardPaths::GenericDataLocation 11 Returns a directory location where persistent data shared across applications can be stored. This is a generic value. The returned path is never empty.

This is set to GenericDataLocation "<USER>" on Android. The exact mappings are mentioned in the class documentation, you just need to scroll down to the tables. I cannot give direct URL as there is no permalink to that section. You can check yourself, too, which fits the best.

Community
  • 1
  • 1
László Papp
  • 51,870
  • 39
  • 111
  • 135
  • Great answer as always, lpapp, thanks. Adding my two cents, personally I've found myself quite comfortable with the `DownloadLocation`. It falls back to `documents` on desktops and for mobiles, my users feel quite intuitive to connect the mobile device and grab files from a subdirectory of that. Anyhow, I guess I've to check out `GenericDataLocation`. – BaCaRoZzo Dec 07 '14 at 10:39
  • First of all, thanks @lpapp for such detailed answer. I need the data path specified for the application. So I looked for some cross-platform solution, at least it should work on Windows, Linux and Android. I've tested GenericDataLocation and it points to system data folder so I just add application name to this path. Sure, I create this folder. – folibis Dec 07 '14 at 12:21
  • 1
    @folibis: I suggest to read the documentation again. `GenericDataLocation` is not what you want based on your question and this comment. You said you needed app data, and that is (App)DataLocation. There is little to no point in constructing exactly that on your own from `GenericDataLocation`. I think you are confused. – László Papp Dec 07 '14 at 12:25
  • Yes @lpapp, you are right, after reading the documentation again, I think `DataLocation` is what I need. `Returns a directory location where persistent application data can be stored. This is an application-specific directory`. So I should read it more carefully – folibis Dec 07 '14 at 23:09
  • Btw, I see no `QStandardPaths::AppDataLocation` in Qt 5.3. – folibis Dec 07 '14 at 23:11
  • @folibis: `or this one in earlier versions: QStandardPaths::DataLocation`. – László Papp Dec 08 '14 at 01:36
1

You can use QStandardPaths to specify a writable location :

QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) ;

Here QStandardPaths::GenericDataLocation returns a directory location where persistent data shared across applications can be stored and it is never empty.

It's also possible use QStandardPaths::ApplicationsLocation or many others which could be found here. You can implement a function in C++ side and use it in your QML to get the standard location.

Nejat
  • 31,784
  • 12
  • 106
  • 138
  • @folibis: can you reveal your logic, please? `I've tested GenericDataLocation and it points to system data folder so I just add application name to this path` and `I need the data path specified for the application`. That is (App)DataLocation, which is GenericDataLocation + appname precreated for you. Are you saying that you reject using (App)DataLocation and reinvent it instead? If so, that does not look like a good idea to me. – László Papp Dec 07 '14 at 12:30