7

I want to save some user credentials in my qt application that runs on Android. I use QSettings for this like so:

QString appPath = QCoreApplication::applicationDirPath()+QLatin1Char('/');
set = new QSettings(appPath+"test",
                   QSettings::NativeFormat);
set->setValue ( "user/username", "NameOfTheUser" );
set->setValue ( "user/password", "UserPassword" );
set->sync();

I restart the app and inside an initialize() method I have:

QString username(set->value("user/username",
                                           ( QVariant ) tr ( "defaultUser" ) ).toString());
QString password(set->value("user/password",
                                           ( QVariant ) tr ( "defaultPass" ) ).toString());

The username and password vars are not read from the QSettings.
The same code is working on Windows.
Thank you

Lucian
  • 874
  • 11
  • 33
  • That path won't be writable on most platforms, including Android. Did you try with a default-constructed (no arguments) QSettings object? – Frank Osterfeld Oct 14 '13 at 20:09
  • I tried as you said, QSettings("test") instead, same responce, invalid values for username and password.Maybe worth mentioning that my AndroidManifest.xml settings contains "...user-permission ...WRITE_EXTERNAL_STORAGE"..this was my only hint to this problem, but it is set and still not working. Thank you – Lucian Oct 14 '13 at 20:18
  • 1
    I think, deploying including a settings file and using that file would help. Or use QSettings::IniFormat, and put the file at /sdcard/.settings or /mnt/card0. Use some predefined paths. – Md. Minhazul Haque Oct 14 '13 at 20:27
  • 1
    QSettings(test) also constructs a path from the working directory. Try a default constructed one, i.e. `new QSettings()` – Frank Osterfeld Oct 15 '13 at 06:13
  • I tried QSettings() with no success. Saving it on "/sdcard..." worked. Strange fact because I don;t have an sdcard, I have a Nexus phone. Thank you for your answers. – Lucian Oct 15 '13 at 10:51

6 Answers6

6

I also ran into similar problem and found out that 2 things should be done:

  1. path to settings file should be specified
  2. QSettings::sync() should be explicitly called after every settings change.

So on Windows I had this working:

QSettings settings("settings.ini", QSettings::IniFormat);
settings.setValue(GRID_ENABLED, enabled);

On Android I have to use the following code:

QSettings settings("/sdcard/settings.ini", QSettings::NativeFormat); //can be IniFormat, no difference
settings.setValue(GRID_ENABLED, enabled);
settings.sync();

Probably using "sdcard" is not good enough and you should use other directory.

Volodymyr K.
  • 669
  • 8
  • 20
2

You can try to specify the location of the setting file to a writable location which exists even if the application is removed :

#include <QSettings>
#include <QStandardPaths>

QString path ;
QString filename;

path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) ;
filename = “config.ini” ;
QSettings settings(path + “/”+ filename,QSettings::IniFormat) ;

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

Also you can set the application and organization name in the main of your application once :

qApp->setOrganizationName("Company");
qApp->setApplicationName("App");
Nejat
  • 31,784
  • 12
  • 106
  • 138
1

As noted, a re-deploy of the application from Qt Creator wipes the settings.

This is still true in Qt Creator 3.3.2 with the following caveat. When you deploy the app on Android and look at the Application Output window, there is a tool bar with a "stop" button (red square) and a "Re-run this run configuration" button (green triangle).

The initial deploy from Qt starts the app. The QSettings object is cleared or empty. Any changes to the QSettings object will be saved in the object.

If you stop the app with the red button, then immediately restart the app with the green Re-run button, the app will restart and all changes to the QSettings object in the previous run will still be there.

I assume this emulates the start, exit, restart of the app on a device.

L Clague
  • 11
  • 1
1

Hi I've found the solution, tested on 3 different Android device. You can set the following path for your settings.

mPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
QString filename = "se.ini";
mPath = mPath + "/" + filename;

By following code you save your info under above location.

void ProfileManager::saveToRegistery()
{
    QSettings settings(mPath , QSettings::NativeFormat);
    settings.setValue("SE/Mail" , mMail);
    settings.setValue("SE/Pass" , mPass);

    settings.sync();
}

If you have any trouble with saving that place, you ask user permission for accessing any file with:

bool QAndroidPermissions::requestPermissions()
{

    QtAndroid::PermissionResult r = 
    QtAndroid::checkPermission("android.permission.WRITE_EXTERNAL_STORAGE");
    if(r == QtAndroid::PermissionResult::Denied) {
    QtAndroid::requestPermissionsSync( QStringList() << 
     "android.permission.WRITE_EXTERNAL_STORAGE" );
    r =QtAndroid::checkPermission("android.permission.WRITE_EXTERNAL_STORAGE");
    if(r == QtAndroid::PermissionResult::Denied) {
        return false;
    }
}
return true;

}

Hope this helps,

0

I had a problem similar to the above, and it turned out that everything worked just fine. That is it did work with a simple QSettings object without any arguments.

HOWEVER, every time I re-deployed the application from Qt Creator, the settings file was destroyed, leading me to the conclusion that QSettings did not work.

The problem should, according to Bogdan himself, have been fixed in Qt Creator 3.2

0

The only problem with your code is that for Android you have to use QStandartPaths to get path and not the QCoreApplication::applicationDirPath().

QCoreApplication::applicationDirPath() will give you the windows application path to your Android Application, which won't work on Android.

Thira
  • 1,555
  • 1
  • 13
  • 24