首先,需要对树莓派进行配置,使其成为AP热点,这里我用的树莓派3B自带wifi蓝牙模块,树莓派3B作AP热点的方法具体参考https://blog.csdn.net/u014271612/article/details/53766627这篇文章,但配置过程中会遇到一些小问题,比如在输入 git clone https: //github.com/oblique/create_ap  这条命令时会提示需要帐号密码,而我的做法是直接上github将这个项目的zip压缩文件下载下来拷贝到我的树莓派中,然后再进行下面操作,后面还有一个问题 ,在 sudo create_ap wlan0eth0 热点名 密码 这行密码中wlan0eth0 应该在中间加一个空格,即 sudo create_ap wlan0 eth0 热点名 密码 至此树莓派作为AP热点配置成功。     下面进入主题,树莓派与android客户端之间的通信我采用socket来实现,树莓派上我写了一个python脚本作为服务器,android作为客户端

    首先,上一下效果图:

    Android客户端:



树莓派服务器端:


    树莓派上的python脚本如下:

import socketimport timeimport sysHOST_IP = "192.168.12.1"    #我的树莓派作为AP热点的ip地址HOST_PORT = 7654            #端口号print("Starting socket: TCP...")socket_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    #创建socketprint("TCP server listen @ %s:%d!" %(HOST_IP, HOST_PORT) )host_addr = (HOST_IP, HOST_PORT)socket_tcp.bind(host_addr)    #绑定我的树莓派的ip地址和端口号socket_tcp.listen(1)#listen函数的参数是监听客户端的个数,这里只监听一个,即只允许与一个客户端创建连接while True:print ('waiting for connection...')socket_con, (client_ip, client_port) = socket_tcp.accept()    #接收客户端的请求print("Connection accepted from %s." %client_ip)socket_con.send("Welcome to RPi TCP server!")    #发送数据while True:data=socket_con.recv(1024)    #接收数据if data:    #如果数据不为空,则打印数据,并将数据转发给客户端print(data)socket_con.send(data)socket_tcp.close()

注:上述代码注释是后期加上去的,可以将代码中的注释去掉再运行。

    接下来是Android客户端代码:

    1、XML布局文件

<?xml version="1.0" encoding="utf-8"?>            

    2、Activity.java

package lh.wifidemo.ui.activity;import android.os.Handler;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.Socket;import lh.wifidemo.R;public class Device_Control_Activity extends ActionBarActivity {    private EditText et_send;    private Button bt_send;    private TextView tv_recv;    private String send_buff=null;    private String recv_buff=null;    private Handler handler = null;    Socket socket = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_device__control_);        initView();        handler = new Handler();          //单开一个线程来进行socket通信          new Thread(new Runnable() {              @Override              public void run() {                  try {                        socket = new Socket("192.168.12.1" , 7654);                        if (socket!=null) {                            System.out.println("###################");                            while (true) {      //循环进行收发                                recv();                                send();                            }                        }                       else                            System.out.println("socket is null");                  } catch (IOException e) {                      e.printStackTrace();                  }              }          }).start();        send();    }    private void recv() {        //单开一个线程循环接收来自服务器端的消息        InputStream inputStream = null;        try {            inputStream = socket.getInputStream();        } catch (IOException e) {            e.printStackTrace();        }        if (inputStream!=null){            try {                byte[] buffer = new byte[1024];                int count = inputStream.read(buffer);//count是传输的字节数                recv_buff = new String(buffer);//socket通信传输的是byte类型,需要转为String类型                System.out.println(recv_buff);            } catch (IOException e) {                e.printStackTrace();            }        }        //将受到的数据显示在TextView上        if (recv_buff!=null){            handler.post(runnableUi);        }    }    //不能在子线程中刷新UI,应为textView是主线程建立的    Runnable runnableUi = new Runnable() {        @Override        public void run() {            tv_recv.append("\n"+recv_buff);        }    };    private void send() {        bt_send.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new Thread(new Runnable() {                    @Override                    public void run() {                        send_buff = et_send.getText().toString();                        //向服务器端发送消息                        System.out.println("------------------------");                        OutputStream outputStream=null;                        try {                            outputStream = socket.getOutputStream();                        } catch (IOException e) {                            e.printStackTrace();                        }                        if(outputStream!=null){                            try {                                outputStream.write(send_buff.getBytes());                                System.out.println("1111111111111111111111");                                outputStream.flush();                            } catch (IOException e) {                                e.printStackTrace();                            }                        }                    }                }).start();            }        });    }    private void initView() {        et_send = (EditText) findViewById(R.id.et_send);        bt_send = (Button) findViewById(R.id.bt_send);        tv_recv = (TextView) findViewById(R.id.tv_recv);    }}

这里有几个地方需要特别注意:

1、创建socket时需要开一个子线程,而不能直接在主线程中完成,否则会报错

2、当接收来自树莓派服务器的消息时,需要刷新TextView,而刷新TextView的操作不能直接在子线程中完成,需要用Handler来实现,否则会报错,提示view只能由源线程来更改

整个项目需要先启动树莓派,然后手机连上树莓派的WIFI热点,如果想要查看树莓派的输出信息,则可以利用window的远程桌面连接树莓派,也可以用putty这个软件进行命令行控制,当然,有条件的完全可以用HDMI接口给你的树莓派连一个显示器

        

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. 一句话锁定MySQL数据占用元凶
  3. android使用AIDL跨进程通信(IPC)
  4. flutter 持久化存储-----数据库sqflite
  5. AndroidStudio 优秀的第三方数据库 GreenDao
  6. java做服务器,android做客户端,实现数据传输
  7. Android入门:深入学习理解 Handler HandlerThread AsyncQueryHan
  8. Android(安卓)基于DataBinding的通用RecyclerView Adapter
  9. Android学习整理- 9- 实时更新UI-Handler

随机推荐

  1. 源码解析Android中AsyncTask的工作原理
  2. pandaboard ES学习之旅——4 Android源代
  3. Android(安卓)多个Activity选项卡实现
  4. android 电容屏(二):驱动调试之基本概念篇
  5. Android中创建对话框
  6. android adb
  7. 跟着做 Android(安卓)NDK学习入门如此简
  8. Android按键添加和处理的方案
  9. Android——编译release版签名系统
  10. android:maxLines和android:ellipsize同