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.io.FileNotFoundException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
@ -70,6 +71,7 @@ import android.view.Menu;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.InputDevice;
|
import android.view.InputDevice;
|
||||||
|
import android.database.Cursor;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.security.KeyStore;
|
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
|
// this method loads full path libs
|
||||||
public static void loadQtLibraries(final ArrayList<String> libraries)
|
public static void loadQtLibraries(final ArrayList<String> libraries)
|
||||||
{
|
{
|
||||||
|
@ -44,9 +44,10 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
AndroidContentFileEngine::AndroidContentFileEngine(const QString &fileName)
|
AndroidContentFileEngine::AndroidContentFileEngine(const QString &f)
|
||||||
: QFSFileEngine(fileName)
|
: m_file(f)
|
||||||
{
|
{
|
||||||
|
setFileName(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
|
bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
|
||||||
@ -78,6 +79,48 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
|
|||||||
return QFSFileEngine::open(openMode, fd, QFile::AutoCloseHandle);
|
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;
|
||||||
AndroidContentFileEngineHandler::~AndroidContentFileEngineHandler() = default;
|
AndroidContentFileEngineHandler::~AndroidContentFileEngineHandler() = default;
|
||||||
|
@ -47,6 +47,12 @@ class AndroidContentFileEngine : public QFSFileEngine
|
|||||||
public:
|
public:
|
||||||
AndroidContentFileEngine(const QString &fileName);
|
AndroidContentFileEngine(const QString &fileName);
|
||||||
bool open(QIODevice::OpenMode openMode) override;
|
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
|
class AndroidContentFileEngineHandler : public QAbstractFileEngineHandler
|
||||||
|
Loading…
x
Reference in New Issue
Block a user