通过一段时间的学习和应用,理解了Android通信,通过这篇文章记录一下学习过程。
基于ESP8266的Android WiFi通信广泛应用于物联网领域,常用是通过局域网实现Android端和下位机的通信,达到控制目的。
此篇文章记录的内容,需要手机连接到WiFi模块,通过wifi让Android端和硬件部分处于同一个局域网内。Android网络通信通过socket编程实现网络的连接,通过IO流实现数据的发送与接收。
首先,创建一个Android项目,首先,需要给予APP网络权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
第二步,创建一个类SendThead,内容为发送和接收的代码,首先定义IP,端口port,以及接收/发送’变量,打开套接字实现网络的连接,连接结束关闭套接字,采取多线程实现信息的发送与接收:
package com.example.a14942.smart_see;
/**
* Created by 14942 on 2018/3/26.
*/
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
class SendThread implements Runnable {
private String ip;
private int port;
BufferedReader in;
PrintWriter out; //打印流
Handler mainHandler;
Socket s;
private String receiveMsg;
ArrayList<String> list = new ArrayList<String>();
public SendThread(String ip,int port, Handler mainHandler) { //IP,端口,数据
this.ip = ip;
this.port=port;
this.mainHandler = mainHandler;
}
/**
* 套接字的打开
*/
void open(){
try {
s = new Socket(ip, port);
//in收单片机发的数据
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
s.getOutputStream())), true);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 套接字的关闭
*/
void close(){
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
//创建套接字
open();
//BufferedReader
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(200);
close();
open();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if (!s.isClosed()) {
if (s.isConnected()) {
if (!s.isInputShutdown()) {
try {
Log.i("mr", "等待接收信息");
char[] chars = new char[1024]; //byte[] bys = new byte[1024];
int len = 0; //int len = 0;
while((len = in.read(chars)) != -1){ //while((len = in.read(bys)) != -1) {
System.out.println("收到的消息: "+new String(chars, 0, len)); in.write(bys,0,len);
receiveMsg = new String(chars, 0, len); // }
Message msg=mainHandler.obtainMessage();
msg.what=0x00;
msg.obj=receiveMsg;
mainHandler.sendMessage(msg);
}
} catch (IOException e) {
Log.i("mr", e.getMessage());
try {
s.shutdownInput();
s.shutdownOutput();
s.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
}
}
}
});
thread.start();
while (true) {
//连接中
if (!s.isClosed()&&s.isConnected()&&!s.isInputShutdown()) {
// 如果消息集合有东西,并且发送线程在工作。
if (list.size() > 0 && !s.isOutputShutdown()) {
out.println(list.get(0));
list.remove(0);
}
Message msg=mainHandler.obtainMessage();
msg.what=0x01;
mainHandler.sendMessage(msg);
} else {
//连接中断了
Log.i("mr", "连接断开了");
Message msg=mainHandler.obtainMessage();
msg.what=0x02;
mainHandler.sendMessage(msg);
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
try {
out.close();
in.close();
s.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
public void send(String msg) {
System.out.println("msg的值为: " + msg);
list.add(msg);
}
}
第三步,创建主活动,编写布局(xml)文件,这里我创建了一个温度显示框,和两个开关控制按钮(switch控件):
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/bb"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_x="30dp"
android:layout_y="130dp"
android:orientation="horizontal">
<TextView
android:id="@+id/textView2"
android:layout_width="50sp"
android:layout_height="wrap_content"
android:layout_marginLeft="33px"
android:text="湿度"
android:textColor="#000000"
android:textSize="18sp" />
<TextView
android:id="@+id/ttv2"
android:layout_width="160sp"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:text=""
android:textSize="18sp" />
<TextView
android:layout_width="60sp"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="10px"
android:text="%rh"
android:textColor="#000000"
android:textSize="18sp" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开 关"
android:textColor="#000000"
android:textSize="18sp"
android:layout_x="50dp"
android:layout_y="200dp"
/>
<Switch
android:id="@+id/Switch2"
android:layout_width="50sp"
android:layout_height="wrap_content"
android:layout_weight="1.01"
android:layout_x="210dp"
android:layout_y="270dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自动手动"
android:textColor="#000000"
android:textSize="18sp"
android:layout_x="50dp"
android:layout_y="270dp"
/>
<Switch
android:id="@+id/Switch1"
android:layout_width="50sp"
android:layout_height="wrap_content"
android:layout_x="210dp"
android:layout_y="200dp" />
</AbsoluteLayout>
第四步,编写主活动,包括实现网络连接(SendThead),实现消息的发送和接收,对开关控件(switch)定义点击事件:
package com.example.a14942.smart_see;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity{
/*接收发送定义的常量*/
private String mIp = "192.168.4.1";
private int mPort = 9000;
private SendThread sendthread;
String receive_Msg;
String l;
String total0,total1,total2,total3;
private Button button0;
private Button button1;
static PrintWriter mPrintWriterClient = null;
static BufferedReader mBufferedReaderClient = null;
Switch switch1,switch2;
/*****************************/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//getSupportActionBar().hide();
setContentView(R.layout.activity_main);
// button0= (Button)findViewById(R.id.Water_W_N);
// button0.setOnClickListener(button0ClickListener);
// button1= (Button)findViewById(R.id.Water_W_O);
// button1.setOnClickListener(button1ClickListener);
/***************连接*****************/
sendthread = new SendThread(mIp, mPort, mHandler);
Thread1();
new Thread().start();
/**********************************/
switch1 = (Switch) findViewById(R.id.Switch1);
switch1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// TODO Auto-generated method stub
if (isChecked) {
sendthread.send("A");
} else {
sendthread.send("B");
}
}
});
switch2 = (Switch) findViewById(R.id.Switch2);
switch2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// TODO Auto-generated method stub
if (isChecked) {
sendthread.send("C");
} else {
sendthread.send("D");
}
}
});
}
// private View.OnClickListener button0ClickListener = new View.OnClickListener() {
// public void onClick(View arg0) {
// mPrintWriterClient.print("j");
// mPrintWriterClient.flush();
//
// }
// };
// private View.OnClickListener button1ClickListener = new View.OnClickListener() {
// public void onClick(View arg0) {
// mPrintWriterClient.print("m");
// mPrintWriterClient.flush();
// }
// };
private class FragmentAdapter extends FragmentPagerAdapter {
List<Fragment> fragmentList = new ArrayList<Fragment>();
public FragmentAdapter(FragmentManager fm, List<Fragment> fragmentList) {
super(fm);
this.fragmentList = fragmentList;
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
}
/*接收线程*******************************************************************************/
/**
* 开启socket连接线程
*/
void Thread1(){
// sendthread = new SendThread(mIp, mPort, mHandler);
new Thread(sendthread).start();//创建一个新线程
}
Handler mHandler = new Handler()
{
public void handleMessage(Message msg)
{
TextView text0 = (TextView)findViewById(R.id.ttv2);
super.handleMessage(msg);
if (msg.what == 0x00) {
Log.i("mr_收到的数据: ", msg.obj.toString());
receive_Msg = msg.obj.toString();
l = receive_Msg;
text0.setText(l);
}
}
};
}
这样,一个简单的物联网通信就实现了。希望对大家有所帮助,如有疑问,欢迎留言。
本次文章一样的源码暂时找不到了,附上依托以上的代码开发的简单的demo示例
csdn:https://download.csdn.net/download/weixin_40042248/13456038