安卓的Socket客户端开发及应用

Posted Heavy sea

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安卓的Socket客户端开发及应用相关的知识,希望对你有一定的参考价值。

一、应用场景

在做嵌入式开发中,比如我们通过开发板控制电机从而驱动小车前进和转向,希望能通过手机安卓app控制小车。这时我们可以引入安卓的Socket编程。
实现思路:假设小车前进和转向的消息获取是经过串口通信完成的,要实现安卓app的控制,可以先在开发板上开启socket服务端,当在安卓app界面上点击按钮时,按钮实现客户端的创建并与服务端建立连接,客户端对服务端发送消息。这时,服务端接收消息后,剩下的步骤便可由串口通信完成。

二、界面简单布局代码

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="70dp"
        android:onClick="ButtonHandler"
        android:text="前进" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="50dp"
        android:onClick="ButtonHandler"
        android:text="后退" />
    
        <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1"
        android:layout_toLeftOf="@+id/button1"
        android:layout_marginRight="10dp"
        android:onClick="ButtonHandler"
        android:text="左转" />
        
        <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1"
        android:layout_toRightOf="@+id/button1"
        android:layout_marginLeft="10dp"
        android:onClick="ButtonHandler"
        android:text="右转" />

</RelativeLayout>

界面布局如下:
在这里插入图片描述

三、Socket服务端

安卓的Socket服务端是基于java的Socket编程实现的,java的Socket编程可参考基于java的socket编程
但值得注意的是:网络访问不能在主线程(UI线程)中进行,否则程序会崩溃!!!

MainActivity.java

package com.example.heavysea.l;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

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

public void sendMessage(final String message) {
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					Socket client = new Socket("192.168.43.241", 8080);
					OutputStream out = client.getOutputStream();
					// 写入数据
					out.write(message.getBytes());
				} catch (UnknownHostException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();				}

			}
		}).start();
		
	}
	public void ButtonHandler(View v) {

		switch (v.getId()) {
		case R.id.button1:
			sendMessage("go ahead");
			break;

		case R.id.button2:
			sendMessage("go behind");
			break;

		case R.id.button3:
			sendMessage("turn left");
			break;

		case R.id.button4:
			sendMessage("turn right");
			break;
		}

	}
}

开启网络调试助手,开启TCP 客户端,运行安卓程序,此时点击按钮"前进",便会与客户端建立一次连接,发送"go ahead"到客户端,客户端便能正常获取消息了。

四、Socket服务端代码结构的优化

按照开发的习惯,可在src底下再建立一个包,在新建立的包下建立新的Net.java文件,然后把服务端的代码剪切到新的java文件中,从而使代码结构更加清晰明了。
在这里插入图片描述

MainActivity.java

package com.example.heavysea.l;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
// 导入新建立的包
import com.example.net.Net;

public class MainActivity extends Activity {

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

	public void ButtonHandler(View v) {

		switch (v.getId()) {
		case R.id.button1:
			Net.sendMessage("go ahead");
			break;

		case R.id.button2:
			Net.sendMessage("go behind");
			break;

		case R.id.button3:
			Net.sendMessage("turn left");
			break;

		case R.id.button4:
			Net.sendMessage("turn right");
			break;
		}

	}
}

注意:把sendMessage方法放到类中,需要把方法定义成静态方法,以方便MainActivity.java中对该方法的运用。

Net.java:

package com.example.net;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Net {
	// 类中的静态方法
	public static void sendMessage(final String message) {
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					Socket client = new Socket("192.168.43.241", 8080);
					OutputStream out = client.getOutputStream();
					// 写入数据
					out.write(message.getBytes());
				} catch (UnknownHostException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}).start();
		
	}
}

以上是关于安卓的Socket客户端开发及应用的主要内容,如果未能解决你的问题,请参考以下文章

Socket开发框架之框架设计及分析

Socket开发框架之框架设计及分析

php socket客户端及服务器端应用实例

安卓。片段 getActivity() 有时返回 null

安卓socket聊天

安卓通讯开发——蓝牙的开启,搜索与传输