Compare commits

...

9 Commits

Author SHA1 Message Date
Roberto Viola
a4f2613c7a Update main.qml 2025-07-11 16:17:09 +02:00
Roberto Viola
1ca3b8a65c Update main.yml 2025-07-11 15:09:17 +02:00
Roberto Viola
dbd8fa4a4c debug 2025-07-11 14:48:09 +02:00
Roberto Viola
18c155fed0 Update homeform.cpp 2025-07-11 13:34:17 +02:00
Roberto Viola
54e2b4fa7f Merge branch 'android-not-fullscreen-nomedia' of https://github.com/cagnulein/qdomyos-zwift into android-not-fullscreen-nomedia 2025-07-11 13:19:15 +02:00
Roberto Viola
ab73e3dfdd debug 2025-07-11 13:17:37 +02:00
Roberto Viola
1133404e87 old system with offset 2025-07-11 12:04:29 +02:00
Roberto Viola
c17852de9c Update CustomQtActivity.java 2025-07-11 10:20:30 +02:00
Roberto Viola
ee0d00012a Hide QZ files from Android gallery and update UI flags
Added createNoMediaFiles() to generate .nomedia files in the QZ directory and its subdirectories, preventing media scanning on Android. Updated CustomQtActivity to keep the status bar visible for notification access while hiding only the navigation bar.
2025-07-11 09:24:17 +02:00
6 changed files with 133 additions and 38 deletions

View File

@@ -750,7 +750,7 @@ jobs:
adb shell pm grant org.cagnulen.qdomyoszwift android.permission.WRITE_EXTERNAL_STORAGE || true
# Start the main activity
adb shell am start -n org.cagnulen.qdomyoszwift/org.cagnulen.qdomyoszwift.CustomQtActivity
adb shell am start -n org.cagnulen.qdomyoszwift/org.cagnulen.qdomyoszwift.QtActivity
# Wait for app to start
sleep 60

View File

@@ -10,7 +10,7 @@
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<application android:hardwareAccelerated="true" android:debuggable="false" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="qdomyos-zwift" android:extractNativeLibs="true" android:icon="@drawable/icon" android:usesCleartextTraffic="true">
<activity android:theme="@style/Theme.AppCompat" android:exported="true" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name="org.cagnulen.qdomyoszwift.CustomQtActivity" android:label="QZ" android:launchMode="singleTop">
<activity android:theme="@style/Theme.AppCompat" android:exported="true" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="QZ" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>

View File

@@ -1,34 +0,0 @@
package org.cagnulen.qdomyoszwift;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import org.qtproject.qt5.android.bindings.QtActivity;
public class CustomQtActivity extends QtActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Handle Android 16 API 36 WindowInsetsController for fullscreen support
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// Android 11 (API 30) and above - use WindowInsetsController
getWindow().setDecorFitsSystemWindows(false);
WindowInsetsController controller = getWindow().getDecorView().getWindowInsetsController();
if (controller != null) {
controller.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
}
} else {
// Fallback for older Android versions (API < 30)
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
}
}
}

View File

