Android TCP客户端输出流错误

时间:2017-06-17 21:40:53

标签: java android sockets tcp outputstream

我开始了一个项目,我希望将一些十六进制的颜色发送到我的Arduino,然后用这种颜色制作一个LED灯条。但我的问题是,每当我尝试向Arduino发送内容时,我都会在NetworkOnMainThreadException抛出的Android工作室中收到错误:

android.os.NetworkOnMainThreadException
W/System.err:     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
W/System.err:     at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
W/System.err:     at java.net.SocketOutputStream.write(SocketOutputStream.java:157)
W/System.err:     at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
W/System.err:     at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
W/System.err:     at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
W/System.err:     at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
W/System.err:     at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
W/System.err:     at java.io.BufferedWriter.flush(BufferedWriter.java:254)
W/System.err:     at java.io.PrintWriter.flush(PrintWriter.java:320)
W/System.err:     at com.example.marnaut.arduinoledcontroller.TCPClient.sendMessage(TCPClient.java:51)
W/System.err:     at com.example.marnaut.arduinoledcontroller.ShutdownAsyncTask.onProgressUpdate(ShutdownAsyncTask.java:49)
W/System.err:     at com.example.marnaut.arduinoledcontroller.ShutdownAsyncTask.onProgressUpdate(ShutdownAsyncTask.java:7)
W/System.err:     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:687)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
W/System.err:     at android.os.Looper.loop(Looper.java:154)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6121)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)

我在GitHub上获得了应用程序的代码,并根据我的需要对其进行了转换。我有红色,SocketOutputStream错误也可能意味着Arduino没有收到任何东西,但它在我运行应用程序时确实会改变颜色,所以它收到了发送的消息。另外,当我用一台电脑正常连接telnet到Arduino时,我可以正常改变颜色。我也试图改变从println发送数据到打印或写入的方法,但都没有帮助。有人可以帮助我,因为我一直得到这个例外吗?

修改 我试图为AsyncTask添加一个新的线程策略:

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build();
StrictMode.setThreadPolicy(policy);

有了这个我摆脱了错误信息,但我仍然从处理程序中得到错误......我也没有提到的是我使用了以下2个权限:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

MainActivity:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    public static final int CHANGED = 0;
    public static final int SENDING = 1;
    public static final int SENT = 2;
    public static final int CONNECTING = 3;
    public static final int ERROR = 4;
    public static final int SHUTDOWN = 5;

    Visualizer visual;
    Handler mHandler;

    private TextView redValue;
    private TextView greenValue;
    private TextView blueValue;
    private SeekBar redSlider;
    private SeekBar greenSlider;
    private SeekBar blueSlider;
    private Button sendBtn;

    private String color = "000000";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mHandler = new Handler(){
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case CHANGED:
                        Log.d(TAG, "Color changed.");
                        break;
                    case SENDING:
                        Log.d(TAG, "Sending data...");
                        break;
                    case SENT:
                        Log.d(TAG, "Data sent.");
                        break;
                    case CONNECTING:
                        Log.d(TAG, "Connecting...");
                        break;
                    case ERROR:
                        Log.d(TAG, "Error...");
                        break;
                    case SHUTDOWN:
                        Log.d(TAG, "Shutdown command recieved");
                        break;
                }
            }
        };

        redValue = (TextView) findViewById(R.id.redValue);
        greenValue = (TextView) findViewById(R.id.greenValue);
        blueValue = (TextView) findViewById(R.id.blueValue);

        redSlider = (SeekBar) findViewById(R.id.redSlider);
        greenSlider = (SeekBar) findViewById(R.id.greenSlider);
        blueSlider = (SeekBar) findViewById(R.id.blueSlider);

        sendBtn = (Button) findViewById(R.id.sendBtn);

        sendBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new ShutdownAsyncTask(mHandler).execute("");
            }
        });

        redSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                redValue.setText(String.valueOf(progress));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        greenSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                greenValue.setText(String.valueOf(progress));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        blueSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                blueValue.setText(String.valueOf(progress));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }


}

TCP客户端:

public class TCPClient {

    private static final String TAG = "TCPClient";
    private final Handler mHandler;
    private String ipNumber, incomingMessage, command;
    private BufferedReader in;
    private PrintWriter out;
    private MessageCallback listener = null;
    private boolean mRun = false;

