Bootstrap

利用Qt5.15.2编写Android程序时遇到的问题及解决方法

文章目录

背景

目前我用的是Qt5.15.2来编写Qt程序,环境的配置看我这篇文章【Qt5.15.2配置Android开发环境】
项目中的一些配置的截图:
在这里插入图片描述
在这里插入图片描述

1.文件读写

假如直接用 QFileDialog::getExistingDirectory来获取路径的话,会得到类似这样的字符串
content://com.android.externalstorage.documents/tree/primary%3A下载
这样的假如直接利用这一串字符串在其他增加文件名来读写文件的话,是会失败的。
比如

    QString dirStr = QFileDialog::getExistingDirectory(this, "dir", "");
    // dir此时会是类似这样的字符串: content://com.android.externalstorage.documents/tree/primary%3A下载
    QString fileName = dirStr + "/123.txt";
    QFile file(fileName);
    if(file.open(QFile::WriteOnly | QFile::Truncate))
    {
    }
    else
    {
    // 百分百进来这里
    }

经过查阅资料及自己的测试,正确的做法如下:

1.动态申请读写权限
2.将QFileDialog::getExistingDirectory得到的路径进行转换
3.将百分号相关字符转换为正常字符

相关代码如下

#ifdef Q_OS_ANDROID
#include <QtAndroid>
// 申请读写权限
bool checkPermission()
{
    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;
        }
    }

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

    return true;
}

// 路径的转换;这里后面可能还要考虑其他情况
QString androidUrlToLocalUrl(QString dirStr)
{
    if(dirStr.startsWith("content://com.android.externalstorage.documents/tree/primary%3A"))
    {
        dirStr = dirStr.replace("content://com.android.externalstorage.documents/tree/primary%3A",
                                "/storage/emulated/0/");
    }
    dirStr = QByteArray::fromPercentEncoding(dirStr.toUtf8());

    return dirStr;
}
#endif

void test()
{
#ifdef Q_OS_ANDROID
     bool ret = checkPermission();
     if(ret == false)
     {
      // 一定要有权限,没有的话,软件可以退出了
      return;
     }
#endif
    QString dirStr = QFileDialog::getExistingDirectory(this, "dir", "");
#ifdef Q_OS_ANDROID
    dirStr = androidUrlToLocalUrl(dirStr);
#endif
    QString fileName = dirStr + "/123.txt";
    QFile file(fileName);
    if(file.open(QFile::WriteOnly | QFile::Truncate))
    {
    }
    else
    {
    }
}

参考:
【Qt Android 申请写文件到内部存储】
【QT Android开发 URL转本地路径】
【Qt for android 之 QFileDialog正确使用方式】

;