Android notification not shown
-
Hello!
I'm building an Android app using Qt. I'm currently trying to implement notifications. Using the Qt Notifier example everything runs fine. However, trying to apply that to my app is not working.
There are no errors occuring when compiling and running the app, but when the notification is supposed to be shown, nothing happens. Also, in Settings->Apps->MyApp I can see no notification settings are available.
Are there any general things to consider when trying to create notifications?
As said above, no error message or anything is displayed. It seems to run just fine, with the exception that no notification i displayed.
-
I also want o add that I think it might be the R.drawable.icon that might be the problem. Or the fact that Android 9.0 is having other reqs to show a notification.
I'm having the below java code being run on when notification is to be shown:
public static void notify(String s) { if (m_notificationManager == null) { m_notificationManager = (NotificationManager)m_instance.getSystemService(Context.NOTIFICATION_SERVICE); m_builder = new Notification.Builder(m_instance); m_builder.setSmallIcon(R.drawable.icon); m_builder.setContentTitle("A message from Qt!"); } m_builder.setContentText(s); m_notificationManager.notify(1, m_builder.build()); }
However, it seems to not trigger a notification. When I run the Qt Notifier example, using the same code, it is triggering a notification. Something's wrong with the icon? I'm using the same icon, but still it's not working.
-
If the Qt example code runs with the same icon, in the same device, then the problem is elsewhere. I'd check the Manifest and the details of how you use Java in your app. I think any such configuration problems might not show errors when compiling or even during debugging - but a debugger run should anyway be the first thing to do, for any error messages produced.
-
Related to the signature from the QAndroidJniObject possibly?
QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/notification/NotificationClient", "notify", "(Ljava/lang/String;)V", javaNotification.object<jstring>());
I assume the org/qtproject/example/notification/NotificationClient needs to be changed for your App, but not completely sure what it needs to be the package name or something different, my own experimenting failed a few times
-
Hi @adddeeee
I tried the same Qt Notifier Example few days back, It is not working with Latest Version of Android.
Can you please try with Android 7 or lesser once ?@Allstar12345 the Qt Notifier example has same code.
QAndroidJniObject javaNotification = QAndroidJniObject::fromString(m_notification); QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/notification/NotificationClient", "notify", "(Ljava/lang/String;)V", javaNotification.object<jstring>());
-
Hi! Thanks for replying!
The demo runs fine on Android 9 in my case.
My guess is that something is not linked correctly with the icon.
The package name has been changed in the app, to reflect the path in the project.
Anyone else tried to apply the demo in an app?
-
Here's some more code...
Notification.pro (example from Qt):
QT += quick androidextras ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-sources SOURCES += \ main.cpp \ notificationclient.cpp OTHER_FILES += \ qml/main.qml \ android-sources/src/org/qtproject/example/notification/NotificationClient.java \ android-sources/AndroidManifest.xml RESOURCES += \ main.qrc HEADERS += \ notificationclient.h target.path = $$[QT_INSTALL_EXAMPLES]/androidextras/notification INSTALLS += target
My .pro file:
QT += quick androidextras ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android SOURCES += \ main.cpp \ notificationclient.cpp OTHER_FILES += \ android/src/org/stryktips/stryket/NotificationClient.java \ android/AndroidManifest.xml \ android/res/drawable/icon.png RESOURCES += \ qml.qrc HEADERS += \ notificationclient.h qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
Notification example main.cpp:
#include <QtGui> #include <QtQuick> #include "notificationclient.h" int main(int argc, char **argv) { QGuiApplication app(argc, argv); QQuickView view; NotificationClient *notificationClient = new NotificationClient(&view); view.engine()->rootContext()->setContextProperty(QLatin1String("notificationClient"), notificationClient); view.setResizeMode(QQuickView::SizeRootObjectToView); view.setSource(QUrl(QStringLiteral("qrc:/qml/main.qml"))); view.show(); return app.exec(); }
My main.cpp:
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "notificationclient.h" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; NotificationClient *notificationClient = new NotificationClient(); engine.rootContext()->setContextProperty(QLatin1String("MyNotificationClient"), notificationClient); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; return app.exec(); }
Notification example notification.cpp:
#include "notificationclient.h" #include <QtAndroidExtras/QAndroidJniObject> NotificationClient::NotificationClient(QObject *parent) : QObject(parent) { connect(this, SIGNAL(notificationChanged()), this, SLOT(updateAndroidNotification())); } void NotificationClient::setNotification(const QString ¬ification) { if (m_notification == notification) return; m_notification = notification; emit notificationChanged(); } QString NotificationClient::notification() const { return m_notification; } void NotificationClient::updateAndroidNotification() { QAndroidJniObject javaNotification = QAndroidJniObject::fromString(m_notification); QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/notification/NotificationClient", "notify", "(Ljava/lang/String;)V", javaNotification.object<jstring>()); }
My notification.cpp:
#include "notificationclient.h" #include <QtAndroidExtras/QAndroidJniObject> NotificationClient::NotificationClient(QObject *parent) : QObject(parent) { connect(this, SIGNAL(notificationChanged()), this, SLOT(updateAndroidNotification())); } void NotificationClient::setNotification(const QString ¬ification) { if (m_notification == notification) return; m_notification = notification; emit notificationChanged(); } QString NotificationClient::notification() const { return m_notification; } void NotificationClient::updateAndroidNotification() { QAndroidJniObject javaNotification = QAndroidJniObject::fromString(m_notification); QAndroidJniObject::callStaticMethod<void>("org/stryktips/stryket/NotificationClient", "notify", "(Ljava/lang/String;)V", javaNotification.object<jstring>()); }
AndroidManifest.xml of the Notification example:
<?xml version="1.0"?> <manifest package="org.qtproject.example.notification" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto"> <application android:icon="@drawable/icon" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="@string/app_name"> <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.example.notification.NotificationClient" android:label="Qt Notifier" android:screenOrientation="unspecified"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/> <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/> <meta-data android:name="android.app.repository" android:value="default"/> <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/> <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/> <!-- Deploy Qt libs as part of package --> <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/> <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/> <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/> <!-- Run with local libs --> <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/> <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/> <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/> <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/> <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/> <!-- Messages maps --> <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/> <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/> <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/> <!-- Messages maps --> <!-- Splash screen --> <!-- <meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/> --> <!-- Splash screen --> </activity> </application> <uses-sdk android:minSdkVersion="16"/> <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> <!-- %%INSERT_PERMISSIONS --> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!-- %%INSERT_FEATURES --> <uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> </manifest>
My AndroidManifest.xml:
<?xml version="1.0"?> <manifest package="org.stryktips.stryket" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto"> <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Stryket" android:icon="@drawable/icon"> <activity 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="Stryket" android:screenOrientation="unspecified" android:launchMode="singleTop"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <!-- Application arguments --> <!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ --> <!-- Application arguments --> <meta-data android:name="android.app.lib_name" android:value="Stryket"/> <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/> <meta-data android:name="android.app.repository" android:value="default"/> <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/> <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/> <!-- Deploy Qt libs as part of package --> <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/> <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/> <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/> <!-- Run with local libs --> <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/> <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/> <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/> <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/> <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/> <!-- Used to specify custom system library path to run with local system libs --> <!-- <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/> --> <!-- Messages maps --> <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/> <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/> <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/> <!-- Messages maps --> <!-- Splash screen --> <!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ --> <!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ --> <!-- Splash screen --> <!-- Background running --> <!-- Warning: changing this value to true may cause unexpected crashes if the application still try to draw after "applicationStateChanged(Qt::ApplicationSuspended)" signal is sent! --> <meta-data android:name="android.app.background_running" android:value="false"/> <!-- Background running --> <!-- auto screen scale factor --> <meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/> <!-- auto screen scale factor --> <!-- extract android style --> <!-- available android:values : * default - In most cases this will be the same as "full", but it can also be something else if needed, e.g., for compatibility reasons * full - useful QWidget & Quick Controls 1 apps * minimal - useful for Quick Controls 2 apps, it is much faster than "full" * none - useful for apps that don't use any of the above Qt modules --> <meta-data android:name="android.app.extract_android_style" android:value="default"/> <!-- extract android style --> </activity> <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices --> </application> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="24"/> <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application. Remove the comment if you do not require these default permissions. --> <!-- %%INSERT_PERMISSIONS --> <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application. Remove the comment if you do not require these default features. --> <!-- %%INSERT_FEATURES --> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> </manifest>
Have I gone blind??
I have created the folder "drawable" and put it in "android/res" and in "android/res/drawable" I put the icon from the example.
Also, my NotificationClient.java is placed in "android\src\org\stryktips\stryket". Which would correspond to the path where we expect to find the NotificationClient constructor. Also, the compiler does find the constructor, so the path seems to be fine.
Any suggestions?