This commit is contained in:
TheUnrealDragon 2026-04-09 13:03:24 +05:30
commit a784bd6549
4 changed files with 55 additions and 9 deletions

View file

@ -11,7 +11,7 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" />
<supports-screens <supports-screens
@ -28,10 +28,10 @@
android:fullBackupOnly="false"> android:fullBackupOnly="false">
<service android:name=".WaterLevelService" <service android:name=".WaterLevelService"
android:foregroundServiceType="specialUse" android:foregroundServiceType="connectedDevice"
android:exported="true"> android:exported="true">
<property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE" <!-- <property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="Monitoring water levels via local network UDP packets for real-time sensor alerts." /> android:value="Monitoring water levels via local network UDP packets for real-time sensor alerts." />-->
<meta-data android:name="android.app.lib_name" android:value="service"/> <meta-data android:name="android.app.lib_name" android:value="service"/>
<meta-data android:name="android.app.background_running" android:value="true"/> <meta-data android:name="android.app.background_running" android:value="true"/>
</service> </service>

View file

@ -65,9 +65,10 @@ public class WaterLevelService extends Service {
@Override @Override
public void run() { public void run() {
Log.d("UDP Service", "Thread initialising"); Log.d("UDP Service", "Client Thread initialising");
android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) getSystemService(Context.WIFI_SERVICE); android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) getSystemService(Context.WIFI_SERVICE);
android.net.wifi.WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("water_level_lock"); android.net.wifi.WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("water_level_lock");
android.net.wifi.WifiManager.WifiLock wifiLock = wifi.createWifiLock(android.net.wifi.WifiManager.WIFI_MODE_FULL_HIGH_PERF, "WaterLevel:WifiLock");
android.os.PowerManager pm = (android.os.PowerManager) getSystemService(Context.POWER_SERVICE); android.os.PowerManager pm = (android.os.PowerManager) getSystemService(Context.POWER_SERVICE);
android.os.PowerManager.WakeLock wakeLock = pm.newWakeLock(android.os.PowerManager.PARTIAL_WAKE_LOCK, "WaterLevel:WakeLock"); android.os.PowerManager.WakeLock wakeLock = pm.newWakeLock(android.os.PowerManager.PARTIAL_WAKE_LOCK, "WaterLevel:WakeLock");
@ -84,14 +85,26 @@ public class WaterLevelService extends Service {
try { try {
multicastLock.acquire(); multicastLock.acquire();
wakeLock.acquire(); wakeLock.acquire();
socket_recv = new DatagramSocket(8176); wifiLock.acquire();
socket_recv = new DatagramSocket(8176, InetAddress.getByName("0.0.0.0"));
socket_send = new DatagramSocket(8177); socket_send = new DatagramSocket(8177);
socket_recv.setBroadcast(true); socket_recv.setBroadcast(true);
socket_recv.setSoTimeout(4000);
Log.d("UDP Service", "Created Sockets"); Log.d("UDP Service", "Created Sockets");
int count = 0;
while (!Thread.currentThread().isInterrupted()) { while (!Thread.currentThread().isInterrupted()) {
count++;
if(count == 3) {
Log.i("UDP Service", "Thread is running");
count = 0;
}
byte[] buffer = new byte[4]; byte[] buffer = new byte[4];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length); try {
socket_recv.receive(packet); DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket_recv.receive(packet);
} catch(java.net.SocketTimeoutException e) {
continue;
}
float f = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getFloat(); float f = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getFloat();
Log.d("UDP Service ", "Received packet: " + f); Log.d("UDP Service ", "Received packet: " + f);
Log.d("UDP Service ", "Threshold is: " + alert_thres_distance); Log.d("UDP Service ", "Threshold is: " + alert_thres_distance);
@ -128,6 +141,8 @@ public class WaterLevelService extends Service {
catch (IOException e) { catch (IOException e) {
Log.e("UDP Service", "Socket Error", e); Log.e("UDP Service", "Socket Error", e);
} finally { } finally {
if (wifiLock.isHeld())
wifiLock.release();
if (multicastLock.isHeld()) if (multicastLock.isHeld())
multicastLock.release(); multicastLock.release();
if (wakeLock.isHeld()) if (wakeLock.isHeld())

View file

@ -39,6 +39,11 @@ void UDPListener::setDistance(double newDistance)
emit distanceChanged(); emit distanceChanged();
} }
void UDPListener::continueDestruction()
{
destroyed = true;
}
void UDPListener::resetAverages() void UDPListener::resetAverages()
{ {
averages.clear(); averages.clear();
@ -117,10 +122,24 @@ void UDPListener::destroy()
{ {
qDebug() << "Destroying UDP Listener"; qDebug() << "Destroying UDP Listener";
timer->stop(); timer->stop();
connect(this, &UDPListener::stopWorker, worker, &Worker::stop);
connect(worker, &Worker::stopped, this, &UDPListener::continueDestruction);
emit stopWorker();
while(!destroyed) {
QCoreApplication::processEvents();
}
thread->exit(0); thread->exit(0);
thread->deleteLater(); QCoreApplication::processEvents();
QCoreApplication::processEvents();
worker->deleteLater(); worker->deleteLater();
QCoreApplication::processEvents();
QCoreApplication::processEvents();
thread->deleteLater();
QCoreApplication::processEvents();
QCoreApplication::processEvents();
timer->deleteLater(); timer->deleteLater();
QCoreApplication::processEvents();
QCoreApplication::processEvents();
qDebug() << "Deinitialized UDP Listener"; qDebug() << "Deinitialized UDP Listener";
} }
@ -149,6 +168,13 @@ Worker::Worker(QObject *parent)
} }
void Worker::stop()
{
disconnect(socket, nullptr, nullptr, nullptr);
delete socket;
emit stopped();
}
void Worker::run() void Worker::run()
{ {
using namespace std::chrono_literals; using namespace std::chrono_literals;

View file

@ -16,9 +16,11 @@ class Worker: public QObject {
public: public:
explicit Worker(QObject *parent = nullptr); explicit Worker(QObject *parent = nullptr);
signals: signals:
void stopped();
void socketError(QString error); void socketError(QString error);
void datagramReceived(QByteArray data, QByteArray data2); void datagramReceived(QByteArray data, QByteArray data2);
public slots: public slots:
void stop();
void run(); void run();
private slots: private slots:
void socketDataReceived(); void socketDataReceived();
@ -29,11 +31,13 @@ class UDPListener : public QObject
Q_OBJECT Q_OBJECT
QML_ELEMENT QML_ELEMENT
Q_PROPERTY(double distance READ distance WRITE setDistance NOTIFY distanceChanged FINAL) Q_PROPERTY(double distance READ distance WRITE setDistance NOTIFY distanceChanged FINAL)
bool destroyed = false;
public: public:
explicit UDPListener(QObject *parent = nullptr); explicit UDPListener(QObject *parent = nullptr);
double distance() const; double distance() const;
void setDistance(double newDistance); void setDistance(double newDistance);
signals: signals:
void stopWorker();
void showError(QString err); void showError(QString err);
void distanceChanged(); void distanceChanged();
void startWorker(); void startWorker();
@ -41,6 +45,7 @@ signals:
void disconnected(); void disconnected();
void distanceReceived(double dist, QString timestamp); void distanceReceived(double dist, QString timestamp);
public slots: public slots:
void continueDestruction();
void resetAverages(); void resetAverages();
void setFlipBits(bool flip_bits); void setFlipBits(bool flip_bits);
void setConfig(float distance, bool flip_bits); void setConfig(float distance, bool flip_bits);