安卓手机Socket通信程序

你好!这里是风筝的博客,

欢迎和我一起交流。


前几天在我的群里发现好多群友在弄ESP-8266这款wifi模块,想起当初我在玩这个模块时想自己做一个手机app上位机,趁着清明放假,就把这个app做出来吧。(java没怎么学过,Android只会简单的拖拖控件,这个app还是挺捉急的......)

先看下UI的源码。

这是activity_main.xml源码:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="1">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <EditText
        android:layout_width="0dp"
        android:layout_weight="1.5"
        android:layout_height="match_parent"
        android:layout_gravity="right"
        android:textSize="21dp"
        android:hint="Addr IP"
        android:inputType="textUri"
        android:id="@+id/ip" />

    <EditText
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:textSize="21dp"
        android:hint="Port"
        android:inputType="number"
        android:id="@+id/port" />
</LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="1">

        <Button
            android:id="@+id/Connet"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Connet"
            android:layout_gravity="left"
            android:layout_marginLeft="30dp"
            android:layout_weight="0.4" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.4"
            android:id="@+id/textView" />
        <Button
            android:id="@+id/Close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Close"
            android:layout_marginRight="50dp"
            android:layout_weight="0.4" />

    </LinearLayout>


    <TextView
        android:layout_width="85dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="12dp"
        android:textSize="20dp"
        android:text="数据接收:"
        android:id="@+id/textView2"
        android:layout_weight="0.08" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <EditText
            android:layout_width="0dp"
            android:layout_height="150dp"
            android:layout_marginLeft="10dp"
            android:gravity="top|left"
            android:layout_weight="1.5"
            android:background="@drawable/edit"
            android:id="@+id/Receive" />
        <Button
            android:id="@+id/Clear"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="Clean"
            android:layout_gravity="bottom"
            android:layout_weight="0.3" />

    </LinearLayout>

    <EditText
        android:id="@+id/message"
        android:inputType="textUri"
        android:layout_width="205dp"
        android:layout_height="wrap_content"
        android:hint="Message" />

    <Button
        android:id="@+id/send"
        android:layout_width="135dp"
        android:layout_height="wrap_content"
        android:text="Send"
        android:layout_gravity="center_horizontal"
        android:layout_weight="0.04" />

    <TextView
        android:layout_width="104dp"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:inputType="textPersonName"
        android:text="By_风筝"
        android:ems="10"
        android:id="@+id/editText"
        android:layout_weight="0.05" />


</LinearLayout>

laylout布局,虽然有点难看,勉勉强强使用吧。其中

 

android:background="@drawable/edit"

这句,在drawable下新建edit.xml文件,在里面写下:

 

 

<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <solid
                android:color="#EFEFEF"/>
            <corners
                android:radius="3dip"
                />
            <stroke
                android:width="0.5px"
                android:color="#505050"/>
        </shape>
    </item>
</layer-list>

以上就是UI的布局了。
接下来看程序,最重要的就是socket通信了:

package com.example.tao.esp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {//, Runnable
    private EditText editText_ip;
    private EditText editText_port;
    private EditText editText_receive;
    private EditText editText_message;
    private Socket socket;
    private PrintWriter pw;
    private BufferedReader br;
    private String IP = "192.168.23.2";
    private int Port = 5000;
    public String rxd;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0x10:
                    Toast.makeText(getApplicationContext(), "连接成功", Toast.LENGTH_LONG).show();
                    break;
                case 0x11:
                    editText_receive.setText(editText_receive.getText().toString() + rxd + "\n");
                    editText_receive.setSelection(editText_receive.getText().length()-1);
                    Log.e("editText:", "rxd");
                    break;
                case 0x12:
                    editText_receive.setText("");
                    break;
            }
        }
    };
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button_send = (Button) findViewById(R.id.send);
        button_send.setOnClickListener(this);
        Button button_conect = (Button) findViewById(R.id.Connet);
        button_conect.setOnClickListener(this);
        Button button_close = (Button) findViewById(R.id.Close);
        button_close.setOnClickListener(this);
        Button button_clean = (Button) findViewById(R.id.Clear);
        button_clean.setOnClickListener(this);
        editText_ip = (EditText) findViewById(R.id.ip);
        editText_port = (EditText) findViewById(R.id.port);
        editText_receive = (EditText) findViewById(R.id.Receive);
        editText_message = (EditText) findViewById(R.id.message);
    }
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.send:
                String str;
                str = editText_message.getText().toString();
                pw.println(str);
                pw.flush();
                break;
            case R.id.Connet:
                IP = editText_ip.getText().toString();
                Port = Integer.parseInt(editText_port.getText().toString());
                new Thread() {
                    public void run() {
                        try {
                            socket = new Socket(IP, Port);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        if (socket == null) {
                            Log.e("socket", "null");
                        } else {
                            try {
                                br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                                pw = new PrintWriter(socket.getOutputStream());
                                if (pw != null && br != null) {
                                    handler.sendEmptyMessage(0x10);
                                    Log.e("接收到:", "成功");
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            while (true) {
                                try {
                                    while ((rxd = br.readLine()) != null) {
                                        handler.sendEmptyMessage(0x11);
                                        Log.e("接收到:", rxd);
                                    }
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                    ;
                }.start();
                break;
            case R.id.Clear:
                handler.sendEmptyMessage(0x12);
                break;
            case R.id.Close:
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
        }
    }
}

这里我们一开始new了message,因为手机接受来自服务器的消息的程序写在了一个子线程,子线程里不能更改UI,所以用handler和主线程通信刷新UI。onclick里写了三个buttun的事件,第一为发送,第二为建立socket通信,值得注意的是,readline()是一个阻塞函数,除非接受到带回车键的消息或者数据流中断,才会有返回值。其他的没什么要说的了,都是调用一些函数,百度一下就能知道这个函数的作用。不过最后想说的是,子线程里最好不要用toast,这个可把我害惨了......

 

好了,这就是安卓手机作为Client的源码,Server我用的网络调试助手,记得先把电脑防火墙关掉,而且手机和电脑在同一个局域网,如果没有网络调试助手的话,可以再写一个Server的app,就是这个程序把连接socket的代码改成开启socket并且监听某个端口即可。

忘了说了,记得要加上网络权限,在AndroidManifest.xml这个文件里加上:

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

by 风筝

 

2017.4.5

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值