实现的功能就是两个手机在一个局域网内可以互相观看对方的摄像头图像,当然如果都是连接公网那么就能远程互看了,,,,和视频聊天差不多,,不过没有声音,,,,,,,,

源码是在网上找的(具体地址忘了,如有侵犯请告知),亲测能用,,其实一开始想直接用到自己现在做的东西上 ,不过直接加到自己现在的软件上,调试了一下发现,,我想多了,老天总是不让自己那么轻易的.......................

因为自己手头上只有一个手机,所以就自己发给自己了,本想像写其它文章似得详细叙述一番,看了一下表,,感觉还是算了吧,,昨天把程序加到自己的软件上然后修改,测试一直熬到了1点,然后下午上班的时候头疼,困,然后就睡了1个小时.............年轻人不要老熬夜,,对身体不好,

上面的是自己的摄像头预览的,

下面的是通过TCP传输过来的

源码如下

package com.example.realtimevideo;

import java.io.ByteArrayOutputStream;

import com.example.threadConnect.ClientThread;
import com.example.threadConnect.RevImageThread; import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.Window;
import android.view.WindowManager;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.widget.ImageView;
import android.widget.RelativeLayout; public class MainVideoActivity extends Activity{
RevImageThread revImageThread;
public static ImageView image;
private static Bitmap bitmap;
private static final int COMPLETED = 0x222; MyHandler handler;
ClientThread clientThread;
ByteArrayOutputStream outstream; SurfaceView surfaceView;
SurfaceHolder sfh;
Camera camera;
boolean isPreview = false; //是否在浏览中
static int screenWidth=300;
static int screenHeight=300; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main_video);
surfaceView = (SurfaceView)findViewById(R.id.surfaceView);
image=(ImageView)findViewById(R.id.imageView1); handler = new MyHandler();
clientThread = new ClientThread();
new Thread(clientThread).start(); revImageThread = new RevImageThread(handler);
new Thread(revImageThread).start(); DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;// 获取屏幕分辨率宽度
screenHeight = dm.heightPixels; image.setLayoutParams(new RelativeLayout.LayoutParams(screenWidth,screenHeight));
//image.setMaxHeight(screenHeight);
//image.setMaxWidth(screenWidth); image.setMaxHeight(screenHeight/2);
sfh = surfaceView.getHolder();
sfh.setFixedSize(screenWidth, screenHeight/2); sfh.addCallback(new Callback(){ @Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub } @Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
initCamera();
} @Override
public void surfaceDestroyed(SurfaceHolder arg0) {
if (camera != null) {
if (isPreview) camera.stopPreview();
camera.release();
camera = null;
} } }); } @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_video, menu);
return true;
} @SuppressWarnings("deprecation")
private void initCamera() {
if (!isPreview) {
int k = 0;
if((k=FindBackCamera())!=-1){
camera = Camera.open(k);
}else{
camera = Camera.open();
}
ClientThread.size = camera.getParameters().getPreviewSize();
}
if (camera != null && !isPreview) {
try{
camera.setPreviewDisplay(sfh); // 通过SurfaceView显示取景画面
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(screenWidth, screenHeight/4*3);
/* 每秒从摄像头捕获5帧画面, */
parameters.setPreviewFrameRate(5);
parameters.setPictureFormat(ImageFormat.NV21); // 设置图片格式
parameters.setPictureSize(screenWidth, screenHeight/4*3); // 设置照片的大小
camera.setDisplayOrientation(90);
camera.setPreviewCallback(new PreviewCallback(){
@Override
public void onPreviewFrame(byte[] data, Camera c) {
// TODO Auto-generated method stub
Size size = camera.getParameters().getPreviewSize();
try{
//调用image.compressToJpeg()将YUV格式图像数据data转为jpg格式
YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
if(image!=null){
Message msg = clientThread.revHandler.obtainMessage();
msg.what=0x111;
msg.obj=image;
clientThread.revHandler.sendMessage(msg);
}
}catch(Exception ex){
Log.e("Sys","Error:"+ex.getMessage());
}
} });
camera.startPreview(); // 开始预览
camera.autoFocus(null); // 自动对焦
} catch (Exception e) {
e.printStackTrace();
}
isPreview = true;
}
} static class MyHandler extends Handler{
@Override
public void handleMessage(Message msg){
if (msg.what == COMPLETED) {
bitmap = (Bitmap)msg.obj; //image.setPivotX(image.getWidth()/2);
//image.setPivotX(image.getHeight()/2); //image.setImageBitmap(bitmap);
image.setLayoutParams(new RelativeLayout.LayoutParams(screenWidth,screenHeight));
image.setImageBitmap(bitmap);
image.setRotation(90);
super.handleMessage(msg);
}
}
} //调用前置摄像头
private int FindFrontCamera(){
int cameraCount = 0;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras(); // get cameras number for ( int camIdx = 0; camIdx < cameraCount;camIdx++ ) {
Camera.getCameraInfo( camIdx, cameraInfo ); // get camerainfo
if ( cameraInfo.facing ==Camera.CameraInfo.CAMERA_FACING_FRONT ) {
// 代表摄像头的方位,目前有定义值两个分别为CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK后置
return camIdx;
}
}
return -1;
} //调用后置摄像头
private int FindBackCamera(){
int cameraCount = 0;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras(); // get cameras number for ( int camIdx = 0; camIdx < cameraCount;camIdx++ ) {
Camera.getCameraInfo( camIdx, cameraInfo ); // get camerainfo
if ( cameraInfo.facing ==Camera.CameraInfo.CAMERA_FACING_BACK ) {
// 代表摄像头的方位,目前有定义值两个分别为CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK后置
return camIdx;
}
}
return -1;
}
}

