Native android code with QT
-
Hi guys
I am trying to get name of wifi connected to my mobile using QAndroidJniObject.
My code is
.java
public class QtAndroidToastJava extends QtActivity { public String getWifiName(Context context) { WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); if (manager.isWifiEnabled()) { WifiInfo wifiInfo = manager.getConnectionInfo(); if (wifiInfo != null) { DetailedState state = WifiInfo.getDetailedStateOf(wifiInfo.getSupplicantState()); if (state == DetailedState.CONNECTED || state == DetailedState.OBTAINING_IPADDR) { return wifiInfo.getSSID(); } } } return null; } }
and my cpp file is
#include "wificlass.h" #include <QtAndroid> #include <QDebug> WIFICLASS::WIFICLASS(QObject *parent) : QObject(parent) { } void WIFICLASS::updateAndroidNotification() { //QAndroidJniObject tstMsg = QAndroidJniObject::fromString("Hello world! :)"); QAndroidJniObject::callStaticMethod <void>("com/amin/QtAndroidToastJava/QtAndroidToastJava", "sMakeToast", "(Ljava/lang/String;)J"); **qDebug()<<"here I want a string which is returned by java file"<<????;** }
My problem is how I can get a string from java class in My cpp file
My java class is returning return wifiInfo.getSSID(); and I want that to be displayed from cpp file in place of this
qDebug()<<"here I want a string which is returned by java file"<<????; -
You call wrong method:
sMakeToast
instead ofgetWifiName
.You're not checking reading the return value. Use this syntax:
auto returnString = QAndroidJniObject::callStaticMethod <jstring>("com/amin/QtAndroidToastJava/QtAndroidToastJava", "getWifiName", "(Ljava/lang/String;)J");
Lastly, you declare that method has a String argument
"(Ljava/lang/String;)J"
, but you fail to provide it's value (it should be provided as following argument to callStaticMethod).By the way, that method does not need an argument.
public String getWifiName(Context context)
. You can get the context from QtActivity. -
@sierdzio I am getting this error
auto returnString = QAndroidJniObject::callStaticMethod <jstring>("com/amin/QtAndroidToastJava/QtAndroidToastJava", "getWifiName");
// QString user = juser.toString();
qDebug()<<returnString;C:\ASHISH\PROGRAMS\Wifipoc\wificlass.cpp:24: error: undefined reference to '_jstring QAndroidJniObject::callStaticMethod<_jstring>(char const*, char const*)**
-
You do need to provide type information. If you removed the context from your Java file, then that info would read
(V;)Ljava/lang/String
(no arguments + return string).One more nitpick: you're calling
callStaticMethod
but your Java method is not static. -
ok sir
@sierdzioNow I have made following changes
package com.amin.QtAndroidToastJava; import org.qtproject.qt5.android.bindings.QtApplication; import org.qtproject.qt5.android.bindings.QtActivity; import android.net.NetworkInfo.DetailedState; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.app.Activity; import android.content.Context; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class QtAndroidToastJava extends QtActivity { public static String getWifiName(Context context) { WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); if (manager.isWifiEnabled()) { WifiInfo wifiInfo = manager.getConnectionInfo(); if (wifiInfo != null) { DetailedState state = WifiInfo.getDetailedStateOf(wifiInfo.getSupplicantState()); if (state == DetailedState.CONNECTED || state == DetailedState.OBTAINING_IPADDR) { return wifiInfo.getSSID(); } } } return null; }
/////////////////////////////////////
#include "wificlass.h" #include <QtAndroid> #include <QDebug> WIFICLASS::WIFICLASS(QObject *parent) : QObject(parent) { } void WIFICLASS::updateAndroidNotification() { auto returnString = QAndroidJniObject::callStaticMethod <jstring>("com/amin/QtAndroidToastJava/QtAndroidToastJava", "getWifiName","(V;)Ljava/lang/String"); //QString user = juser.toString(); qDebug()<<returnString; }
After running I am getting this error
..\Wifipoc/wificlass.cpp:23: error: undefined reference to '_jstring QAndroidJniObject::callStaticMethod<_jstring>(char const*, char const*, char const*, ...)'
collect2.exe: error: ld returned 1 exit status
make: *** [libWifipoc.so] Error 1
17:34:55: The process "C:\ASHISH\android-ndk-r15c\prebuilt\windows-x86_64\bin\make.exe" exited with code 2.
Error while building/deploying project Wifipoc (kit: Android for armeabi-v7a (GCC 4.9, Qt 5.11.2 for Android ARMv7))
When executing step "Make"
17:34:55: Elapsed time: 00:06.** -
Hm, looks like the static method call needs a jclass instead of string. Weird.
Try this:
jclass myClass = "com/amin/QtAndroidToastJava/QtAndroidToastJava"; auto returnString = QAndroidJniObject::callStaticMethod <jstring>( myClass, "getWifiName", "(V)Ljava/lang/String;");
-
Hi sir @sierdzio
What I did is in my cpp file I added this lineQAndroidJniObject returnString = QAndroidJniObject::callStaticObjectMethod("org/qtproject/example/QtAndroidToastJava","getWifiName","(Landroid/content/Context)",QtAndroid::androidContext().object());
As I am using getWifiName(Context context) function it requires context from cpp.
What I did is I added "(Landroid/content/Context)",QtAndroid::androidContext().object()); to check if it works but it is throwing these errors:W System.err: java.lang.NoSuchMethodError: no static method "Lorg/qtproject/example/QtAndroidToastJava;.getWifiName(Landroid/content/Context)"
W System.err: at org.qtproject.qt5.android.QtNative.startQtApplication(Native Method)
W System.err: at org.qtproject.qt5.android.QtNative$6.run(QtNative.java:359)
W System.err: at org.qtproject.qt5.android.QtThread$1.run(QtThread.java:61)I think I am making some mistake in this line "(Landroid/content/Context)",QtAndroid::androidContext().object());"
how can I figure out what I should pass or where its getting wrong?
-
@ashajg said in Native android code with QT:
how can I figure out what I should pass or where its getting wrong?
Only by guessing, unfortunately. JNI is not clever enough to point our errors exactly.
"(Landroid/content/Context)"
- no return type (your method returns a string).I did tell you to drop the context arg, by the way. But if you want to keep it - so be it.
-
ok Sir
I ll also try thisjclass myClass = "com/amin/QtAndroidToastJava/QtAndroidToastJava";
auto returnString = QAndroidJniObject::callStaticMethod <jstring>(
myClass, "getWifiName", "(V)Ljava/lang/String;");it is saying cannot initialize a variable with jclass..
-
you asked to drop context so should I just write the code like this
public class QtAndroidToastJava extends QtActivity { public String getWifiName(){ WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); if (manager.isWifiEnabled()) { WifiInfo wifiInfo = manager.getConnectionInfo(); if (wifiInfo != null) { DetailedState state = WifiInfo.getDetailedStateOf(wifiInfo.getSupplicantState()); if (state == DetailedState.CONNECTED || state == DetailedState.OBTAINING_IPADDR) { return wifiInfo.getSSID(); } } }
its throwing error
symbol: variable context
location: class QtAndroidToastJava
Note: Some input files use or override a deprecated API. if I remove context -
I am trying to do the same thing. But
auto returnString = QAndroidJniObject::callStaticMethod <jstring>(
myClass, "getWifiName", "(V)Ljava/lang/String;");
causes compiling error.
undefined reference to `_jstring* QAndroidJniObject::callStaticMethod<_jstring*>(char const*, char const*, char const*, ...)
QAndroidJniObject::callStaticMethod <jstring> is dropped? I tried int and func call works.I checked the doc of Qt5
https://doc.qt.io/qt-5/qandroidjniobject.html
// C++ code
QAndroidJniObject stringNumber = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/TestClass",
"fromNumber"
"(I)Ljava/lang/String;",
10);
should be work. But the call in my app returns empty object.
My Qt version: 5.15.2 and OS: Ubuntu 18.04