Copy file from assets to permanent location Qt + Android
I'm trying to copy a default initialized database packaged in the assets folder to an permanent location in an android device. For this I have the following snippet of code:
QString db_file = "/my_db"; QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); QFile assets_path("assets:" + db_file); assets_path.copy(path + db_file); QFile::setPermissions(path + db_file, QFileDevice::ReadUser | QFileDevice::WriteUser);
And then I would go on to open the database in this new path, the thing is I'm getting the following error after the copy.
Copy error "Cannot create /data/user/0/org.qtproject.Demo/files/my_db for output"
What am I doing wrong?. Is also this the correct/proper way to do this? Can it be that it doesn't finds the asset file?
Hi and welcome to devnet,
You should check if the copy is successful and print the error message returned by errorString if it fails.
Sorry if I didn't make myself clear but that copy error is a print of errorString() right after the .copy() call.
Ok, did you check whether that directory return by
writableLocationwas already created ?
No, I was assuming it was since the doc says "The returned path is never empty." Although I have to say I've tried with other QstandardPaths with no avail. Is there a way to see if I'm getting a permission error?
From the documentation:
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.
See the note, it's important.
You can use QDir::exists to check whether the folder currently exists.
Yes I've read that but the doc also said:
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.
Anyways I'll check about the path and come back. Although I tried to create a folder I didn't know if I was doing it right, I tried this.
QDir dir_folder(QDir::root()); dir.mkdir(path);
It means that the returned
QStringis not empty, not that the path it points to is not empty.
I would have used QDir::mkpath so it creates all the parent directories as needed.
Hi, tried what you suggested above but It still doesn't works. At first I though the asset wasn't being packade but QFile exists returns true, tried creating the folder with a good result but it just doesnt copies the file
Android debug output
// QFile file("assets:/my_db"); file.exists() D LOG TAG : Does the asset exists asset? true // QDir dir(QDir::root()); dir.mkpath(path); // QStandardPath::AppLocalData dir exists? after mkpath D LOG TAG : "/data/user/0/org.qtproject.Demo/files" true // file.errorString() output D LOG TAG : Err String: "Cannot create /data/user/0/org.qtproject.Demo/files/my_db for output"
At this point i'm just mindf*. I checked everything it just doesn't copies the file :/
Well after googling a lot I found this https://bugreports.qt.io/browse/QTBUG-64103?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel&showAll=true
Its working now with qt 5.9. Wish they had added that to known issues https://wiki.qt.io/Qt_5.10.0_Known_Issues.
Good catch !
I had forgotten about that one...
The known issues page has been updated.