package com.example.threadConnect;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket; import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera.Size;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log; public class ClientThread implements Runnable {
private static Socket socket ;
private static ByteArrayOutputStream outputstream;
private static byte byteBuffer[] = new byte[1024];
public static Size size; //接受UI线程消息
public MyHandler revHandler; BufferedReader br= null;
static OutputStream os = null; @Override
public void run() {
Looper.prepare();
//接受UI发来的信息
revHandler = new MyHandler();
Looper.loop();
} public static class MyHandler extends Handler{
@Override
public void handleMessage(Message msg){
if(msg.what==0x111){
try {
socket = new Socket("192.168.3.10",8081);
os = socket.getOutputStream();
YuvImage image = (YuvImage) msg.obj;
if(socket.isOutputShutdown()){
Log.e("output is down","ljq");
}else{
os = socket.getOutputStream();
outputstream = new ByteArrayOutputStream();
image.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, outputstream);
ByteArrayInputStream inputstream = new ByteArrayInputStream(outputstream.toByteArray());
int amount;
while ((amount = inputstream.read(byteBuffer)) != -1) {
os.write(byteBuffer, 0, amount);
}
os.write("\n".getBytes());
outputstream.flush();
outputstream.close();
os.flush();
os.close();
socket.close();
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

package com.example.threadConnect;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket; import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message; public class RevImageThread implements Runnable { public Socket s;
public ServerSocket ss; //向UI线程发送消息
private Handler handler; private Bitmap bitmap;
private static final int COMPLETED = 0x222; public RevImageThread(Handler handler){
this.handler = handler;
} public void run()
{
byte [] buffer = new byte[1024];
int len = 0; try {
ss = new ServerSocket(8080);
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} InputStream ins = null;
while(true){ try {
s = ss.accept();
ins = s.getInputStream(); ByteArrayOutputStream outStream = new ByteArrayOutputStream();
while( (len=ins.read(buffer)) != -1){
outStream.write(buffer, 0, len);
}
ins.close(); byte data[] = outStream.toByteArray();
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); Message msg =handler.obtainMessage();
msg.what = COMPLETED;
msg.obj = bitmap;
handler.sendMessage(msg); outStream.flush();
outStream.close();
if(!s.isClosed()){
s.close();
} } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Bitmap bitmap = BitmapFactory.decodeStream(ins); }
} }

布局

<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"
android:orientation="vertical"
tools:context=".MainVideoActivity" > <SurfaceView
android:id="@+id/surfaceView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
/>
<ImageView
android:id="@+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:src="@drawable/ic_launcher"/>
</RelativeLayout>

权限

对了关于如何使用

这个程序把发送图像和接收图像做在了一块了

其实只有知道TCP通信应该就会用,,不对源程序没提供地址输入框,,,,,,,后期自己加上了,不过现在感觉需要修改,因为源程序是不停的申请不停的释放,,,,,,

未完,,待续,,改好了就把自己完善的代码奉上, 加详细解释,一步一步的写出来..................

Android之网络摄像头的更多相关文章

  1. Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  2. Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  3. 抓住“新代码”的影子 —— 基于GoAhead系列网络摄像头多个漏洞分析

    PDF 版本下载:抓住“新代码”的影子 —— 基于GoAhead系列网络摄像头多个漏洞分析 Author:知道创宇404实验室 Date:2017/03/19 一.漏洞背景 GoAhead作为世界上最 ...

  4. Android okHttp网络请求之Json解析

    前言: 前面两篇文章介绍了基于okHttp的post.get请求,以及文件的上传下载,今天主要介绍一下如何和Json解析一起使用?如何才能提高开发效率? okHttp相关文章地址: Android o ...

  5. Android okHttp网络请求之Get/Post请求

    前言: 之前项目中一直使用的Xutils开源框架,从xutils 2.1.5版本使用到最近的xutils 3.0,使用起来也是蛮方便的,只不过最近想着完善一下app中使用的开源框架,由于Xutils里 ...

  6. Android okHttp网络请求之文件上传下载

    前言: 前面介绍了基于okHttp的get.post基本使用(http://www.cnblogs.com/whoislcj/p/5526431.html),今天来实现一下基于okHttp的文件上传. ...

  7. Android okHttp网络请求之缓存控制Cache-Control

    前言: 前面的学习基本上已经可以完成开发需求了,但是在项目中有时会遇到对请求做个缓存,当没网络的时候优先加载本地缓存,基于这个需求我们来学习一直okHttp的Cache-Control. okHttp ...

  8. Android okHttp网络请求之Retrofit+Okhttp+RxJava组合

    前言: 通过上面的学习,我们不难发现单纯使用okHttp来作为网络库还是多多少少有那么一点点不太方便,而且还需自己来管理接口,对于接口的使用的是哪种请求方式也不能一目了然,出于这个目的接下来学习一下R ...

  9. Android检测网络是否正常代码!

    在Android开发中,如果该应用程序需要连接网络请求,那么最好我们先做一个检测网络是否在线的判断,否则程序容易出现卡死或FC等Bug,应该判断如果手机离线则弹出提示让用户检查网络,如果正常则继续执行 ...

随机推荐

  1. 关于DDL、DML和DCL的区别与理解

    2017年5月31日,天气阴.近期事情颇多,心情比较沉重. 端午刚过,早上上课,很多同学还处在端午的疲惫状态中没有回过神来,当然我也不例外.端午奔波三天,加上毕设的事情,可以说身心俱疲.状态不佳,整理 ...

  2. Textarea输入字数限制(兼容iOS&安卓)

    最近在做一个微信公众号的页面,其中有对textarea做输入字数限制,而且需要兼容iOS和安卓手机,下面直接贴代码: <!DOCTYPE html> <html lang=" ...

  3. DevExpress.XtraCharts曲线上的点所对应的坐标值

    private void chartControl_ObjectSelected(object sender, HotTrackEventArgs e) { e.Cancel = false; XYD ...

  4. nginx深入剖析

    1.nginx功能模块说明 nginx之所以很强大,是因为具有很多的强大的模块 nginx核心功能模块:nginx的核心功能模块负责nginx的全局应用,主要对应的是主配置文件中的Main区块和Eve ...

  5. Python 在子类中调用父类方法详解(单继承、多层继承、多重继承)

    Python 在子类中调用父类方法详解(单继承.多层继承.多重继承)   by:授客 QQ:1033553122   测试环境: win7 64位 Python版本:Python 3.3.5 代码实践 ...

  6. SQLServer 学习笔记之超详细基础SQL语句 Part 7

    Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 6------------------- 29 存储过程和触发器 存储过 ...

  7. JavaScript判断当前手机是Android还是iOS系统

    $(function () { var u = navigator.userAgent, app = navigator.appVersion; var isAndroid = u.indexOf(' ...

  8. Mac配置SDK+JDK环境

    1.打开默认终端设备,编辑.bash_profile文件,命令:vi .bash_profile 2.执行,打开文件,编辑,配置环境命令如下: ①JDK环境:export JAVA_HOME=/lib ...

  9. chrome中workspace配置达到同步修改本地文件的作用

    在前端开发中,我们经常需要在浏览器中进行调试,特别是一些样式的修改,如果你还是先在浏览器elements中调试好在复制到本地文件,那就真的out了. chrome浏览器的workspace功能完全可以 ...

  10. python数据类型之间的转换

    1,字符串转整型,前提条件是该字符串为纯数字. a = '1' a = int(a) 2,整型转字符串 a= 1 a = str(a) 3,整型转浮点型 a = 1 a = float(a) 4,浮点 ...