How to get mobile app lifecycle events on QtApp - qt

I am programming an app in Qt 5.9.4 commercial license. My app runs on Android and iOS.
Question:
Is there a way in Qt to detect usual mobile device events like:
- Device display switched off
- Device went to background after user presses home button on iOS/Android
- back button pressed on Android etc
There are a bunch of these events that each of the platform Android and iOS trigger.
If there is class/module in Qt that is relaying these events back then I wouldn't have to do the extra work of writing native(java and objective-c) classes to get these events inside my QtApp.

Most of these events are handeled by Qt itself and you can get them through classical means. Qt tries to hide android specific stuff as good as possible and delivers those though events etc. as you would get them on a desktop application.
The back button press triggers a QCloseEvent that is sent to the primary window. You can install an event filter on the object from C++ it to intercept it. For qml it's the Window::closing signal.
Since Qt does not support background execution of activities, the background press is propably reported as close event as well - or it quits the application directly.
For the DIsplay switch of I don't now for sure, but maybe the QGuiApplication::applicationStateChanged signal does report it as Qt::ApplicationSuspended or another of those states - simply try it out! (this might be the case for other events as well)
Short Hint for Android: If you however want something Qt does not handle, you can always just create a custom Java activity that extends the QtActivity and use it in the manifest. From there on you can use the JNI to interact with Java from C++ and vice versa. If you need to do so, have a look at the Qt Android Extras - They make using the JNI much easier and provide a bunch of nice wrapper classes and utility methods in the QtAndroid namespace that can come in very handy.

Related

How notify user when my application is not running in qt?

I have a qt quick 2 application that I run it in android.Now I want to show message to my users ,For example I want to send a get Request to my server to find out "Is this user has any message from another user or not?" and if has new message show a notification to my user.This should be run when my application is not runnng.
But I didn't see any Class that i can do this in qt?
How can I Do this?
Qt for Android lists what you can do with Qt. Qt Android Extras includes classes that wrap the most important functions of few Android package methods, but is not intended to provide out of the box methods for everything in Android.
You can write Java Classes to implement detailed or specialized Android functions, those then can easily be implemented with Qt using the rich Android Extras JNI APIs.
In Qt Examples, Qt Notifier, serves very similar or same functionality you asking for.
You can run Android services (long running apps hiding user interface) , by Creating Android Services And QAndroidService Class

Using Qt classes natively in an Android application

The Android application I am about to work on has the UI in Java and the non-UI functionality in C++ that would be accessed via JNI. The C++ code uses some non-UI Qt classes. I am thinking I will spawn a thread in JNI_OnLoadthat essentially will instantiate and run QCoreApplication. Any subsequent JNI call will simply post an event to this thread. Is this possible? Regards.
What you want to do is definitely possible but a bit more difficult than it seems initially.
If you build your app end to end in Qt there's a lot of functionality you get for free from their framework that allows it to run on Android and a lot of that functionality/plumbing is wrapped up in their UI. So if you're not using their UI there's extra work that you need to do.
On Android their UI framework basically creates a native Activity and then uses that activity as a wrapper for the app. If you look at the low-level source for their UI thats what's happening on Android and it's what allows the Qt app to access local resources, the network, OS facilities, etc.
Without the Activity wrapper, your app will only be able to do simple, in-memory operations that require no OS, file system, or network access and also won't be able to make use of other Qt libraries(eg Qt5Sql, Qt5Core, etc).
Here's what we had to do to make this work in our java app:
Create a proxy wrapper Activity for Qt to use that shares the base
context of your app.
Create a QtActivityDelegate.
Set the proxy activity and delegate using the native Qt android
libraries. eg QtNavite.setActivity.
Instantiate and set a DexClassLoader using the same native Qt android libraries.
Load any Qt libraries using System.loadLibrary(..). Please note that the libraries need to be present on the file system already. This part was a big pain for us.
For your Qt Code, make sure you have proper wrappers written so that they can be used via jni. We ended up using swig to auto-generate java wrappers for our code.
You can find out more about swig here: http://swig.org/
After all that you should be able to use your Qt class/library from within a native Android app.
Painful but definitely possible!

How to run a PhoneGap app with Sqlite in Ripple?

