1、基于 android 的远程视频监控系统(已开放源码)基本过程是 android 作为 socket 客户端将采集到的每一帧图像数据发送出去,PC 作为服务器接收并显示每一帧图像实现远程监控。图片如下(后来 PC 端加了个拍照功能)。(PS 。刚学 android 和 java 不久很多东西还不懂,高手若是知道哪些地方可以继续优化的话还请多多指点下啊)系统代码如下:一、android 手机客户端(1)AndroidManifest.xml 文件。添加 camera 和 socket 权限,并设置了程序开始执行的activity、(2)main.xml 设置 surfaceview 用于摄像头采
2、集图像的预览(3)login.xml 登录界面,用于输入服务器 IP(4)GetIP.java 获得服务器 IP 后,通过 Intent 启动 CameraTest 的 activity,ip 信息通过 Bundle 传递public class GetIP extends Activity String ipname = null;Overridepublic void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState);/ 设置全屏requestWindowFeature(Window.FEATURE
3、_NO_TITLE);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);setContentView(R.layout.main);final Builder builder = new AlertDialog.Builder(this); /定义一个 AlertDialog.Builder 对象builder.setTitle(“登录服务器对话框“); / 设置对话框的标题/装载/res/layout/login.xml 界面布
4、局TableLayout loginForm = (TableLayout)getLayoutInflater().inflate( R.layout.login, null);final EditText iptext = (EditText)loginForm.findViewById(R.id.ipedittext);builder.setView(loginForm); / 设置对话框显示的 View 对象/ 为对话框设置一个“登录”按钮builder.setPositiveButton(“登录“/ 为按钮设置监听器, new OnClickListener() Overridepub
5、lic void onClick(DialogInterface dialog, int which) /此处可执行登录处理ipname = iptext.getText().toString().trim();Bundle data = new Bundle();data.putString(“ipname“,ipname);Intent intent = new Intent(GetIP.this,CameraTest.class);intent.putExtras(data);startActivity(intent););/ 为对话框设置一个“取消”按钮builder.setNegat
6、iveButton(“取消“, new OnClickListener()Overridepublic void onClick(DialogInterface dialog, int which)/取消登录,不做任何事情。System.exit(1););/创建、并显示对话框builder.create().show();(5)CameraTest.java 程序主体。设置 PreviewCallback 后,每当一帧图像数据采集完成后将调用 PreviewCallback 的 onPreviewFrame 函数。在这里我们将 YUV 格式数据转为jpg,再启用线程将数据通过 socket
7、发送出去。public class CameraTest extends Activity SurfaceView sView;SurfaceHolder surfaceHolder;int screenWidth, screenHeight;Camera camera; / 定义系统所用的照相机boolean isPreview = false; /是否在浏览中private String ipname;SuppressWarnings(“deprecation“)Overridepublic void onCreate(Bundle savedInstanceState) super.on
8、Create(savedInstanceState);/ 设置全屏requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);setContentView(R.layout.main);/ 获取 IP 地址Intent intent = getIntent();Bundle data = intent.getExtras();ipname = dat
9、a.getString(“ipname“);screenWidth = 640;screenHeight = 480;sView = (SurfaceView) findViewById(R.id.sView); / 获取界面中 SurfaceView 组件surfaceHolder = sView.getHolder(); / 获得 SurfaceView 的 SurfaceHolder/ 为 surfaceHolder 添加一个回调监听器surfaceHolder.addCallback(new Callback() Overridepublic void surfaceChanged(S
10、urfaceHolder holder, int format, int width,int height) Overridepublic void surfaceCreated(SurfaceHolder holder) initCamera(); / 打开摄像头Overridepublic void surfaceDestroyed(SurfaceHolder holder) / 如果 camera 不为 null ,释放摄像头if (camera != null) if (isPreview)camera.stopPreview();camera.release();camera = n
11、ull;System.exit(0););/ 设置该 SurfaceView 自己不维护缓冲surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);private void initCamera() if (!isPreview) camera = Camera.open();if (camera != null parameters.setPreviewSize(screenWidth, screenHeight); / 设置预览照片的大小parameters.setPreviewFpsRange(20,30); / 每秒
12、显示 2030 帧parameters.setPictureFormat(ImageFormat.NV21); / 设置图片格式parameters.setPictureSize(screenWidth, screenHeight); / 设置照片的大小/camera.setParameters(parameters); / android2.3.3 以后不需要此行代码camera.setPreviewDisplay(surfaceHolder); / 通过 SurfaceView 显示取景画面camera.setPreviewCallback(new StreamIt(ipname); /
13、设置回调的类camera.startPreview(); / 开始预览camera.autoFocus(null); / 自动对焦 catch (Exception e) e.printStackTrace();isPreview = true;class StreamIt implements Camera.PreviewCallback private String ipname;public StreamIt(String ipname)this.ipname = ipname;Overridepublic void onPreviewFrame(byte data, Camera ca
14、mera) Size size = camera.getParameters().getPreviewSize();try/调用 pressToJpeg()将 YUV 格式图像数据 data 转为 jpg 格式YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);if(image!=null)ByteArrayOutputStream outstream = new ByteArrayOutputStream();pressToJpeg(new Rect(0, 0, size.w
15、idth, size.height), 80, outstream);outstream.flush();/启用线程将图像数据发送出去Thread th = new MyThread(outstream,ipname);th.start();catch(Exception ex)Log.e(“Sys“,“Error:“+ex.getMessage();class MyThread extends Threadprivate byte byteBuffer = new byte1024;private OutputStream outsocket;private ByteArrayOutputS
16、tream myoutputstream;private String ipname;public MyThread(ByteArrayOutputStream myoutputstream,String ipname)this.myoutputstream = myoutputstream;this.ipname = ipname;try myoutputstream.close(); catch (IOException e) e.printStackTrace();public void run() try/将图像数据通过 Socket 发送出去Socket tempSocket = n
17、ew Socket(ipname, 6000);outsocket = tempSocket.getOutputStream();ByteArrayInputStream inputstream = new ByteArrayInputStream(myoutputstream.toByteArray();int amount;while (amount = inputstream.read(byteBuffer) != -1) outsocket.write(byteBuffer, 0, amount);myoutputstream.flush();myoutputstream.close(
18、);tempSocket.close(); catch (IOException e) e.printStackTrace();二、PC 服务器端ImageServer.java 用于显示图像,并且可以拍照public class ImageServer public static ServerSocket ss = null;public static void main(String args) throws IOExceptionss = new ServerSocket(6000);final ImageFrame frame = new ImageFrame(ss);frame.se
19、tDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);while(true)frame.panel.getimage();frame.repaint();/*A frame with an image panel*/SuppressWarnings(“serial“)class ImageFrame extends JFramepublic ImagePanel panel;public JButton jb;public ImageFrame(ServerSocket ss)/ get screen dimen
20、sionsToolkit kit = Toolkit.getDefaultToolkit();Dimension screenSize = kit.getScreenSize();int screenHeight = screenSize.height;int screenWidth = screenSize.width;/ center frame in screensetTitle(“ImageTest“);setLocation(screenWidth - DEFAULT_WIDTH) / 2, (screenHeight - DEFAULT_HEIGHT) / 2);setSize(D
21、EFAULT_WIDTH, DEFAULT_HEIGHT);/ add panel to framethis.getContentPane().setLayout(null);panel = new ImagePanel(ss);panel.setSize(640,480);panel.setLocation(0, 0);add(panel);jb = new JButton(“拍照“);jb.setBounds(0,480,640,50);add(jb);saveimage saveaction = new saveimage(ss);jb.addActionListener(saveaction);public static final int DEFAULT_WIDTH = 640;public static final int DEFAULT_HEIGHT = 560;/*A panel that displays a tiled image*/SuppressWarnings(“serial“)