如何要在wifi网络状态更改通知?要在、状态、通知、网络

2023-09-12 04:09:16 作者:挽手说梦话

我写一个应用程序,通过WiFi连接到Telnet服务器。我有管理的套接字连接的服务。这一切工作正常,但是当手机睡觉断开连接WiFi无线电,这会导致套接字连接断裂(并引发SocketException异常)。

我觉得我应该是能够建立AA广播接收器,其onResume()方法被调用时,丢失的无线网络连接,这将让我正常关闭套接字,并重新打开它,如果网络被立即重新连接。但我找不到这样的事情在doc或通过搜索。

服务code是在这里,如果你想要的话,感谢您的帮助,我真的AP preciate了!

 包com.wingedvictorydesign.LightfactoryRemote;

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

/ **
 * @author最大
 * /
公共类TelnetService延伸服务{

    私人最终诠释DISCONNECTED = 0;
    私人最终诠释CONNECTED = 1;
    在通知栏//地点的通知
    NotificationManager MNM;
    受保护的InputStream的;
    受保护的OutputStream出来;
    保护Socket套接字;
    //套接字超时,以prevent阻塞,如果丢失与服务器的连接。
    受保护的最终诠释SO_TIMEOUT = 250;
    //拥有插座输入流,直到它准备好被读取。
    BufferedReader类INPUTBUFFER;
    最后RemoteCallbackList< TelnetServiceCallback> mCallbacks =
            新RemoteCallbackList< TelnetServiceCallback>();

    @覆盖
    公共无效的onCreate(){
        super.onCreate();
        Log.d(LightfactoryRemote,TelnetService的onCreate());
        MNM =(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    } //结束的onCreate()

    @覆盖
    公共无效的onDestroy(){
        super.onDestroy();
        Log.d(LightfactoryRemote,TelnetService的onDestroy());
        //取消永久通知,如果它没有被已经。
        mNM.cancel(R.string.telnet_service_connected);
    } //结束的onDestroy()

    @覆盖
    公众的IBinder onBind(意向意图){
        Log.d(LightfactoryRemote,TelnetService onBind());
        返回mBinder;
    }

    @覆盖
    公共布尔onUnbind(意向意图){
        super.onUnbind(意向);
        Log.d(LightfactoryRemote,TelnetService onUnBind());
        返回true;
    }

    @覆盖
    公共无效ONSTART(意向意图,诠释startId){
        super.onStart(意向,startId);
        Log.d(TelnetService,TelnetService ONSTART());
    }

    私人最终TelnetServiceInterface.Stub mBinder =
            新TelnetServiceInterface.Stub(){

        公共无效registerCallback(TelnetServiceCallback CB){
            如果(CB!= NULL)mCallbacks.register(CB);
        }

        公共无效unregisterCallback(TelnetServiceCallback CB){
            如果(CB!= NULL)mCallbacks.unregister(CB);
        }

        公共字符串connectToTelnet(字符串主机,INT端口)
                将抛出RemoteException {
            // android.os.Debug.waitForDebugger();
            字符串Hostinfo中= NULL;
            尝试 {
                插座=新的java.net.Socket();
                Socket的(SO_TIMEOUT);
                socket.connect(新InetSocketAddress(主机,端口),10000); //建立
                //端口与10秒的超时。
                OUT = socket.getOutputStream();
                / *
                 *在被包裹在一个阅读器,然后在缓冲阅读器。这是
                 *理应更好的性能,并且使我们能够读
                 *在使用的readLine()方法的时间线。
                 * /
                INPUTBUFFER =新的BufferedReader(新的InputStreamReader(
                    socket.getInputStream()));
            }赶上(java.io.IOException异常E){
                Log.d(TelnetService.java,连接失败!+ E);
                / *
                 *如果连接失败,返回null serverResponse,
                 *将要在客户端适当处理。
                 * /
                返回Hostinfo中;
            }
            //现在命令已发送,读取响应。
            Hostinfo中= readBuffer();
            Log.d(TelnetService.java,Hostinfo中);
            //通知我们所连接的用户
            showNotification(连接,主机,端口);
            返回Hostinfo中;
        } //结束connectToTelnet

        / **
         *测试为当前活动的连接。三种情况下必须
         *区分。 1.连接尝试尚未作出。返回
         * 假。 2.连接尝试已经取得,而插座
         *初始化,但没有连接处于活动状态。 isConnected()返回
         * 假。 3.连接处于活动状态。 isConnected()返回true。
         * /
        公共布尔areYouThere(){
            如果(插座!= NULL){
                布尔connectStatus = socket.isConnected();
                返回connectStatus;
            } 其他 {
                返回false;
            }
        } //结束areYouThere

        公共无效断开(){
            尝试 {
                如果(INPUTBUFFER!= NULL){
                    inputBuffer.close();
                }
                如果(插座!= NULL){
                    socket.close();
                }
            }赶上(IOException异常E){}
            //取消永久通知。
            mNM.cancel(R.string.telnet_service_connected);
        } //端断开连接()

        / **
         *发送字符串到telnet服务器,并返回从响应
         *服务器如果连接丢失,IOException异常的结果,所以回报
         *空要在客户端妥善处理。
         *
         * @throws的RemoteException
         * /
        公共字符串sendToTelnet(字符串toTelnet)将抛出RemoteException {
            如果(出== NULL){
                / *
                 *如果超出仍是空,无连接已经建立。扔
                 * RemoteException的可在客户端进行处理。
                 * /
                抛出新的RemoteException();
            } 其他 {
                字节ARR [];
                。ARR =(toTelnet +\ R+\ N)的GetBytes();
                尝试 {
                    out.write(ARR);
                    //现在命令已发送,读取响应。
                    串serverResponse = readBuffer();
                    返回serverResponse;
                }赶上(IOException异常E){
                    / *
                     *如果连接而成,但后来失去了,我们在这里结束。
                     *抛出RemoteException处理客户端。
                     * /
                    Log.d(TelnetService,IO异常+ E);
                    断开();
                    抛出新的RemoteException();
                }
            } //结束其他
        } //结束sendToTelnet
    }; //结束ConnectService.Stub类

    公共字符串readBuffer(){
        StringBuilder的serverResponse =新的StringBuilder();
        INT字符;
        尝试 {
            //继续阅读新行入行,直至一个也不剩。
            而(inputBuffer.ready()){
                / *
                 *为每个字符被读取,追加到serverResponse,
                 *扔掉回车(其内容字形),
                 *和>中提示符号。
                 * /
                字符= inputBuffer.read();
                如果((字符= 13)及!&安培;!(字符= 62)){
                    serverResponse.append((char)的字符);
                }
            }
        } //结束试
        赶上(SocketTimeoutException如果E){
            Log.d(TelnetService读(),SocketTimeoutException如果);
        }赶上(IOException异常E){
            Log.d(TelnetService阅读(),阅读()IO异常+ E);
        }
        返回serverResponse.toString();
    }

    / **
     *当此服务运行显示通知。
     * /
    私人无效showNotification(INT事件,字符串主机,诠释端口){
        //在此示例中,我们将使用相同​​的文字为股票和
        //扩展的通知
        CharSequence的notificationText =连接到+主机+:+端口;
        //设置图标,滚动文字和时间戳
        通知通知=新的通知(
            R.drawable.notbar_connected,notificationText,
            System.currentTimeMillis的());
        //设置通知要清除用户点击时,
        //清除通知
        notification.flags | = Notification.FLAG_NO_CLEAR;
        //该PendingIntent来,如果用户选择此推出我们的活动
        // 通知
        PendingIntent contentIntent = PendingIntent.getActivity(此,0,
            新的意图(这一点,LightfactoryRemote.class),0);
        //设置为显示在通知面板的意见信息。
        notification.setLatestEventInfo(这一点,
            的getText(R.string.telnet_service_connected),notificationText,
            contentIntent);
        //发送通知。
        //我们使用一个字符串的id,因为它是唯一的编号。后来我们用它来
        // 取消。
        mNM.notify(R.string.telnet_service_connected,通知);
    } //结束showNotification()
} //结束TelnetConnection的
 

解决方案

注册一个的BroadcastReceiver 的ConnectivityManager.CONNECTIVITY_ACTION。在的onReceive 处理程序可以调用的NetworkInfo信息=(的NetworkInfo)intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO)然后 info.getType()和检查 ConnectivityManager.TYPE_WIFI ,做你想做的话。 :)

I am writing an app that connects to a telnet server via wifi. I have a service that manages the socket connection. It all works fine, but when the phone sleeps it disconnects the wifi radio, which causes the socket connection to break (and throws a SocketException).

为什么笔记本电脑wifi标志不见了

I feel like I should be able to set up a a broadcast receiver whose onResume() method is called when the wifi network connection is lost, and that would allow me to gracefully shut down the socket, and re-open it if the network is immediately re-connected. But I can't find anything like that in the doc or via searching.

Service code is here if you want it, thanks for the help, I really appreciate it!

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

解决方案

Register a BroadcastReceiver for ConnectivityManager.CONNECTIVITY_ACTION. In the onReceive handler you can call NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO) and then info.getType() and check for ConnectivityManager.TYPE_WIFI and do what you want then. :)