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 hav the following 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?
Thanks.
Well aparently is a bug in Qt 5.10 prebuilt version, rolled back to Qt 5.9 and it works. Its a shame since I needed the QML translation functions.
https://bugreports.qt.io/browse/QTBUG-64103
Related
I have battled this issue for sometime now and i seem to be going nowhere, I am using file_picker flutter plugin, its working on devices with android v7, now am running the app on emulator with android v9 and the filepicker creates symlink, here is a log:
I/FilePickerUtils( 7999): File loaded and cached at:/data/user/0/com.lulliezy.videostatus/cache/file_picker/KHALIGRAPH JONES x SARKODIE - WAVY (OFFICIAL VIDEO).webm
I/FilePickerDelegate( 7999): Absolute file path:/data/user/0/com.lulliezy.videostatus/cache/file_picker/KHALIGRAPH JONES x SARKODIE - WAVY (OFFICIAL VIDEO).webm
Now my understanding bt the word cached is a symlink is created, now how do i disable this feature or rather, get the original file name with this code:
await FilePicker.getFile(
type: FileType.custom,
allowedExtensions: ['mp4', 'webm'],
);
Thanks in advance.
EDIT
I should clarify, am using flutter ffmpeg so it complains with file does not exists.
I actually found a workaround for this, I copied the picked file to another temporary directory and used that new path after which when am done, I delete the copied file.
I'm developing an app on android using Qt 5.15.0. My app creates a database and some other files using QStandardPaths::AppDataLocation. everything works fine from the code side: debug output makes me think the files are there and that the app is using them. The problem is that when I search from the PC inside the smartphone folders I cannot find the files created. So this makes me think I am not writing to the folder I'm expecting to.
This is my code:
appDataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
QDir directory;
if (!directory.exists(appDataPath + QStringLiteral("/DATABASE")))
directory.mkpath(appDataPath + QStringLiteral("/DATABASE"));
if (!directory.exists(appDataPath + QStringLiteral("/DATA")))
directory.mkpath(appDataPath + QStringLiteral("/DATA"));
qDebug() << "Percorso: " << appDataPath << " dir exists:" << directory.exists(appDataPath + QStringLiteral("/DATABASE"));
QFile f( appDataPath + "/DATABASE/Prova.txt" );
if( f.open( QIODevice::WriteOnly ) )
{
f.write( "Ciao" );
f.close();
}
if( f.error() != QFileDevice::NoError )
qDebug() << QString("Error writing file '%1':").arg(appDataPath + "/DATABASE/Prova.txt") << f.errorString();
I also write a file that I read at startup and I can read from it so I assume the file is present and is not saved as temporary.
The output is:
D/MyApp(17849): Percorso: "/data/data/org.qtproject.example/files" dir exists: true
Now I suppose I can find my files in this directory inside the phone in this folder:
Questo PC\Samsung Galaxy J3 (2016)\Phone\Android\data\org.qtproject.example\files
But there are no directories or files inside. I bet I am missing some trivial things.
I am giving the app these permission:
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAGE
Can someone help me?
Thanks in advance!
It seems that
QStandardPaths::AppLocalDataLocation, QStandardPaths::AppDataLocation
don't give the correct path to the app's file folder. I encountered the same issue with Qt 5.14.1. While QStandardPaths gave me
/data/user/0/com.mycompany.myapp/files
a call via a QAndroidJniObject to the java side gave me
/storage/emulated/0/Android/data/com.mycompany.myapp/files
Using the latter all directories and files were created correctly. I suggest to either try my work-around with
QtNative.activity().getExternalFilesDir(null).getAbsolutePath();
in an added java class and call it through a QAndroidJniObject or report this as a bug to Qt.
Nevertheless, there might be another solution to the problem I'm not aware of.
An empty database file with the same name exists BEFORE we copy it from the assets folder.
android.database.sqlite.SQLiteException: no such table:
This error message is legitimate because an empty database exists in our data directory with the same name. Although we have not copied it yet.
How is our database file being created?
Why does it exist even if we have not called or instantiated our Database Helpers?
Using the same SQLiteHelper classes for all previous versions with no issues.
Running on Android 9 Pie causes this error message after a clean install of our Android app that uses an existing database in the assets directory. Normally when this file does NOT exist in the data directory it is copied then opened.
Checked and rechecked, the file exists BEFORE our call to move it from our assets directory.
When checking the Android 9 Pie data directory, our SQLite database file already exists. This is after a new install AND clearing cache & data
To repeat what we are seeing.
Settingsā¦ Apps & Notifications
Select our app
Storage
Clear Cache + Clear Storage
Uninstall the app.
Launcher Activity "SplashActivity" onCreate()
String mName = "myawesomedatabase.db";
String mDatabasePath = this.getApplicationInfo().dataDir + "/databases";
File file = new File (mDatabasePath + "/" + mName);
Log.i("DATABASE", "##### SplashActivity.getData() " + mDatabasePath + "/" + mName);
if (file.exists()) {
Log.i("DATABASE", "##### SplashActivity.getData() FILE EXISTS!!!");
}
Repeating the above and NOT uninstalling the app, copies the file properly. It is ONLY on new installations.
We have confirmed we are not hardcoding the data directory. Researching this we learned that the database directory has changed.
From: /data/data/com.___._____/databases/
To: /data/user/0/com.____.____/databases/
Referencing this article that helped this discovery.
Android P - 'SQLite: No Such Table Error' after copying database from assets
Work around:
Clean install of the app.
Wait for crash
Settings... Apps... Specific App... Clear Cache + Clear Storage
Run app again
Success, database does NOT exist in data directory, then the app copies file from Assets Directory with no issue.
No stupid questions?
But man I feel dumb when it was an easy answer.
Perhaps taking the time to ask here made us look harder.
Android P has auto restore from backup. Even if you do not have a copy of the app installed. So a corrupted file was being restored from backup.
Android P steps to correct (at least in development environment)
Settings...
System
/ Advanced
Backup
App data
Turn OFF Automatic Restore
Discovery came after finding out it worked on AVD with Factory reset. However development devices with different app versions experienced the same issue.
This code works in the simulator but not on my Android device:
local path = system.pathForFile("chinese_rules.db")
print("PATH:: " .. tostring( path ) )
When I run this code on my Galaxy S4 path returns nil.
My first thought was that it was some typo (case sensitivity) but I can't find any typo:
http://i59.tinypic.com/wlpu14.png
I can't find any reason why it should receive nil. This causes a problem as I can't load my database.
I have also tried this with the same result:
local path = system.pathForFile("chinese_rules.db", system.ResourceDirectory)
I have been able to load a path and load databases like this before.
Corona Build: 2013.2100 (2013.12.7)
Further reading the documentation I don't see that .db is a restricted file type:
Corona allows direct loading of images and audio files using the
appropriate APIs, but it has limited access to resource files on
Android using the file I/O APIs. Specifically, the following types can
not be read from the resources directory: .html, .htm., .3gp, .m4v,
.mp4,.png, .jpg, and .ttf.
http://docs.coronalabs.com/api/library/system/pathForFile.html
I found out the reason for the problem:
We are two that are working on this project and he had setup to use expansion files so two files was created (the main APK and the OBB expansion file) which I didn't notice and I only loaded the main APK file and I guess the database is in the OBB file. After setting not to use an expansion file the app works.
usesExpansionFile = false
I have a application that has a shared library and a small executable that uses the shared library.
The small executalbe (~2kB) is in assets and I write it to the Cache Directory, which is available by calling Context.getCacheDir(). I can start my small executable by putting LD_LIBRARY_PATH=/data/data/my.app.package/lib into the environment before starting the process with ProcessBuilder.
Is there a better way to set the library path?
Is there a way to get the library directory without hardcoding it?
Setting the library path through ProcessBuilder.environment() seems reasonable to me, and you can get the library directory by calling Context.getApplicationInfo():
ApplicationInfo info = getApplicationInfo();
Log.i(TAG, "native library dir = " + info.nativeLibraryDir);