<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[SD card removed notification]]></title><description><![CDATA[<p dir="auto">Hi,</p>
<p dir="auto">I tried to implement a notification of SD card removal in my application on Android. There is a <a href="https://www.kdab.com/qt-android-episode-6/" target="_blank" rel="noopener noreferrer nofollow ugc">sample app and guide</a>  to do it. The sample works for me, but I stops working if I try to implement it in my application.</p>
<p dir="auto">I tried to change the sample app to meet my needs and at one point it stopped working too. Basically the Java part works OK and even the callback to C++ on Android UI thread works. Originally it is implemented like this:</p>
<pre><code>// native.cpp
#include &lt;jni.h&gt;
 #include &lt;QMetaObject&gt;
 #include "mainwindow.h"
 
/static void onReceiveNativeMounted(JNIEnv * /*env*/, jobject /*obj*/)
{
    QMetaObject::invokeMethod(&amp;MainWindow::instance(), "onReceiveMounted"
                              , Qt::QueuedConnection);
}
</code></pre>
<p dir="auto">Then there is the <strong>mainwindow</strong> class:</p>
<pre><code>// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include &lt;QMainWindow&gt;
 
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    static MainWindow &amp;instance(QWidget *parent = 0);
 
public slots:
    void onReceiveMounted();
    void onReceiveUnmounted();
 
private:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
 
private:
    Ui::MainWindow *ui;
};
</code></pre>
<p dir="auto">This construction works. Now all I did was to create my own class called <strong>AndroidLib</strong> and call it from the <strong>native.cpp</strong>. The modified part looks like this:</p>
<pre><code>#include "androidlib.h"
 
static void onReceiveNativeMounted(JNIEnv * /*env*/, jobject /*obj*/)
{
    QMetaObject::invokeMethod(&amp;AndroidLib::instance(), "onReceiveMounted"
                              , Qt::QueuedConnection);
}
</code></pre>
<p dir="auto">The AndroidLib class looks almost identical to the former MainWindows class:</p>
<pre><code>#ifndef ANDROIDLIB_H
#define ANDROIDLIB_H

#include &lt;QObject&gt;
#include &lt;QDebug&gt;

class AndroidLib : public QObject
{
    Q_OBJECT
public:
    explicit AndroidLib(QObject *parent = nullptr);
    static AndroidLib &amp;instance(QObject *parent = 0);

/*private:
    explicit AndroidLib(QObject *parent = nullptr);*/

public slots:
    void onReceiveMounted();
    void onReceiveUnmounted();

signals:
    void sdMount(const bool mounted);
};

#endif // ANDROIDLIB_H

</code></pre>
<p dir="auto">The function in <strong>native.cpp</strong> is called. Even the function <strong>AndroidLib::instance()</strong> is called. But the function <strong>onReceiveMounted()</strong> in AndroidLib is not called.</p>
<p dir="auto">Is there something wrong in the command</p>
<pre><code>/QMetaObject::invokeMethod(&amp;AndroidLib::instance(), "onReceiveMounted", Qt::QueuedConnection);
</code></pre>
<p dir="auto">which causes that the function is not executed?</p>
<p dir="auto">Thanks a lot for any advice regarding this issue.</p>
]]></description><link>https://forum.qt.io/topic/84892/sd-card-removed-notification</link><generator>RSS for Node</generator><lastBuildDate>Sat, 25 Apr 2026 12:36:52 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/84892.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 09 Nov 2017 14:06:17 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to SD card removed notification on Thu, 09 Nov 2017 16:11:30 GMT]]></title><description><![CDATA[<p dir="auto">The implementation can be found in the <a href="https://www.kdab.com/qt-android-episode-7/" target="_blank" rel="noopener noreferrer nofollow ugc">guide</a> I mentioned in the beginning. It looks like this:</p>
<pre><code>MainWindow &amp;MainWindow::instance(QWidget *parent)
{
    static MainWindow mainWindow(parent);
    return mainWindow;
}
</code></pre>
<p dir="auto">There is also explained, why it is a little bit more difficult then one would expect.</p>
<p dir="auto">The problem is that the function in native.cpp is executed in Android UI thread and I need to call the function in AndroidLib so that it is called in Qt main loop.</p>
<p dir="auto">After many trial and errors I finally made it to work although I'm not sure why. I found out that if I called the function in AndroidLib directly from main.cpp. Then it was executed. So I implemented a signal and connected it to the class when I needed the information. But that didn'T work.</p>
<p dir="auto">Now I've used this in my code:</p>
<pre><code>QObject::connect(&amp;AndroidLib::instance(), SIGNAL(sdMount(bool)), qmltocpp, SLOT(sdMount(bool)));
</code></pre>
<p dir="auto">And it works!!!! The function in AndroidLib is called, the signal is emitted and received in my qmltocpp class. Because C++ doesn't have a garbage collector, I hope the AndroidLib instance will not be destroyed. And I can always get the reference to it by calling the static <strong>instance()</strong> function. The constructor is now a private function as in the example. Maybe that was the trick, I'm really confused.</p>
<p dir="auto">Now I need to move it to a service. That will be the next task. So the problem is solved but I still have no idea why it didn't work earlier and now it works.</p>
]]></description><link>https://forum.qt.io/post/425106</link><guid isPermaLink="true">https://forum.qt.io/post/425106</guid><dc:creator><![CDATA[vlada]]></dc:creator><pubDate>Thu, 09 Nov 2017 16:11:30 GMT</pubDate></item><item><title><![CDATA[Reply to SD card removed notification on Thu, 09 Nov 2017 15:26:49 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/vlada">@<bdi>vlada</bdi></a><br />
How is <code>AndroidLib::instance()</code> exactly implemented?<br />
The fact that you need to use a reference (<code>&amp;AndroidLib::instance()</code>) of the returned object seems a bit odd.<br />
If you return an object allocated on the stack the function call will never happen, since it is destroyed before.</p>
]]></description><link>https://forum.qt.io/post/425094</link><guid isPermaLink="true">https://forum.qt.io/post/425094</guid><dc:creator><![CDATA[raven-worx]]></dc:creator><pubDate>Thu, 09 Nov 2017 15:26:49 GMT</pubDate></item></channel></rss>