1818 */
1919package de .yaacc .upnp .server ;
2020
21+ import android .content .BroadcastReceiver ;
2122import android .content .Context ;
23+ import android .content .Intent ;
24+ import android .content .IntentFilter ;
2225import android .content .SharedPreferences ;
2326import android .net .ConnectivityManager ;
2427import android .net .Network ;
@@ -53,18 +56,34 @@ public class NetworkDeviceListener {
5356 private UdpTransiver udpTransiver ;
5457 private UpnpProtocolHandler upnpProtocolHandler ;
5558
59+ private final Object lock = new Object ();
60+ private boolean isHotspotEnabled = false ;
61+ private BroadcastReceiver networkStateReceiver ;
62+
63+ private boolean isHotspotEnabled () {
64+ try {
65+ WifiManager wifiManager = (WifiManager ) context .getSystemService (Context .WIFI_SERVICE );
66+ java .lang .reflect .Method method = wifiManager .getClass ().getDeclaredMethod ("isWifiApEnabled" );
67+ return (Boolean ) method .invoke (wifiManager );
68+ } catch (Exception e ) {
69+ YaaccLogger .w (getClass ().getName (), "Failed to check hotspot state" , e );
70+ return false ;
71+ }
72+ }
5673
5774 public NetworkDeviceListener (Context context , Registry registry , YaaccUpnpServerService service ) throws IllegalStateException {
5875 this .service = service ;
5976 this .context = context ;
6077 this .registry = registry ;
6178 this .wifiManager = ((WifiManager ) context .getSystemService (Context .WIFI_SERVICE ));
79+ // Check hotspot state on startup
80+ isHotspotEnabled = isHotspotEnabled ();
6281 ConnectivityManager connectivityManager = (ConnectivityManager ) context .getSystemService (Context .CONNECTIVITY_SERVICE );
6382 if (!isCellular ()) {
6483 currentNetwork = connectivityManager .getActiveNetwork ();
6584
6685 }
67- if (currentNetwork != null ) {
86+ if (currentNetwork != null || isWifiOrHotspot () ) {
6887 multicastReceiver = new MulticastReceiver ();
6988 udpTransiver = new UdpTransiver ();
7089 httpRequestSender = new HttpRequestSender ();
@@ -107,37 +126,74 @@ public void onLost(@NonNull Network network) {
107126 }
108127 }
109128 });
129+
130+ // Register for WiFi and access point state changes
131+ networkStateReceiver = new BroadcastReceiver () {
132+ @ Override
133+ public void onReceive (Context context , Intent intent ) {
134+ String action = intent .getAction ();
135+ if (WifiManager .WIFI_STATE_CHANGED_ACTION .equals (action )) {
136+ YaaccLogger .d (getClass ().getName (), "WiFi state changed" );
137+ onNetworkStateChange ();
138+ } else if ("android.net.wifi.WIFI_AP_STATE_CHANGED" .equals (action )) {
139+ int apState = intent .getIntExtra ("wifi_state" , 0 );
140+ isHotspotEnabled = (apState == 13 ); // WIFI_AP_STATE_ENABLED
141+ YaaccLogger .d (getClass ().getName (), "Access point state changed: " + (isHotspotEnabled ? "enabled" : "disabled" ));
142+ onNetworkStateChange ();
143+ }
144+ }
145+ };
146+
147+ IntentFilter filter = new IntentFilter ();
148+ filter .addAction (WifiManager .WIFI_STATE_CHANGED_ACTION );
149+ filter .addAction ("android.net.wifi.WIFI_AP_STATE_CHANGED" );
150+ context .registerReceiver (networkStateReceiver , filter );
110151 }
111152
112153 public void enable () {
113- YaaccLogger .v (getClass ().getName (), "in android router enable" );
114-
115- // Enable multicast on the WiFi network interface,
116- // requires android.permission.CHANGE_WIFI_MULTICAST_STATE
117- if (isWifi ()) {
118- setWiFiMulticastLock (true );
119- setWifiLock (true );
154+ synchronized (lock ) {
155+ YaaccLogger .v (getClass ().getName (), "in android router enable" );
156+
157+ // Enable multicast on the WiFi network interface,
158+ // requires android.permission.CHANGE_WIFI_MULTICAST_STATE
159+ if (isWifiOrHotspot ()) {
160+ setWiFiMulticastLock (true );
161+ setWifiLock (true );
162+ }
163+ if (multicastReceiver == null ) multicastReceiver = new MulticastReceiver ();
164+ if (udpTransiver == null ) udpTransiver = new UdpTransiver ();
165+ if (httpRequestSender == null ) httpRequestSender = new HttpRequestSender ();
166+ upnpProtocolHandler = new UpnpProtocolHandler (context , registry , udpTransiver , multicastReceiver , httpRequestSender );
167+ multicastReceiver .init (context , upnpProtocolHandler );
168+ multicastReceiver .execute ();
169+ udpTransiver .init (context , upnpProtocolHandler );
170+ udpTransiver .execute ();
171+ service .updateNotification ();
120172 }
121- upnpProtocolHandler = new UpnpProtocolHandler (context , registry , udpTransiver , multicastReceiver , httpRequestSender );
122- multicastReceiver .init (context , upnpProtocolHandler );
123- multicastReceiver .execute ();
124- udpTransiver .init (context , upnpProtocolHandler );
125- udpTransiver .execute ();
126- service .updateNotification ();
127173 }
128174
129175 public void disable () {
130- YaaccLogger .v (getClass ().getName (), "in android router disable" );
131- // Disable multicast on WiFi network interface,
132- // requires android.permission.CHANGE_WIFI_MULTICAST_STATE
133- if (isWifi ()) {
134- setWiFiMulticastLock (false );
135- setWifiLock (false );
176+ synchronized (lock ) {
177+ YaaccLogger .v (getClass ().getName (), "in android router disable" );
178+ // Disable multicast on WiFi network interface,
179+ // requires android.permission.CHANGE_WIFI_MULTICAST_STATE
180+ if (isWifiOrHotspot ()) {
181+ setWiFiMulticastLock (false );
182+ setWifiLock (false );
183+ }
184+ if (upnpProtocolHandler != null ) {
185+ upnpProtocolHandler = null ;
186+ }
187+ if (multicastReceiver != null ) {
188+ multicastReceiver .cancel ();
189+ multicastReceiver = null ;
190+ }
191+ if (udpTransiver != null ) {
192+ udpTransiver .cancel ();
193+ udpTransiver = null ;
194+ }
195+ service .updateNotification ();
136196 }
137- upnpProtocolHandler = null ;
138- multicastReceiver .cancel ();
139- udpTransiver .cancel ();
140- service .updateNotification ();
141197 }
142198
143199 private boolean isWifi () {
@@ -148,6 +204,10 @@ private boolean isWifi() {
148204 return connectivityManager .getNetworkCapabilities (connectivityManager .getActiveNetwork ()).hasTransport (NetworkCapabilities .TRANSPORT_WIFI );
149205 }
150206
207+ private boolean isWifiOrHotspot () {
208+ return isWifi () || isHotspotEnabled ;
209+ }
210+
151211 private boolean isCellular () {
152212 ConnectivityManager connectivityManager = (ConnectivityManager ) context .getSystemService (Context .CONNECTIVITY_SERVICE );
153213 if (connectivityManager .getNetworkCapabilities (connectivityManager .getActiveNetwork ()) == null ) {
@@ -256,4 +316,46 @@ public UpnpProtocolHandler getUpnpProtocolHandler() {
256316 public boolean isInitalized () {
257317 return udpTransiver != null && multicastReceiver != null && upnpProtocolHandler != null ;
258318 }
319+
320+ private void onNetworkStateChange () {
321+ YaaccLogger .d (getClass ().getName (), "Network state change detected" );
322+ synchronized (lock ) {
323+ if (isWifiOrHotspot ()) {
324+ if (!isInitalized ()) {
325+ YaaccLogger .d (getClass ().getName (), "Reinitializing network components" );
326+ if (currentNetwork == null ) {
327+ ConnectivityManager connectivityManager = (ConnectivityManager ) context .getSystemService (Context .CONNECTIVITY_SERVICE );
328+ currentNetwork = connectivityManager .getActiveNetwork ();
329+ }
330+ if (currentNetwork != null ) {
331+ if (multicastReceiver == null ) multicastReceiver = new MulticastReceiver ();
332+ if (udpTransiver == null ) udpTransiver = new UdpTransiver ();
333+ if (httpRequestSender == null ) httpRequestSender = new HttpRequestSender ();
334+ enable ();
335+ // Notify service to restart UPnP device
336+ if (service != null ) {
337+ service .onNetworkStateChange ();
338+ }
339+ }
340+ }
341+ } else {
342+ YaaccLogger .d (getClass ().getName (), "Not on WiFi or hotspot, disabling" );
343+ disable ();
344+ // Notify service to stop UPnP device
345+ if (service != null ) {
346+ service .onNetworkStateChange ();
347+ }
348+ }
349+ }
350+ }
351+
352+ public void cleanup () {
353+ if (networkStateReceiver != null ) {
354+ try {
355+ context .unregisterReceiver (networkStateReceiver );
356+ } catch (IllegalArgumentException e ) {
357+ YaaccLogger .w (getClass ().getName (), "Receiver not registered" );
358+ }
359+ }
360+ }
259361}
0 commit comments