bara@develer.com
package qtday17;
import org.qtproject.qt5.android.bindings.QtActivity;
public class MyActivity extends QtActivity {
}
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation"
android:name="qtday17.MyActivity"
android:label="-- %%INSERT_APP_NAME%% --"
android:screenOrientation="unspecified"
android:launchMode="singleTop">QT += quickcontrols2#include <QQuickStyle>
// ...
int main(int argc, char *argv[]) {
// ...
QGuiApplication app(argc, argv);
QQuickStyle::setStyle("Material");
// ...
}Possibilità per la personalizzare varie parti dello stile (per esempio background, foreground, theme)
Esistono shades e colori Material predefiniti
Material.background: Material.color(Material.Red, Material.Shade900)Qt fornisce un'unità di misura scalabile, font.pointSize, che però non tiene conto della densità di pixel del display.
Non esiste un'unità di misura scalabile.
Android associa risorse diverse in base alla risoluzione dello schermo
Con Qt possiamo utilizzare SVG
namespace {
const double REFERENCE_DPI = 150;
}
Units::Units(QObject *parent) :
QObject(parent)
{
// due to QTBUG-35701 we cannot use phisycaldotsperinch * devicepixelratio on android
#ifdef Q_OS_ANDROID
QAndroidJniObject qtActivity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative",
"activity", "()Landroid/app/Activity;");
QAndroidJniObject resources = qtActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
QAndroidJniObject displayMetrics = resources.callObjectMethod("getDisplayMetrics",
"()Landroid/util/DisplayMetrics;");
int dpi = displayMetrics.getField<int>("densityDpi");
#else
auto screen = qApp->primaryScreen();
int dpi = screen->logicalDotsPerInch() * qApp->devicePixelRatio();
#endif
scale_ratio = dpi / REFERENCE_DPI;
}
int Units::dp(int pixels)
{
return ceil(pixels * scale_ratio);
}
int main(int argc, char *argv[]) {
....
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
....
}Applicazione sviluppata per monitor obiettivo, interfaccia pixel perfet
Problema: su device dimensioni di schermo diverse lo spazio potrebbe non essere occupato correttamente
#define REFERENCE_WIDTH 1280
#define REFERENCE_HEIGHT 800
double calculateRatio() {
auto qtActivity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative",
"activity",
"()Landroid/app/Activity;");
auto windowManager = qtActivity.callObjectMethod("getWindowManager",
"()Landroid/view/WindowManager;");
auto defaultDisplay = windowManager.callObjectMethod("getDefaultDisplay",
"()Landroid/view/Display;");
auto point("android/graphics/Point");
defaultDisplay.callMethod<void>("getRealSize", "(Landroid/graphics/Point;)V", point.object());
auto width = point.getField<int>("x");
auto height = point.getField<int>("y");
return qMin((float)width / REFERENCE_WIDTH, (float)height / REFERENCE_HEIGHT);
}
int main(int argc, char *argv[]) {
.....
qputenv("QT_SCALE_FACTOR", QString::number(calculateRatio()).toLocal8Bit());
QGuiApplication app(argc, argv);
.....
}bool allow;
QtAndroid::androidActivity().callMethod<void>("allowLockScreen", "(Z)V", allow);Java
C++
public void allowLockScreen(final boolean allow) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (allow)
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
else
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
}public class PrintInformation {
...
public PrintInformation(String value) {
...
}
}
public class MyActivity extends QtActivity {
public static void setColorInfo(PrintInformation print_information) {
...
}
}auto str = QAndroidJniObject::fromString(QString("hello"));
QAndroidJniObject value("org/qt/PrintInformation", "(Ljava/lang/String;)V",
str.object<jstring>());
QAndroidJniObject::callStaticMethod<void>("org/qt/MyActivity",
"setColorInfo", "(Lorg/qt/PrintInformation;)V", value.object());public class MyActivity extends QtActivity {
private static native void printerFound(String name, String mac, int type, int index);
}class ConfigurationManager {
static void printerFound(JNIEnv *env, jobject thiz, jstring name,
jstring mac, jint printer_type, jint index) {
...
}
}Java
C++
static JNINativeMethod methods[] {{"printerFound",
"(Ljava/lang/String;Ljava/lang/String;II)V",
(void*)ConfigurationManager::printerFound}};
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
{
JNIEnv* env; // get the JNIEnv pointer.
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
return JNI_ERR;
// search for Java class which declares the native methods
jclass javaClass = env->FindClass("org/qt/MyActivity");
if (!javaClass)
return JNI_ERR;
// register our native methods
if (env->RegisterNatives(javaClass, methods,
sizeof(methods) / sizeof(methods[0])) < 0) {
return JNI_ERR;
}
return JNI_VERSION_1_6;
}<meta-data android:name="android.app.background_running" android:value="true"/>package qtday17;
import android.content.Context;
import android.content.Intent;
import org.qtproject.qt5.android.bindings.QtService;
public class MyService extends QtService {
public static void startMyService(Context ctx) {
ctx.startService(new Intent(ctx, MyService.class));
}QAndroidJniObject::callStaticMethod<void>("com/prova/MyService", "startMyService",
"(Landroid/content/Context;)V",
QtAndroid::androidActivity().object());QT += remoteobjectsclass SimpleCounter {
PROP(int count=0);
}REPC_SOURCE += simplecounter.rep#include <QCoreApplication>
#include "simplecounter.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
SimpleCounter simple_counter;
QRemoteObjectHost n(QUrl(QStringLiteral("local:replica")));
n.enableRemoting(&simple_counter);
return app.exec();
}
#include "simplecounter.h"
#include <QTimer>
SimpleCounter::SimpleCounter(QObject *parent) :
SimpleCounterSimpleSource(parent)
{
timer = new QTimer(this);
timer->setInterval(1000);
connect(timer, &QTimer::timeout, this, &SimpleCounter::timeout);
timer->start();
}
void SimpleCounter::timeout()
{
setCount(count() + 1);
}QT += remoteobjectsANDROID_EXTRA_LIBS = $$OUT_PWD/libserver.soREPC_REPLICA += simplecounter.repQRemoteObjectNode repNode;
QSharedPointer<SimpleCounterReplica> ptr;
repNode.connectToNode(QUrl(QStringLiteral("local:replica")));
ptr = QSharedPointer<SimpleCounterReplica>(repNode.acquire<SimpleCounterReplica>());
bool res = ptr->waitForSource();
QObject::connect(ptr.data(), &SimpleCounterReplica::countChanged, [](int count) {
qDebug() << "Count changed" << count;
});