简介
在开发Qt for Android应用程序时,往往会需要用到获取Wifi相关信息的需求,比如要获取wifi名称、wifi信号强度等.针对该需求,本文以一个简单的Demo介绍如何通过调用android接口获取相关信息
获取方法
经过本人查阅相关资料,普遍介绍的方法有三种:
1> 通过QProcess以指令的方式进行获取, 如"netsh wlan show interfaces"指令(不推荐),有兴趣自行研究,可参考博客:https://zhuanlan.zhihu.com/p/520167870?utm_id=0
2> 调用Windows Api,这种不能到移动端,不推荐,自行研究,可参考博客:https://www.jianshu.com/p/fc15107cb92f
3> 通过android原生WifiManager获取,重点介绍这种方式.
获取步骤
1> 创建Qt Widget工程
这里创建工程的时候需要注意的是编译器要选择android的编译器
ps : 程序能正常运行的前提是Qt for android开发环境已正确配置好了,如果环境没有配置好(包括android sdk, ndk之类的), 自行百度配置好环境
2> 创建AndroidManifest.xml
qt creator提供了快捷的创建该文件的方法,如图所示,点击项目左侧边栏项目按钮,然后点击创建模板即可
3> 将AndroidManifest.xml添加到工程
在项目上右键,选择添加现有文件
添加完成后完整目录结构应当如图所示
4> 添加java接口文件
在android目录添加上MyWifi.java文件,使目录结构如图所示
5> 编写java代码
java
package com.MyWifi;
import org.qtproject.qt.android.bindings.QtActivity;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import java.util.List;
import android.os.Message;
import android.os.Handler;
import android.os.Bundle;
import android.net.wifi.WifiInfo;
public class MyWifi extends org.qtproject.qt.android.bindings.QtActivity
{
private static MyWifi m_instance;
private WifiManager wifiManager;
List<ScanResult> listb;
public MyWifi() {
m_instance = this;
}
public String[] callExternalCamera()
{
System.out.println("I an In");
wifiManager = (WifiManager)getSystemService(WIFI_SERVICE);
if(!wifiManager.isWifiEnabled()){
if(wifiManager.getWifiState() != WifiManager.WIFI_STATE_ENABLING) {
wifiManager.setWifiEnabled(true);
}
}
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
// 获取当前连接的wifi的信息
StringBuffer sb = new StringBuffer();
sb.append("SSID: ");
sb.append(wifiInfo.getSSID());
System.out.println(sb);
// 获取wifi列表信息
listb = wifiManager.getScanResults();
String[] listk = new String[listb.size()];
String res = " %";
if(listb!=null){
for( int i=0;i<listb.size();i++){
ScanResult scanResult = listb.get(i);
listk[i] = scanResult.SSID;
System.out.println(scanResult.SSID);
res += scanResult.SSID + "%";
System.out.println(scanResult.level);
}
return listk;
}
return listk;
}
}
这里需要注意包名和类名需要和android/src目录下文件目录和文件名对应.
6> 编写c++调用代码
c++
#include <QJniObject>
#include <QJniEnvironment>
#include <QDebug>
void Dialog::getScanResult()
{
#ifdef Q_OS_ANDROID
QJniEnvironment env;
QJniObject activity = QNativeInterface::QAndroidApplication::context();
QJniObject str = activity.callObjectMethod("callExternalCamera", "()[Ljava/lang/String;");
jobjectArray objectArray = str.object<jobjectArray>();
const int n = env->GetArrayLength(objectArray);
for (int i = 0; i < n; ++i) {
QJniObject element = env->GetObjectArrayElement(objectArray, i);
}
if(env->ExceptionCheck()){
env->ExceptionDescribe();
env->ExceptionClear();
}
#endif
}
这里需要注意的是以上代码是Qt6的写法,Qt5对应的QJniObject、QJniEnvironment、QAndroidApplication不叫这个名字;Qt5代码可以参考:
https://blog.csdn.net/weixin_30617561/article/details/96271573
7> 修改AndroidManifest.xml
xml
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.qtproject.example" android:installLocation="auto" android:versionCode="-- %%INSERT_VERSION_CODE%% --" android:versionName="-- %%INSERT_VERSION_NAME%% --">
<!-- %%INSERT_PERMISSIONS -->
<!-- %%INSERT_FEATURES -->
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true"/>
<application android:name="org.qtproject.qt.android.bindings.QtApplication" android:hardwareAccelerated="true" android:label="-- %%INSERT_APP_NAME%% --" android:requestLegacyExternalStorage="true" android:allowNativeHeapPointerTagging="false" android:allowBackup="true" android:fullBackupOnly="false">
<activity android:name="com.MyWifi.MyWifi" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:label="-- %%INSERT_APP_NAME%% --" android:launchMode="singleTop" android:screenOrientation="unspecified" android:exported="true">
<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.arguments" android:value="-- %%INSERT_APP_ARGUMENTS%% --"/>
<meta-data android:name="android.app.extract_android_style" android:value="minimal"/>
</activity>
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"/>
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
</manifest>
需要注意的是权限的添加,需要以下四个权限:
运行即可得到wifi信息!