android IOIO是通过安卓手机的USB接口控制的电路板,通过android IOIO可以不需要太多的硬件知识,通过安卓手机转接的IOIO板控制外围设备,配件有纸盒、L298N电机驱动模块、旧手机一部(系统必须在安卓2.3以上(与IOIO的固件有关)),旧手机电池两块,LED灯一组,USB线一根、减速电机带轮子 两个、万向轮一个、杜邦线6根左右就够了

先搭好硬件环境,然后进行安卓代码的编写,以下是代码:

视频传输部分参考了网上的代码

public class SocketCameraActivity extends IOIOActivity implements SurfaceHolder.Callback,

Camera.PreviewCallback{

private SurfaceView mSurfaceview = null; // SurfaceView对象:(视图组件)视频显示

private SurfaceHolder mSurfaceHolder = null; // SurfaceHolder对象:(抽象接口)SurfaceView支持类

private Camera mCamera = null; // Camera对象,相机预览

DigitalOutput left,right,light;

ServerSocket ser_socket;

Socket cli_socket;

 

private String pUsername="XZY";

 

private String serverUrl="192.168.1.100";

 

private int serverPort=8888;

 

private int VideoPreRate=1;

 

private int tempPreRate=0;

 

private int VideoQuality=85;

 

private float VideoWidthRatio=1;

 

private float VideoHeightRatio=1;

 

private int VideoWidth=320;

 

private int VideoHeight=240;

 

private int VideoFormatIndex=0;

 

private boolean startSendVideo=false;

 

private boolean connectedServer=false;

private Button myBtn01, myBtn02;

 

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

//禁止屏幕休眠

getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,

WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

mSurfaceview = (SurfaceView) findViewById(R.id.camera_preview);

myBtn01=(Button)findViewById(R.id.button1);

myBtn02=(Button)findViewById(R.id.button2);

ServerThread st=new ServerThread();

st.start();

//开始连接主机按钮

myBtn01.setOnClickListener(new OnClickListener(){

public void onClick(View v) {

//Common.SetGPSConnected(LoginActivity.this, false);

if(connectedServer){//停止连接主机,同时断开传输

startSendVideo=false;

connectedServer=false;

myBtn02.setEnabled(false);

myBtn01.setText("开始连接");

myBtn02.setText("开始传输");

//断开连接

Thread th = new MySendCommondThread("PHONEDISCONNECT|"+pUsername+"|");

th.start();

}

else//连接主机

{

//启用线程发送命令PHONECONNECT

Thread th = new MySendCommondThread("PHONECONNECT|"+pUsername+"|");

th.start();

connectedServer=true;

myBtn02.setEnabled(true);

myBtn01.setText("停止连接");

}

}});

myBtn02.setEnabled(false);

myBtn02.setOnClickListener(new OnClickListener(){

public void onClick(View v) {

if(startSendVideo)//停止传输视频

{

startSendVideo=false;

myBtn02.setText("开始传输");

}

else{ // 开始传输视频

startSendVideo=true;

myBtn02.setText("停止传输");

}

}});

}

@Override

public void onStart()//重新启动的时候

{

mSurfaceHolder = mSurfaceview.getHolder(); // 绑定SurfaceView,取得SurfaceHolder对象

mSurfaceHolder.addCallback(this); // SurfaceHolder加入回调接口

mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 设置显示器类型,setType必须设置

//读取配置文件

SharedPreferences preParas = PreferenceManager.getDefaultSharedPreferences(SocketCameraActivity.this);

pUsername=preParas.getString("Username", "XZY");

serverUrl=preParas.getString("ServerUrl", "172.17.95.1");

String tempStr=preParas.getString("ServerPort", "8888");

serverPort=Integer.parseInt(tempStr);

tempStr=preParas.getString("VideoPreRate", "1");

VideoPreRate=Integer.parseInt(tempStr);

tempStr=preParas.getString("VideoQuality", "85");

VideoQuality=Integer.parseInt(tempStr);

tempStr=preParas.getString("VideoWidthRatio", "100");

VideoWidthRatio=Integer.parseInt(tempStr);

tempStr=preParas.getString("VideoHeightRatio", "100");

VideoHeightRatio=Integer.parseInt(tempStr);

VideoWidthRatio=VideoWidthRatio/100f;

VideoHeightRatio=VideoHeightRatio/100f;

super.onStart();

}

