智能手机的发展彻底颠覆了原有手机的定义,已不再仅仅只是电话短信工具,随着网络的发展与强大,智能手机更像是一个智能小型电脑,几乎能完成所有电脑可以完成的任务,笔者看来,智能手机的强大不仅在于融入我们的生活,而且改变了我们的生活习惯,一部智能手机几乎包揽了所有电子产品的功能,而且只要你有想法,只要你懂编程,就会有方法完成,android系统是一个完全开放的系统,笔者在android 4.0系统上,编写了wifi智能小车软件WifiCar,可以控制小车的运行、机械臂的旋转以及获取小车视频并显示。界面如下:
Android平台的四大组件:Activity、Service、ContentProvider、BroadcastReceiver
WifiCar使用了MainActivity作为窗口,主要负责UI的绘制并与用户交互,使用ConnecThread作为后台线程,负责连接网络与网络通信,包括WifiCar向路由发送控制命令和接收路由传回的视频图像。
(1)视频的获取
private void RefreshImage(){
try{
URL m_URL=new URL("http://"+board_ip+":8080/?action=snapshot");
URLConnection m_URL_Connection=m_URL.openConnection();
m_URL_Connection.connect();
InputStream m_InputStream=m_URL_Connection.getInputStream();
MainActivity.m_Bitmap=BitmapFactory.decodeStream(m_InputStream);
m_InputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
(2)建立命令连接,并打开输入输出流
private void cmdConnect(){
try {
MainActivity.cmdSocket=new Socket(board_ip,2001);
System.out.println("Client is created! site:"+board_ip+" port:"+"2001");
if(MainActivity.cmdSocket!=null){
MainActivity.cmdOutputStream=MainActivity.cmdSocket.getOutputStream();
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
(3)线程运行函数,run
public void run() {
// TODO Auto-generated method stub
super.run();
while(true)
{
board_ip=MainActivity.board_ip;
if(isRunning==true){
if(MainActivity.cmdSocket==null&& connectNum<3)
{
cmdConnect();
connectNum++;
}
if(MainActivity.cmdSocket!=null && cmdFlag==0)
{
Message msg=Message.obtain();
msg.what=0;
MainActivity.m_Handler.sendMessage(msg);
cmdFlag=1;
}
if(MainActivity.video_flag==1)
{
MainActivity.video_flag=0;
RefreshImage();
Message msg=Message.obtain();
msg.what=2;
MainActivity.m_Handler.sendMessageDelayed(msg, 100);
}
}
else if(MainActivity.cmdSocket!=null)
{
connectNum=0;
cmdFlag=0;
Message msg=Message.obtain();
msg.what=1;
MainActivity.m_Handler.sendMessage(msg);
try {
MainActivity.cmdSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MainActivity.cmdSocket=null;
}
}
}
(4)更新UI,采用handler,接收子线程发送的数据
public class MyHandler extends Handler{
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch(msg.what)
{
case 0:
connectBtn.setText("Ͽ");
showMessage("ґlӺ"+board_ip);
break;
case 1:
connectBtn.setText("lӢ);
showMessage("ґϿ:"+board_ip);
break;
case 2:
videoIv.setImageBitmap(m_Bitmap);
video_flag=1;
break;
}
}
}
(5)发送命令
try {
cmdOutputStream.write(cmdStr,0,4);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
全部源代码如下:
package com.example.wificar;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
publicclass MainActivity extends Activity{
public static Bitmap m_Bitmap;
public static String board_ip;
public staticint video_flag=1;
private byte[] cmdStr; //control commond
private int connect_flag;
public static MyHandler m_Handler;
public static Socket cmdSocket;
public static OutputStream cmdOutputStream;
ConnectThread mThread=null;
private ImageView videoIv;
private Button connectBtn;
private EditText ipEt;
private Button eyeTopBtn;
private Button eyeLeftBtn;
private Button eyeResetBtn;
private Button eyeRightBtn;
private Button eyeBottomBtn;
private Button forwardBtn;
private Button leftBtn;
private Button rightBtn;
private Button backwardBtn;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cmdStr=newbyte[4];
videoIv=(ImageView)findViewById(R.id.video);
ipEt=(EditText)findViewById(R.id.ip);
connectBtn=(Button)findViewById(R.id.connect);
eyeTopBtn=(Button)findViewById(R.id.eyeUp);
eyeLeftBtn=(Button)findViewById(R.id.eyeLeft);
eyeResetBtn=(Button)findViewById(R.id.eyeReset);
eyeRightBtn=(Button)findViewById(R.id.eyeRight);
eyeBottomBtn=(Button)findViewById(R.id.eyeDown);
forwardBtn=(Button)findViewById(R.id.forward);
leftBtn=(Button)findViewById(R.id.left);
rightBtn=(Button)findViewById(R.id.right);
backwardBtn=(Button)findViewById(R.id.backward);
connectBtn.setOnClickListener(new connectButtonListener());
eyeTopBtn.setOnClickListener(new CmdButtonOnClickListener());
eyeLeftBtn.setOnClickListener(new CmdButtonOnClickListener());
eyeResetBtn.setOnClickListener(new CmdButtonOnClickListener());
eyeRightBtn.setOnClickListener(new CmdButtonOnClickListener());
eyeBottomBtn.setOnClickListener(new CmdButtonOnClickListener());
forwardBtn.setOnClickListener(new CmdButtonOnClickListener());
leftBtn.setOnClickListener(new CmdButtonOnClickListener());
rightBtn.setOnClickListener(new CmdButtonOnClickListener());
backwardBtn.setOnClickListener(new CmdButtonOnClickListener());
ipEt.setText("192.168.1.1");
board_ip=ipEt.getText().toString();
m_Handler=new MyHandler();
mThread=new ConnectThread(board_ip);
mThread.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.activity_main, menu);
returntrue;
}
public class MyHandler extends Handler{
@Override
publicvoid handleMessage(Message msg){
// TODO Auto-generated method stub
super.handleMessage(msg);
switch(msg.what)
{
case0:
connectBtn.setText("Ͽ");
showMessage("ґlӺ"+board_ip);
break;
case1:
connectBtn.setText("lӢ);
showMessage("ґϿ:"+board_ip);
break;
case2:
videoIv.setImageBitmap(m_Bitmap);
video_flag=1;
break;
}
}
}
public class connectButtonListener implements android.view.View.OnClickListener{
@Override
publicvoid onClick(View v){
// TODO Auto-generated method stub
board_ip=ipEt.getText().toString();
if(connect_flag==0){
connect_flag=1;
mThread.setRunning(true);
}
else{
connect_flag=0;
mThread.setRunning(false);
}
}
}
private void showMessage(String str){
// TODO Auto-generated method stub
Toast toast=Toast.makeText(this, str, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.TOP,0,550);
toast.show();
}
class CmdButtonOnClickListener implements android.view.View.OnClickListener{
@Override
publicvoid onClick(View v){
// TODO Auto-generated method stub
if(cmdSocket!=null){
switch(v.getId())
{
case R.id.eyeUp:
cmdStr[0]='0';cmdStr[1]='0';cmdStr[2]='0';cmdStr[3]='1';
break;
case R.id.eyeLeft:
cmdStr[0]='0';cmdStr[1]='0';cmdStr[2]='1';cmdStr[3]='0';
break;
case R.id.eyeReset:
cmdStr[0]='0';cmdStr[1]='0';cmdStr[2]='1';cmdStr[3]='1';
break;
case R.id.eyeRight:
cmdStr[0]='0';cmdStr[1]='1';cmdStr[2]='0';cmdStr[3]='0';
break;
case R.id.eyeDown:
cmdStr[0]='0';cmdStr[1]='1';cmdStr[2]='0';cmdStr[3]='1';
break;
case R.id.forward:
cmdStr[0]='1';cmdStr[1]='0';cmdStr[2]='0';cmdStr[3]='1';
break;
case R.id.left:
cmdStr[0]='1';cmdStr[1]='0';cmdStr[2]='1';cmdStr[3]='0';
break;
case R.id.right:
cmdStr[0]='1';cmdStr[1]='1';cmdStr[2]='0';cmdStr[3]='0';
break;
case R.id.backward:
cmdStr[0]='1';cmdStr[1]='1';cmdStr[2]='0';cmdStr[3]='1';
break;
}
try{
cmdOutputStream.write(cmdStr,0,4);
}catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
package com.example.wificar;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import android.R.string;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Message;
public class ConnectThread extends Thread{
private String board_ip;
private boolean isRunning;
private int connectNum;
private int cmdFlag;
private int db1;
public ConnectThread(String ip){
board_ip=ip;
connectNum=0;
cmdFlag=0;
}
@Override
public void run(){
// TODO Auto-generated method stub
super.run();
while(true)
{
board_ip=MainActivity.board_ip;
if(isRunning==true){
if(MainActivity.cmdSocket==null&& connectNum<3)
{
cmdConnect();
connectNum++;
}
if(MainActivity.cmdSocket!=null&& cmdFlag==0)
{
Message msg=Message.obtain();
msg.what=0;
MainActivity.m_Handler.sendMessage(msg);
cmdFlag=1;
}
if(MainActivity.video_flag==1)
{
MainActivity.video_flag=0;
RefreshImage();
Message msg=Message.obtain();
msg.what=2;
MainActivity.m_Handler.sendMessageDelayed(msg,100);
}
}
elseif(MainActivity.cmdSocket!=null)
{
connectNum=0;
cmdFlag=0;
Message msg=Message.obtain();
msg.what=1;
MainActivity.m_Handler.sendMessage(msg);
try{
MainActivity.cmdSocket.close();
}catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
MainActivity.cmdSocket=null;
}
}
}
private void RefreshImage(){
try{
URL m_URL=new URL("http://"+board_ip+":8080/?action=snapshot");
URLConnection m_URL_Connection=m_URL.openConnection();
m_URL_Connection.connect();
InputStream m_InputStream=m_URL_Connection.getInputStream();
MainActivity.m_Bitmap=BitmapFactory.decodeStream(m_InputStream);
m_InputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
private void cmdConnect(){
try{
MainActivity.cmdSocket=new Socket(board_ip,2001);
System.out.println("Client is created! site:"+board_ip+" port:"+"2001");
if(MainActivity.cmdSocket!=null){
MainActivity.cmdOutputStream=MainActivity.cmdSocket.getOutputStream();
}
}catch(UnknownHostException e){
// TODO Auto-generated catch block
e.printStackTrace();
}catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void cmdDisconnect(){
try{
MainActivity.cmdSocket.close();
}catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void setRunning(boolean isRunning){
this.isRunning=isRunning;
}
}