2010-06-25 61 views
8

我在寫一個通過wifi連接到telnet服務器的應用程序。我有一個管理套接字連接的服務。這一切都正常,但是當電話睡眠時,它會斷開wifi無線電,導致套接字連接中斷(並引發SocketException)。如何在WiFi網絡狀態更改時收到通知?

我覺得我應該能夠建立一個廣播接收機,當wifi網絡連接丟失時,它的onResume()方法會被調用,這將允許我正常關閉套接字,並重新打開它,如果網絡立即重新連接。但我在文檔或搜索中找不到類似的內容。

服務代碼在這裏,如果你想要它,感謝您的幫助,我真的很感激它!

package com.wingedvictorydesign.LightfactoryRemote; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.net.InetSocketAddress; 
import java.net.Socket; 
import java.net.SocketException; 
import java.net.SocketTimeoutException; 
import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.app.Service; 
import android.content.Intent; 
import android.os.IBinder; 
import android.os.RemoteCallbackList; 
import android.os.RemoteException; 
import android.text.Editable; 
import android.util.Log; 
import android.widget.Toast; 
import android.os.Debug; 

/** 
* @author Max 
*/ 
public class TelnetService extends Service { 

    private final int DISCONNECTED = 0; 
    private final int CONNECTED = 1; 
    // place notifications in the notification bar 
    NotificationManager mNM; 
    protected InputStream in; 
    protected OutputStream out; 
    protected Socket socket; 
    // the socket timeout, to prevent blocking if the server connection is lost. 
    protected final int SO_TIMEOUT = 250; 
    // holds the incoming stream from socket until it is ready to be read. 
    BufferedReader inputBuffer; 
    final RemoteCallbackList<TelnetServiceCallback> mCallbacks = 
      new RemoteCallbackList<TelnetServiceCallback>(); 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     Log.d("LightfactoryRemote", "TelnetService onCreate()"); 
     mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
    }// end onCreate() 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.d("LightfactoryRemote", "TelnetService onDestroy()"); 
     // Cancel the persistent notification, if it hasn't been already. 
     mNM.cancel(R.string.telnet_service_connected); 
    }// end onDestroy() 

    @Override 
    public IBinder onBind(Intent intent) { 
     Log.d("LightfactoryRemote", "TelnetService onBind()"); 
     return mBinder; 
    } 

    @Override 
    public boolean onUnbind(Intent intent) { 
     super.onUnbind(intent); 
     Log.d("LightfactoryRemote", "TelnetService onUnBind()"); 
     return true; 
    } 

    @Override 
    public void onStart(Intent intent, int startId) { 
     super.onStart(intent, startId); 
     Log.d("TelnetService", "TelnetService onStart()"); 
    } 

    private final TelnetServiceInterface.Stub mBinder = 
      new TelnetServiceInterface.Stub() { 

     public void registerCallback(TelnetServiceCallback cb) { 
      if (cb != null) mCallbacks.register(cb); 
     } 

     public void unregisterCallback(TelnetServiceCallback cb) { 
      if (cb != null) mCallbacks.unregister(cb); 
     } 

     public String connectToTelnet(String Host, int Port) 
       throws RemoteException { 
      // android.os.Debug.waitForDebugger(); 
      String hostInfo = null; 
      try { 
       socket = new java.net.Socket(); 
       socket.setSoTimeout(SO_TIMEOUT); 
       socket.connect(new InetSocketAddress(Host, Port), 10000); //setup 
       // the port with a timeout of 10sec. 
       out = socket.getOutputStream(); 
       /* 
       * in is wrapped in a reader, then in a Buffered reader. This is 
       * supposedly better for performance, and allows us to read a 
       * line at a time using the readLine() method. 
       */ 
       inputBuffer = new BufferedReader(new InputStreamReader(
        socket.getInputStream())); 
      } catch (java.io.IOException e) { 
       Log.d("TelnetService.java", "Connection failed! " + e); 
       /* 
       * if the connection fails, return null for serverResponse, 
       * which will be handled appropriately on the client side. 
       */ 
       return hostInfo; 
      } 
      // now that the command has been sent, read the response. 
      hostInfo = readBuffer(); 
      Log.d("TelnetService.java", hostInfo); 
      // notify the user that we are connected 
      showNotification(CONNECTED, Host, Port); 
      return hostInfo; 
     }// end connectToTelnet 

     /** 
     * Tests for a currently active connection. Three cases must be 
     * distinguished. 1. A connection attempt has not been made. Return 
     * false. 2. A connection attempt has been made, and socket is 
     * initialized, but no connection is active. isConnected() returns 
     * false. 3. A connection is active. isConnected() returns true. 
     */ 
     public boolean areYouThere() { 
      if (socket != null) { 
       boolean connectStatus = socket.isConnected(); 
       return connectStatus; 
      } else { 
       return false; 
      } 
     }// end areYouThere 

     public void disconnect() { 
      try { 
       if (inputBuffer != null) { 
        inputBuffer.close(); 
       } 
       if (socket != null) { 
        socket.close(); 
       } 
      } catch (IOException e) {} 
      // Cancel the persistent notification. 
      mNM.cancel(R.string.telnet_service_connected); 
     }// end disconnect() 

     /** 
     * send the string to the telnet server, and return the response from 
     * server If the connection is lost, an IOException results, so return 
     * null to be handled appropriately on the client-side. 
     * 
     * @throws RemoteException 
     */ 
     public String sendToTelnet(String toTelnet) throws RemoteException { 
      if (out == null) { 
       /* 
       * if out is still null, no connection has been made. Throw 
       * RemoteException to be handled on the client side. 
       */ 
       throw new RemoteException(); 
      } else { 
       byte arr[]; 
       arr = (toTelnet + "\r" + "\n").getBytes(); 
       try { 
        out.write(arr); 
        // now that the command has been sent, read the response. 
        String serverResponse = readBuffer(); 
        return serverResponse; 
       } catch (IOException e) { 
        /* 
        * if a connection was made, but then lost, we end up here. 
        * throw a Remoteexception for handling by the client. 
        */ 
        Log.d("TelnetService", "IO exception" + e); 
        disconnect(); 
        throw new RemoteException(); 
       } 
      }// end else 
     }// end sendToTelnet 
    };// end ConnectService.Stub class 

    public String readBuffer() { 
     StringBuilder serverResponse = new StringBuilder(); 
     int character; 
     try { 
      // keep reading new lines into line until there are none left. 
      while (inputBuffer.ready()) { 
       /* 
       * as each character is read, append it to serverResponse, 
       * throwing away the carriage returns (which read as glyphs), 
       * and the ">" prompt symbols. 
       */ 
       character = inputBuffer.read(); 
       if ((character != 13) && (character != 62)) { 
        serverResponse.append((char) character); 
       } 
      } 
     }// end try 
     catch (SocketTimeoutException e) { 
      Log.d("TelnetService read()", "SocketTimeoutException"); 
     } catch (IOException e) { 
      Log.d("TelnetService read()", "read() IO exception" + e); 
     } 
     return serverResponse.toString(); 
    } 

    /** 
    * Show a notification while this service is running. 
    */ 
    private void showNotification(int event, String Host, int Port) { 
     // In this sample, we'll use the same text for the ticker and the 
     // expanded notification 
     CharSequence notificationText = "Connected to " + Host + " : " + Port; 
     // Set the icon, scrolling text and timestamp 
     Notification notification = new Notification(
      R.drawable.notbar_connected, notificationText, 
      System.currentTimeMillis()); 
     // set the notification not to clear when the user hits 
     // "Clear All Notifications" 
     notification.flags |= Notification.FLAG_NO_CLEAR; 
     // The PendingIntent to launch our activity if the user selects this 
     // notification 
     PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 
      new Intent(this, LightfactoryRemote.class), 0); 
     // Set the info for the views that show in the notification panel. 
     notification.setLatestEventInfo(this, 
      getText(R.string.telnet_service_connected), notificationText, 
      contentIntent); 
     // Send the notification. 
     // We use a string id because it is a unique number. We use it later to 
     // cancel. 
     mNM.notify(R.string.telnet_service_connected, notification); 
    }// end showNotification() 
} // end TelnetConnection 
+0

