Skip to content

Commit

Permalink
Show IPv6 addresses on Android
Browse files Browse the repository at this point in the history
For #34
The Qt actually supports IPv6 address, but the IPv6 addresses are not
shown by calling QNetworkInterface::allAddresses() on Android.
I guess it's caused by the lack of the permission of accessing
/proc/net/dev. I have to write some Java code for it.
  • Loading branch information
wh201906 committed Jun 16, 2023
1 parent 1bd23bf commit 03a0e79
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 8 deletions.
28 changes: 27 additions & 1 deletion src/android/java/priv/wh201906/serialtest/MainActivity.java
Expand Up @@ -11,9 +11,15 @@
import android.bluetooth.*;
import android.os.Process;

import java.util.Set;
import java.lang.String;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.net.NetworkInterface;
import java.net.InetAddress;
import java.net.Inet6Address;
import java.net.SocketException;

public class MainActivity extends QtActivity
{
Expand Down Expand Up @@ -114,6 +120,26 @@ else if (isBLE && (deviceType == BluetoothDevice.DEVICE_TYPE_LE || deviceType ==
return result;
}

public String[] getIPv6Addresses()
{
ArrayList<String> list = new ArrayList<String>();
try {
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces) {
List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
for (InetAddress addr : addrs) {
if (addr instanceof Inet6Address) {
list.add(addr.getHostAddress()); // maybe with scope id
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
String[] result = (String[]) list.toArray(new String[list.size()]);
return result;
}

private static native void shareText(String text);
private static native void shareFile(String text);
}
35 changes: 28 additions & 7 deletions src/devicetab.cpp
Expand Up @@ -221,7 +221,7 @@ void DeviceTab::refreshTargetList()
#ifdef Q_OS_ANDROID
void DeviceTab::getBondedTarget(bool isBLE)
{
QAndroidJniEnvironment env;
QAndroidJniEnvironment androidEnv;
QtAndroid::PermissionResult r = QtAndroid::checkPermission("android.permission.ACCESS_FINE_LOCATION");
if(r == QtAndroid::PermissionResult::Denied)
{
Expand All @@ -234,13 +234,13 @@ void DeviceTab::getBondedTarget(bool isBLE)
}
qDebug() << "has permission";
QAndroidJniObject array = QtAndroid::androidActivity().callObjectMethod("getBondedDevices", "(Z)[Ljava/lang/String;", isBLE);
int arraylen = env->GetArrayLength(array.object<jarray>());
qDebug() << "arraylen:" << arraylen;
int arrayLen = androidEnv->GetArrayLength(array.object<jarray>());
qDebug() << "arrayLen:" << arrayLen;
QTableWidget* deviceList = isBLE ? ui->BLEC_deviceList : ui->BTClient_deviceList;
deviceList->setRowCount(arraylen);
for(int i = 0; i < arraylen; i++)
deviceList->setRowCount(arrayLen);
for(int i = 0; i < arrayLen; i++)
{
QString info = QAndroidJniObject::fromLocalRef(env->GetObjectArrayElement(array.object<jobjectArray>(), i)).toString();
QString info = QAndroidJniObject::fromLocalRef(androidEnv->GetObjectArrayElement(array.object<jobjectArray>(), i)).toString();
QString address = info.left(info.indexOf(' '));
QString name = info.right(info.length() - info.indexOf(' ') - 1);
qDebug() << address << name;
Expand Down Expand Up @@ -418,6 +418,7 @@ qint64 DeviceTab::updateNetInterfaceList()
{
Connection::Type currType = ui->typeBox->currentData().value<Connection::Type>();
QHostAddress currNetLocalAddr;
QList<QHostAddress> shownAddresses;

if(currType == Connection::UDP)
{
Expand All @@ -432,7 +433,27 @@ qint64 DeviceTab::updateNetInterfaceList()
ui->Net_localAddrBox->addItem(m_anyLocalAddress);
auto netInterfaceList = QNetworkInterface::allAddresses();
for(auto it = netInterfaceList.cbegin(); it != netInterfaceList.cend(); ++it)
ui->Net_localAddrBox->addItem((*it).toString());
{
shownAddresses.append(*it);
ui->Net_localAddrBox->addItem(it->toString());
}
#ifdef Q_OS_ANDROID
QAndroidJniEnvironment androidEnv;
QAndroidJniObject array = QtAndroid::androidActivity().callObjectMethod("getIPv6Addresses", "()[Ljava/lang/String;");
int arrayLen = androidEnv->GetArrayLength(array.object<jarray>());
qDebug() << "arraylen:" << arrayLen;
for(int i = 0; i < arrayLen; i++)
{
QString addressStr = QAndroidJniObject::fromLocalRef(androidEnv->GetObjectArrayElement(array.object<jobjectArray>(), i)).toString();
QHostAddress address(addressStr);
// QHostAddress has operator==(), so QList::contains() works
if(!shownAddresses.contains(address))
{
shownAddresses.append(address);
ui->Net_localAddrBox->addItem(addressStr);
}
}
#endif

if(currType == Connection::UDP && currNetLocalAddr.isMulticast())
ui->Net_localAddrBox->setCurrentText(currNetLocalAddr.toString());
Expand Down

0 comments on commit 03a0e79

Please sign in to comment.