@Override

protected void onResume() {

super.onResume();

InitCamera();

}

 

private void InitCamera(){

try{

mCamera = Camera.open();

} catch (Exception e) {

e.printStackTrace();

}

}

@Override

protected void onPause() {

super.onPause();

try{

if (mCamera != null) {

mCamera.setPreviewCallback(null); // !!这个必须在前,不然退出出错

mCamera.stopPreview();

mCamera.release();

mCamera = null;

}

} catch (Exception e) {

e.printStackTrace();

}

}

@Override

public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

// TODO Auto-generated method stub

if (mCamera == null) {

return;

}

mCamera.stopPreview();

mCamera.setPreviewCallback(this);

mCamera.setDisplayOrientation(90); //设置横行录制

//获取摄像头参数

Camera.Parameters parameters = mCamera.getParameters();

Size size = parameters.getPreviewSize();

VideoWidth=size.width;

VideoHeight=size.height;

VideoFormatIndex=parameters.getPreviewFormat();

mCamera.startPreview();

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

// TODO Auto-generated method stub

try {

if (mCamera != null) {

mCamera.setPreviewDisplay(mSurfaceHolder);

mCamera.startPreview();

}

} catch (IOException e) {

e.printStackTrace();

}

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

// TODO Auto-generated method stub

if (null != mCamera) {

mCamera.setPreviewCallback(null); // !!这个必须在前,不然退出出错

mCamera.stopPreview();

mCamera.release();

mCamera = null;

}

}

@Override