    public TCPClient(Handler mHandler, String command, String ipNumber, MessageCallback listener) {
        this.listener = listener;
        this.ipNumber = ipNumber;
        this.command = command;
        this.mHandler = mHandler;
    }

    public void sendMessage(String message) {
        try {
            if (out != null && !out.checkError()) {
                out.write(message);
                out.flush();
                mHandler.sendEmptyMessageDelayed(MainActivity.SENDING, 1000);
                Log.d(TAG, "Sent Message: " + message);

            }
        } catch (Exception e) {
            mHandler.sendEmptyMessageDelayed(MainActivity.ERROR, 1000);
            e.printStackTrace();
        }
    }

    public void stopClient() {
        Log.d(TAG, "Client stopped!");
        mRun = false;
    }

    public void run() {

        mRun = true;

        try {
            Log.d(TAG, "Connecting...");
            InetAddress serverAddress = InetAddress.getByName(ipNumber);
            mHandler.sendEmptyMessageDelayed(MainActivity.CONNECTING, 1000);
            Socket socket = new Socket(serverAddress, 23);
            Log.d(TAG, "Socket created with ip: " + ipNumber);

            try {
                out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                Log.d(TAG, "In/Out created");

                this.sendMessage(command);
                mHandler.sendEmptyMessageDelayed(MainActivity.SENDING, 2000);

                while (mRun) {
                    incomingMessage = in.readLine();
                    if (incomingMessage != null && listener != null)
                        listener.callbackMessageReceiver(incomingMessage);
                    //incomingMessage = null;
                }

                Log.d(TAG, "Received Message: " + incomingMessage);

            } catch (Exception e) {

                Log.d(TAG, "Error", e);
                mHandler.sendEmptyMessageDelayed(MainActivity.ERROR, 2000);

            } finally {

                out.flush();
                out.close();
                in.close();
                socket.close();
                mHandler.sendEmptyMessageDelayed(MainActivity.SENT, 3000);
                Log.d(TAG, "Socket Closed");
            }

        } catch (Exception e) {

            Log.d(TAG, "Error in socket", e);
            mHandler.sendEmptyMessageDelayed(MainActivity.ERROR, 2000);

        }

    }

    boolean isRunning() {
        return mRun;
    }

    public interface MessageCallback {
        void callbackMessageReceiver(String message);
    }
}

的AsyncTask:

public class MyAsyncTask extends AsyncTask<String, String, TCPClient> {

    private static final String COMMAND = "0xFFFF00";
    private TCPClient tcpClient;
    private Handler mHandler;
    private static final String TAG = "MyAsyncTask";

    public MyAsyncTask(Handler mHandler){
        this.mHandler = mHandler;
    }

    @Override
    protected TCPClient doInBackground(String... params) {
        Log.d(TAG, "In: do in background");

        try{
            tcpClient = new TCPClient(mHandler, COMMAND, "192.168.0.190", new TCPClient.MessageCallback() {
                @Override
                public void callbackMessageReceiver(String message) {
                    publishProgress(message);
                }
            });

        } catch (NullPointerException e){
            Log.d(TAG, "Caught null pointer exception");
            e.printStackTrace();
        } catch (Exception e) {
            Log.d(TAG, "Cought sth weird");
            e.printStackTrace();
        }

        tcpClient.run();
        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        for (String value : values)
            Log.d(TAG, "In progress update, values: " + value);
        Log.d(TAG, "#Values: " + values.length);
        if(values[0].equals("Welcome!")){
            tcpClient.sendMessage("0x00FF00");
            tcpClient.stopClient();
            mHandler.sendEmptyMessageDelayed(MainActivity.CHANGED, 2000);

        }else{
            tcpClient.sendMessage("0xFF0000");
            mHandler.sendEmptyMessageDelayed(MainActivity.ERROR, 2000);
            tcpClient.stopClient();
        }
    }

    @Override
    protected void onPostExecute(TCPClient result){
        super.onPostExecute(result);
        Log.d(TAG, "In on post execute");
        if(result != null && result.isRunning()){
            result.stopClient();
        }
        mHandler.sendEmptyMessageDelayed(MainActivity.SENT, 4000);
    }
}

0 个答案:

没有答案