Android: Add support for getting information about content uris
This enables things like size(), exists() to work with Android content uris with the provided uri given from a filedialog. It is expected that it is always a full path due to the nature of content uris, so relative paths will not work. Change-Id: I9c9ea42833677eb9d937b33e9dd42ee2a7d9c7c5 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io> Reviewed-by: BogDan Vatra <bogdan@kdab.com>
This commit is contained in:
parent
ca9de96233
commit
7e5f38aec6
@ -44,6 +44,7 @@ import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.io.IOException;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Service;
|
||||
@ -70,6 +71,7 @@ import android.view.Menu;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.InputDevice;
|
||||
import android.database.Cursor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.KeyStore;
|
||||
@ -231,6 +233,61 @@ public class QtNative
|
||||
}
|
||||
}
|
||||
|
||||
public static long getSize(Context context, String contentUrl)
|
||||
{
|
||||
Uri uri = getUriWithValidPermission(context, contentUrl, "r");
|
||||
long size = -1;
|
||||
|
||||
if (uri == null) {
|
||||
Log.e(QtTAG, "getSize(): No permissions to open Uri");
|
||||
return size;
|
||||
}
|
||||
|
||||
try {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Cursor cur = resolver.query(uri, null, null, null, null);
|
||||
if (cur != null) {
|
||||
if (cur.moveToFirst())
|
||||
size = cur.getLong(5); // size column
|
||||
cur.close();
|
||||
}
|
||||
return size;
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(QtTAG, "getSize(): Invalid Uri");
|
||||
return size;
|
||||
} catch (UnsupportedOperationException e) {
|
||||
Log.e(QtTAG, "getSize(): Unsupported operation for given Uri");
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean checkFileExists(Context context, String contentUrl)
|
||||
{
|
||||
Uri uri = getUriWithValidPermission(context, contentUrl, "r");
|
||||
boolean exists = false;
|
||||
|
||||
if (uri == null) {
|
||||
Log.e(QtTAG, "checkFileExists(): No permissions to open Uri");
|
||||
return exists;
|
||||
}
|
||||
|
||||
try {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Cursor cur = resolver.query(uri, null, null, null, null);
|
||||
if (cur != null) {
|
||||
exists = true;
|
||||
cur.close();
|
||||
}
|
||||
return exists;
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(QtTAG, "checkFileExists(): Invalid Uri");
|
||||
return exists;
|
||||
} catch (UnsupportedOperationException e) {
|
||||
Log.e(QtTAG, "checkFileExists(): Unsupported operation for given Uri");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// this method loads full path libs
|
||||
public static void loadQtLibraries(final ArrayList<String> libraries)
|
||||
{
|
||||
|
@ -44,9 +44,10 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
AndroidContentFileEngine::AndroidContentFileEngine(const QString &fileName)
|
||||
: QFSFileEngine(fileName)
|
||||
AndroidContentFileEngine::AndroidContentFileEngine(const QString &f)
|
||||
: m_file(f)
|
||||
{
|
||||
setFileName(f);
|
||||
}
|
||||
|
||||
bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
|
||||
@ -78,6 +79,48 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
|
||||
return QFSFileEngine::open(openMode, fd, QFile::AutoCloseHandle);
|
||||
}
|
||||
|
||||
qint64 AndroidContentFileEngine::size() const
|
||||
{
|
||||
const jlong size = QJNIObjectPrivate::callStaticMethod<jlong>(
|
||||
"org/qtproject/qt5/android/QtNative", "getSize",
|
||||
"(Landroid/content/Context;Ljava/lang/String;)J", QtAndroidPrivate::context(),
|
||||
QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
|
||||
return (qint64)size;
|
||||
}
|
||||
|
||||
AndroidContentFileEngine::FileFlags AndroidContentFileEngine::fileFlags(FileFlags type) const
|
||||
{
|
||||
FileFlags commonFlags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag);
|
||||
FileFlags flags;
|
||||
const bool exists = QJNIObjectPrivate::callStaticMethod<jboolean>(
|
||||
"org/qtproject/qt5/android/QtNative", "checkFileExists",
|
||||
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
|
||||
QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
|
||||
if (!exists)
|
||||
return flags;
|
||||
flags = FileType | commonFlags;
|
||||
return type & flags;
|
||||
}
|
||||
|
||||
QString AndroidContentFileEngine::fileName(FileName f) const
|
||||
{
|
||||
switch (f) {
|
||||
case PathName:
|
||||
case AbsolutePathName:
|
||||
case CanonicalPathName:
|
||||
case DefaultName:
|
||||
case AbsoluteName:
|
||||
case CanonicalName:
|
||||
return m_file;
|
||||
case BaseName:
|
||||
{
|
||||
const int pos = m_file.lastIndexOf(QChar(QLatin1Char('/')));
|
||||
return m_file.mid(pos);
|
||||
}
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
AndroidContentFileEngineHandler::AndroidContentFileEngineHandler() = default;
|
||||
AndroidContentFileEngineHandler::~AndroidContentFileEngineHandler() = default;
|
||||
|
@ -47,6 +47,12 @@ class AndroidContentFileEngine : public QFSFileEngine
|
||||
public:
|
||||
AndroidContentFileEngine(const QString &fileName);
|
||||
bool open(QIODevice::OpenMode openMode) override;
|
||||
qint64 size() const override;
|
||||
FileFlags fileFlags(FileFlags type = FileInfoAll) const override;
|
||||
QString fileName(FileName file = DefaultName) const override;
|
||||
private:
|
||||
QString m_file;
|
||||
|
||||
};
|
||||
|
||||
class AndroidContentFileEngineHandler : public QAbstractFileEngineHandler
|
||||
|
Loading…
x
Reference in New Issue
Block a user