[通知當Android設備的網絡狀態改變(http://www.singhajit.com/notify-android-device-network-status-changes/) – 2016-10-28 14:32:29

回答

17

爲ConnectivityManager.CONNECTIVITY_ACTION註冊BroadcastReceiver。在onReceive處理程序中,您可以撥打NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO),然後info.getType()並檢查ConnectivityManager.TYPE_WIFI,然後執行您想要的操作。 :)

+1

供參考: EXTRA_NETWORK_INFO現在已棄用。 http://developer.android.com/reference/android/net/ConnectivityManager.html#EXTRA_NETWORK_INFO – noahd 2013-05-28 21:47:09

10

*在設置這些權限您的清單

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> 

*對這些行爲一個BroadcastReceiver您的清單中的過濾器

<receiver android:name="com.myBroadcastReceiver" > 
      <intent-filter> 
       <action android:name="android.net.wifi.supplicant.CONNECTION_CHANGE" /> 
       <action android:name="android.net.wifi.STATE_CHANGE" /> 
      </intent-filter> 
     </receiver> 

*定義您BroadcastReceiver's實現

public class myBroadcastReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 

     WifiManager wifiManager = (WifiManager) context 
       .getSystemService(Context.WIFI_SERVICE); 

     NetworkInfo networkInfo = intent 
       .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 
     if (networkInfo != null) { 
      Log.d(AppConstants.TAG, "Type : " + networkInfo.getType() 
        + "State : " + networkInfo.getState()); 


if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { 

    //get the different network states 
if (networkInfo.getState() == NetworkInfo.State.CONNECTING || networkInfo.getState() ==  NetworkInfo.State.CONNECTED) { 
    } 
         } 
         } 

        } 
       } 
相關問題