按计划每周更新一篇技术博文,上周因工作忙而中断,第三篇:《Android基于Socket无线遥控(1)--Socket基本模型搭建》
本例子内容比较多,初步构思分三篇完成,Android系统基于Socket实现无线遥控,可控制另一台Android设备音量增减、亮度调节、方向控制、确认、退出等,本篇主要介绍Socket基本模型搭建,以及无线控制Android系统音量增加,亮度增减。
一、技术介绍
1、Socket介绍
Socket技术实现,软件实现部分有客户端(遥控器)和服务器(显示器),服务器与客户端定制一致的收发消息信息,以致达到需求功能,主要使用步骤如下:
a.服务器通过创建ServerSocket指定一个固定的端口号,以致客户端能够向该端口号发送连接请求;
b.服务器通过accept()方法为下一个传入的连接请求创建Socket实例,如果没有新的连接请求,accept()方法将处于阻塞等待;
c.客户端创建Socket,指定远程地址和端口号,向服务端发送请求;
d.客户端与服务器连接成功后通过InputStream和OutputStream进行数据信息交互以达到无线遥控功能。
通常情况下,服务器端可能会接收多个客户端的请求,此时需要使用循环来接收来自不同客户端的连接请求,主要使用如下代码:
- // 创建一个ServerSocket,Ports为端口号
- ServerSocket ss = new ServerSocket(Ports);
- // 采用循环不断接收来自客户端的请求
- while(!quit)
- {
- //此行代码会阻塞,将一直等待别人的连接
- Socket s = ss.accept();
- socketList.add(s);
- //每当客户端连接后启动一条ServerThread线程为该客户端服务
- new Thread(new ServerThread(s)).start();
- ……
- }
客户端创建Socket,指定服务端IP地址和端口号,当Socket创建成功后,服务端的ServerSocket的accept()方法会向下执行,此时服务器端和客户端产生一对相互连接的Socket,创建Socket代码如下:
- // 创建Socket连接服务器,IP 为IP地址,Ports为端口号
- Socket s = new Socket( IP, Ports );
- // 客户端启动ClientThread线程不断读取来自服务器的数据
- new Thread(new ClientThread(s , handler )).start();
- ……
当客户端与服务端产生对应的Socket之后,程序无需再区分服务端与客户端,而是通过各自的Socket进行通讯,主要采用Java IO流来进行数据信息传输,输入输出流方法乳如下:
a.InputStream getInputStream() 返回该Socket对象对应的输入流,让程序通过该输入流从Socket中取出数据,主要使用之一:
- ……
- BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream()));
- ……
- String content = null;
- //不断读取Socket输入流中的内容。
- while ((content = br .readLine()) != null)
- {
- // 对接收到的信息进行对应操作
- }
b.OutputStream getOutputStream() 返回该Socket对象对应的输出流,让程序通过该输出流向Socket中输出数据,主要使用之一:
- ……
- OutputStream os = socket.getOutputStream();
- String OutputStr = "";
- ……
- os.write(OutputStr + "\r\n").getBytes("utf-8"));
- ……
二、编码前预定准则
1、客户端(遥控器)、服务器(显示器)
2、端口:58888 (有效范围0~65535)
3、消息规则
a.客户端 --请求连接--> 服务器
消息:"CN" // CN为connect标志
b.客户端 --方向请求--> 服务器
消息:
"DT" // 向上(
direction
Top)
"DB" // 向下(
bottom
)
"DL" // 向左(Left)
"DR" // 向右(Right)
C.客户端 --音量增加、减少-->服务器
消息:
"VO +" // 音量增加(v
olume)
"VO -" // 音量减少
D.客户端 --亮度增加、减少-->服务器
消息:
"BR +" // 亮度增加(
brightness)
"BR -" // 亮度减少
E.客户端 --单击确认-->服务器
消息:
"CL" // 单击确认(Click)
F.客户端 --菜单-->服务器
消息:
"ME" // 取消(Menu
l)
G.客户端 --返回--> 服务器
消息:
"BA" //退出(Back)
H.客户端 --电源--> 服务器
消息:
"PO" // 电源(Power)
I.客户端 --Home--> 服务器
消息:
"HO" //退出(Home)
三、编码实现
1.页面截图
a.遥控器简单界面

b.服务器端显示界面一

c.服务器端显示界面二

2.客户端(遥控器)主要代码
a.
RemoteControlClient.java 遥控器客户端
- /**
- * 遥控器客户端
- *
- */
- public class RemoteControlClient extends Activity
- {
- ……
- private OutputStream os ;
- private String IP = "192.168.2.10" ; // 此IP地址根据实际项目修改
- private int Ports = 58888; // 端口
- ……
- private Handler handler = new Handler()
- {
- @Override
- public void handleMessage(Message msg)
- {
- // 如果消息来自于子线程
- if (msg.what == 0x123)
- {
- // 将读取的内容追加显示在文本框中
- show .append(msg.obj .toString());
- }
- }
- };
- OnClickListener mOnClickListener = new OnClickListener()
- {
- @Override
- public void onClick(View v)
- {
- switch (v.getId()) {
- case R.id. send:
- try
- {
- Log. v( "", "Socket ---> input : " + input.getText().toString());
- // 将用户在文本框内输入的内容写入网络
- os .write((input .getText().toString() + "\r\n").getBytes( "utf-8" ));
- // 清空input文本框
- input .setText("" );
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- break ;
- case R.id. volume_add_btn:
- input .setText("VO +" );
- break ;
- case R.id. volume_reduced_btn:
- input .setText("VO -" );
- break ;
- case R.id. brightness_add_btn:
- input .setText("BR +" );
- break ;
- case R.id. brightness_reduced_btn:
- input .setText("BR -" );
- break ;
- case R.id. direction_top_btn:
- input .setText("DT" );
- break ;
- case R.id. direction_bottom_btn:
- input .setText("DB" );
- break ;
- case R.id. direction_left_btn:
- input .setText("DL" );
- break ;
- case R.id. direction_right_btn:
- input .setText("DR" );
- break ;
- case R.id. click_btn:
- input .setText("CL" );
- break ;
- case R.id. back_btn:
- input .setText("BA" );
- break ;
- case R.id. menu_btn:
- input .setText("ME" );
- break ;
- case R.id. power_btn:
- input .setText("PO" );
- break ;
- case R.id. home_btn:
- input .setText("HO" );
- break ;
- case R.id. connect_btn:
- try
- {
- IP = ipInput .getText().toString();
- Log. v( "", " --> IP : " + IP );
- // 创建Socket连接服务器
- Socket s = new Socket(IP , Ports);
- // 客户端启动ClientThread线程不断读取来自服务器的数据
- new Thread( new ClientThread(s, handler)).start(); os = s.getOutputStream();
- Toast. makeText( context, getString(R.string. con_success ), Toast. LENGTH_LONG).show();
- reContentView();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- Toast. makeText( context, getString(R.string. con_failed ), Toast. LENGTH_LONG).show();
- }
- break ;
- }
- }
- };
- }
b. ClientThread.java 不断读取来自服务端的数据信息