public void onPreviewFrame(byte[] data, Camera camera) {

// TODO Auto-generated method stub

//如果没有指令传输视频,就先不传

if(!startSendVideo)

return;

if(tempPreRate

tempPreRate++;

return;

}

tempPreRate=0;

try {

if(data!=null)

{

Log.d("YuvImage","success");

YuvImage image = new YuvImage(data,VideoFormatIndex, VideoWidth, VideoHeight,null);

if(image!=null)

{

ByteArrayOutputStream outstream = new ByteArrayOutputStream();

//在此设置图片的尺寸和质量

image.compressToJpeg(new Rect(0, 0, (int)(VideoWidthRatio*VideoWidth),

(int)(VideoHeightRatio*VideoHeight)), VideoQuality, outstream);

outstream.flush();

//启用线程将图像数据发送出去

Thread th = new MySendFileThread(outstream,pUsername,serverUrl,serverPort);

th.start();

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

 

public boolean onCreateOptionsMenu(Menu menu)

{

menu.add(0,0,0,"系统设置");

menu.add(0,1,1,"关于程序");

menu.add(0,2,2,"退出程序");

return super.onCreateOptionsMenu(menu);

}

 

public boolean onOptionsItemSelected(MenuItem item)

{

super.onOptionsItemSelected(item);//获取菜单

switch(item.getItemId())//菜单序号

{

case 0:

//系统设置

{

Intent intent=new Intent(this,SettingActivity.class);

startActivity(intent);

}

break;

case 1://关于程序

{

new AlertDialog.Builder(this)

.setTitle("关于本程序")

.setMessage("遥控小车程序")

.setPositiveButton

(

"我知道了",

new DialogInterface.OnClickListener()

{

@Override

public void onClick(DialogInterface dialog, int which)

{

}

}

)

.show();

}

break;

case 2://退出程序

{

//杀掉线程强制退出

android.os.Process.killProcess(android.os.Process.myPid());

}

break;

}

return true;

}

 

class MySendCommondThread extends Thread{

private String commond;

public MySendCommondThread(String commond){

this.commond=commond;

}

public void run(){

//实例化Socket

try {

Socket socket=new Socket(serverUrl,serverPort);

PrintWriter out = new PrintWriter(socket.getOutputStream());

out.println(commond);

out.flush();

} catch (UnknownHostException e) {

} catch (IOException e) {

}

}

}

 

class MySendFileThread extends Thread{

private String username;

private String ipname;

private int port;

private byte byteBuffer[] = new byte[1024];

private OutputStream outsocket;

private ByteArrayOutputStream myoutputstream;

public MySendFileThread(ByteArrayOutputStream myoutputstream,String username,String ipname,int port){

this.myoutputstream = myoutputstream;

this.username=username;

this.ipname = ipname;

this.port=port;

try {

myoutputstream.close();

} catch (IOException e) {

e.printStackTrace();

}

}

public void run() {

try{

//将图像数据通过Socket发送出去

Socket tempSocket = new Socket(ipname, port);

outsocket = tempSocket.getOutputStream();

//写入头部数据信息

String msg=java.net.URLEncoder.encode("PHONEVIDEO|"+username+"|","utf-8");

byte[] buffer= msg.getBytes();

outsocket.write(buffer);

ByteArrayInputStream inputstream = new ByteArrayInputStream(myoutputstream.toByteArray());

int amount;

while ((amount = inputstream.read(byteBuffer)) != -1) {

outsocket.write(byteBuffer, 0, amount);

}

myoutputstream.flush();

myoutputstream.close();

tempSocket.close();

Log.d("MySendFileThread","success");

} catch (IOException e) {

e.printStackTrace();

}

}

}

class Looper extends BaseIOIOLooper {

@Override

protected void setup() throws ConnectionLostException {

left=ioio_.openDigitalOutput(1);

right=ioio_.openDigitalOutput(2);

light=ioio_.openDigitalOutput(3);

left.write(true);

right.write(true);

light.write(true);

}

@Override

public void loop() throws ConnectionLostException {

}

}

@Override

protected IOIOLooper createIOIOLooper() {

return new Looper();

}

public void go()

{

try {

left.write(false);

right.write(false);

} catch (ConnectionLostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public void nstop()

{

try {

left.write(true);

right.write(true);

} catch (ConnectionLostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public void goleft()

{

try {

left.write(false);

right.write(true);

} catch (ConnectionLostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public void goright()

{

try {

left.write(true);

right.write(false);

} catch (ConnectionLostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public void lightOn()

{

try {

light.write(false);

} catch (ConnectionLostException e) {

e.printStackTrace();

}

}

public void lightOff()

{

try {

light.write(true);

} catch (ConnectionLostException e) {

e.printStackTrace();

}

}

class ServerThread extends Thread

{

public void run()

{

try {

ser_socket=new ServerSocket(8000);

} catch (IOException e) {

e.printStackTrace();

}

while (true)

{

try {

cli_socket = ser_socket.accept();

Log.e("接受连接", "accept");

BufferedReader in = new BufferedReader(new InputStreamReader(cli_socket.getInputStream()));

String str ="";

String temp;

while((temp=in.readLine())!=null)

{

str=str+temp;

Log.e("收到数据",temp);

if(temp.equals("lightOn"))

{

Log.d("收到","lightOn");

lightOn();

}

if(temp.equals("lightOff"))

{

lightOff();

}

if(temp.equals("go"))

{

go();

}

if(temp.equals("nstop"))

{

nstop();

}

if(temp.equals("goleft"))

{

goleft();

}

if(temp.equals("goright"))

{

goright();

}

}

}

catch (Exception e)

{

e.printStackTrace();

}

finally

{

try

{

cli_socket.close();

}

catch (IOException e)

{

e.printStackTrace();

}

}

}

}

}

}