@@ -779,6 +779,9 @@ homeform::homeform(QQmlApplicationEngine *engine, bluetooth *bl) {
"registerReceiver",
"(Landroid/content/Context;)V",
QtAndroid::androidContext().object());
// Create .nomedia files to hide QZ files from Android gallery
createNoMediaFiles();
#endif
bluetoothManager->homeformLoaded = true;
@@ -8253,6 +8256,33 @@ QString homeform::getAndroidDataAppDir() {
path = out;
return out;
}
void homeform::createNoMediaFiles() {
QString rootPath = getWritableAppDir();
// Create .nomedia file in root QZ directory
QString noMediaPath = rootPath + QStringLiteral(".nomedia");
QFile noMediaFile(noMediaPath);
if (!noMediaFile.exists()) {
noMediaFile.open(QIODevice::WriteOnly);
noMediaFile.close();
}
// Create .nomedia files in all subdirectories
QDir rootDir(rootPath);
if (rootDir.exists()) {
QStringList subDirs = rootDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const QString &subDir : subDirs) {
QString subDirPath = rootPath + subDir + QStringLiteral("/");
QString subNoMediaPath = subDirPath + QStringLiteral(".nomedia");
QFile subNoMediaFile(subNoMediaPath);
if (!subNoMediaFile.exists()) {
subNoMediaFile.open(QIODevice::WriteOnly);
subNoMediaFile.close();
}
}
}
}
#endif
quint64 homeform::cryptoKeySettingsProfiles() {
@@ -8268,6 +8298,72 @@ quint64 homeform::cryptoKeySettingsProfiles() {
return v;
}
#ifdef Q_OS_ANDROID
int homeform::getStatusBarHeight() {
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if (activity.isValid()) {
QAndroidJniObject resources = activity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
if (resources.isValid()) {
jint resourceId = resources.callMethod<jint>("getIdentifier", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
QAndroidJniObject::fromString("status_bar_height").object<jstring>(),
QAndroidJniObject::fromString("dimen").object<jstring>(),
QAndroidJniObject::fromString("android").object<jstring>());
if (resourceId > 0) {
jint result = resources.callMethod<jint>("getDimensionPixelSize", "(I)I", resourceId);
qDebug() << "Status bar height (pixels):" << result;
return result;
} else {
qDebug() << "Status bar height resource not found";
}
} else {
qDebug() << "Resources object invalid";
}
} else {
qDebug() << "Activity object invalid";
}
qDebug() << "Status bar height: returning 0 (fallback)";
return 0;
}
int homeform::getAndroidApiLevel() {
jint apiLevel = QAndroidJniObject::getStaticField<jint>("android/os/Build$VERSION", "SDK_INT");
qDebug() << "Android API level:" << apiLevel;
return apiLevel;
}
QString homeform::getAndroidDebugInfo() {
int statusBarHeight = getStatusBarHeight();
int apiLevel = getAndroidApiLevel();
QString info = QString("Android Debug Info:\n");
info += QString("API Level: %1\n").arg(apiLevel);
info += QString("Status Bar Height: %1px\n").arg(statusBarHeight);
// Get screen dimensions
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if (activity.isValid()) {
QAndroidJniObject windowManager = activity.callObjectMethod("getWindowManager", "()Landroid/view/WindowManager;");
if (windowManager.isValid()) {
QAndroidJniObject display = windowManager.callObjectMethod("getDefaultDisplay", "()Landroid/view/Display;");
if (display.isValid()) {
QAndroidJniObject metrics = QAndroidJniObject("android/util/DisplayMetrics");
display.callMethod<void>("getMetrics", "(Landroid/util/DisplayMetrics;)V", metrics.object());
int width = metrics.getField<jint>("widthPixels");
int height = metrics.getField<jint>("heightPixels");
float density = metrics.getField<jfloat>("density");
info += QString("Screen: %1x%2px\n").arg(width).arg(height);
info += QString("Density: %1\n").arg(density);
}
}
}
qDebug() << info;
return info;
}
#endif
void homeform::saveSettings(const QUrl &filename) {
Q_UNUSED(filename)
QString path = getWritableAppDir();

View File

@@ -521,6 +521,13 @@ class homeform : public QObject {
Q_INVOKABLE static QString getProfileDir();
Q_INVOKABLE static void clearFiles();
#ifdef Q_OS_ANDROID
static void createNoMediaFiles();
Q_INVOKABLE int getStatusBarHeight();
Q_INVOKABLE int getAndroidApiLevel();
Q_INVOKABLE QString getAndroidDebugInfo();
#endif
double wattMaxChart() {
QSettings settings;
if (bluetoothManager && bluetoothManager->device() &&

View File

@@ -13,10 +13,18 @@ ApplicationWindow {
id: window
width: 640
height: 480
visibility: Qt.WindowFullScreen
visibility: (OS_VERSION === "Android" && statusBarOffset > 0) ? Qt.WindowMaximized : Qt.WindowFullScreen
visible: true
objectName: "stack"
title: qsTr("qDomyos-Zwift")
// Android status bar offset (only for Android API 31+ / Android 12+)
property int statusBarOffset: {
if (OS_VERSION === "Android" && rootItem.getAndroidApiLevel() >= 31) {
return rootItem.getStatusBarHeight()
}
return 0
}
signal gpx_open_clicked(url name)
signal gpxpreview_open_clicked(url name)
@@ -47,6 +55,23 @@ ApplicationWindow {
property bool lockTiles: false
property bool settings_restart_to_apply: false
// Debug Android status bar
property int androidApiLevel: 0
property int statusBarHeight: 0
Component.onCompleted: {
if(OS_VERSION === "Android") {
console.log("Calling Android debug functions...")
try {
androidApiLevel = rootItem.getAndroidApiLevel()
statusBarHeight = rootItem.getStatusBarHeight()
console.log("Debug values set: API=" + androidApiLevel + ", StatusBar=" + statusBarHeight)
} catch (e) {
console.log("Error calling Android functions:", e)
}
}
}
Settings {
id: settings
@@ -909,6 +934,7 @@ ApplicationWindow {
id: stackView
initialItem: "Home.qml"
anchors.fill: parent
anchors.topMargin: statusBarOffset
focus: true
Keys.onVolumeUpPressed: (event)=> { console.log("onVolumeUpPressed"); volumeUp(); event.accepted = settings.volume_change_gears; }
Keys.onVolumeDownPressed: (event)=> { console.log("onVolumeDownPressed"); volumeDown(); event.accepted = settings.volume_change_gears; }
@@ -924,5 +950,5 @@ ApplicationWindow {
event.accepted = settings.volume_change_gears;
}
}
}
}