I have a phongap app with a sqlite plugin that runs in both android and iphone. When I try to run it in Ripple i get several errors depending on the inclusion of the cordova version and device I use. Non of them are working at all. In some comments in stackoverflow i've seen people running sqlite in phonegap under ripple.
I'm using the PG-SQLitePlugin-Android plugin in my project, which it acually only supports Phonegap 2.7.0+.
I've found that i can force Ripple to use 2.7.0 by calling it :
file://localhost/Users/----/----/----/www/index.html?enableripple=cordova-2.7.0
Ripple actually loads great after enabling access to file system through chrome.
When i include cordova-2.7.0.js in my script
The index.html pops me a pop up with the following text :
gap:["Device","getDeviceInfo","Device119187522"]
that i can accept or cancel, then 2 more dialogs appeare, if I accept it gets hanged.
the js console shows that cordova 2.7.0 is really running :
Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only. cordova-2.7.0.js:906
deviceready is not fired
When i include cordova-2.9.0.js in my script
It happens the same as 2.7
Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only. cordova-2.7.0.js:906
but this time I get this other errors
Failed to load resource file://localhost/Users/laullobetpayas/-------/---/------/www/cordova/cordova_plugins.json
Failed to load resource file://localhost/Users/-------/---/------/www/cordova/cordova_plugins.js
deviceready is not fired
When I don't include any cordova.js in my script
SQLitePlugin.js:31
Uncaught ReferenceError: cordova is not defined SQLitePlugin.js:34
Am I using the proper plugin ?
which is the propper version of cordova / device tu run with the plugin and ripple ?
Do i have to include the cordova.js in my project
Hel will be very apreciated, it's for a long time that I'm trying to solve this.
Thank you in advanced.
Phonegap plugins won't work with Ripple because the idea of a Phonegap plugin is that it provides a Javascript interface in order to execute native code. That means, in the case of Android, the Javascript will invoke native Java code and in the case of iOS, the Javascript will invoke native Objective-C.
Ripple is purely Javascript-based, so the Javascript part of the plugin has nothing to interface with.
In the case of the SQLitePlugin, for example, calling SQLitePlugin.close() results in the call:
cordova.exec(null, null, "SQLitePlugin", "close", [this.dbname]);
where SQLitePlugin is the native class name and close is the native function name.
If you want to use the same storage API across Android, iOS and Ripple, maybe consider using lawnchair with appropriate adapters.
As for the issues with Ripple and Phonegap 2.7.0/2.9.0, Ripple has not quite caught up with Phonegap, so you will get these popups and error messages in the console, but that will not stop your Phonegap app (without native plugins) running in Ripple. You can convince yourself of this with a simple test case like:
document.addEventListener("deviceready", function(){
alert("I'm alive");
});
But the answer is, yes, you do need to include cordova.js in order for it to work at all in Ripple.
The Cordova-SQLitePlugin is a drop-in replacement for the HTML5 SQL API, so when running inside Ripple you don't need to call the Cordova layer you can just replace calls to sqlitePlugin.openDatabase() with window.openDatabase(). I've not yet tested this with Ripple but it should work. There are some database size limitations but this is probably all you need for testing.
There several ways to test if your inside Cordova. You could create a shim for the openDatabase() method based on testing for Cordova on app startup.
Since your primary goal is really to do rapid testing of SQLite with Cordova (rather than specifically to use Ripple) I'd like to suggest another new alternative to using Ripple.
I wrote an app call Sencha Touch Live that can be used for rapid development of Cordova / HTML5 apps by allowing you to Live Edit and Debug the HTML/JS/CSS code on your mobile device simply by updating files on your development computer - so you can skip most recompile/redeploy/restart debugger time costs. It has tons of other cool features. I'm using it myself for SQLite app testing instead of Ripple or Weinre
Detailed overview and Step by Step Guides
Installation Guide
It's based on the code from Adobe's PhoneGap Developer App so core code is well tested. It's been extensively adapted and tuned for Sench Touch framework though it should also work for jQuery Mobile or any framework that places HTML5 code under the phonegap/www or cordova/www folder. Just start up the server in you PhoneGap or Cordova project folder.
For testing your SQL and controller logic, I recommend using Geny Motion emulator with a version of Android 4.4.x KitKat. Start up an recent version of Chrome on your desktop and once you get your app working on the emulator or real device open chrome://inspect and now you can use the full Chrome debugger on your remote device app. You can also use a recent version of Safari for OSX/iPhone Simulator testing.
You can watch a demo here (starts at the 5 min. mark). Yes! It needs a more polished video with less echoes but you'll get the idea:
https://www.youtube.com/watch?v=94J4HBB0f7I

USB mouse hotplugging in DirectFB/QT Embedded

Is there any way to achieve hot-plugging of USB mouse in DirectFB 1.2.9 or Qt Embedded 4.7.3?
Currently my application stack is thus..
-----------------
GUI
-----------------
Qt Embedded 4.7.3
-----------------
DirectFB 1.2.9
-----------------
/dev/input/eventX
-----------------
DirectFB opens the Linux input device node. Qt uses a QSocketNotifier to wait on the DirectFB event buffer and sets up a slot to read the mouse data. But on hot-plugging, DirectFB does not open the device node and no mouse events are generated.
As far as I understand so far, hot-plugging is not supported by DirectFb..
I tried disabling DirectFB's handling of the Linux input device (removing the dev node from linux-input-devices= option in directfbrc), and set QWS_MOUSE_PROTO="linuxinput:.." but this did not work for some reason. Seems no mouse events were generated. Even if I manage to get it to work, I don't think QT provides any support for hot-plugging either.
So is my only alternative to sub-class QMouseDriverPlugin and QWSMouseHandle classes?. For this, I am yet to figure out how to make QT use the sub-classes I implement. i.e, Once I implement these classes how do I link them into the QT input device handling frame-work, so that I can set something like QWS_MOUSE_PROTO="mylinuxinput:.."?
As far as I can remember, I encountered no issue with mouse or keyboard hotplugging in Qt Embedded 4.7.2 (without DirectFB). If you want to subclass yourself, modify the plugin starting from the linuxinput plugin. You'll find that in Qt sources: this is the directory where the plugins are placed, but some classes are included in other directories.
Also, are you getting data in your linux device after pluggin in? Did you try to cat the device?

Qt: receive keyboard events when my application doesn't have focus

I am writing a Qt application. At the first stage I want to receive all key press events, system-wide, without creating any widgets.
Is this possible in Qt, or do I have to hook into the underlying window system? (This needs to be cross-platform.)

Resources