JOIM:Android通过IPCamera通过互联网实时监控功能的实现
Android系统:2.3.1
IPCamera:F系列
开发板:A8-Tiny210
这几天一直在研究Android上的IPCamera实时监控功能。业务流程是这样的:
用户申请监控后,Android端打开一个线程每隔200ms向服务器发送HTTP请求(请求获取当前的摄像头图片,是的,我也是用了刷图片的效果)。
服务器端向IPCamera发送一段带有cgi参数的http请求到IPCamera,获取到图片流信息,然后封装成字符串(byteàString),发送到客户端,经过解析(byteàbitmap),然后经过宽和高的设置,刷到ImageView上。
首先,Android端开启了一个线程,当用户按下ImageView时启动,实现代码如下:
private Runnable refreshCameraRunnable = new Runnable() {
@Override
publicvoid run() {
while (cameraFlag) {
try {
//这是一个ThreadHandler,且看下面介绍.
cameraHanler.sendEmptyMessage(0);
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//向用户线程发送消息,刷新一下ImageView。
Message msg = new Message();
recoverHandler.sendMessage(msg);
}
private Handler recoverHandler = new Handler() {
@Override
publicvoid handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
//这是最开始ImageView的默认图片,在用户申请关闭监控后,恢复之
ivCamera.setImageResource(R.drawable.esto_main_new_2);
}
};
};
我重新定义了一个MyThreadHandler,继承自ThreadHanler,在这里面做ImageView刷新图片的功能(所以,在构造的时候要把ImageView传递过去了!)在handleMessage中,发送HTTP请求,获取InputStream,解析成Bitmap,在用户线程上重新set一下Image,这样客户端就好了。代码如下:
@Override
publicboolean handleMessage(Message arg0) {
Message msg = new Message();
refreshImg.sendMessage(msg);
returntrue;
}
//我说明一下,Android的消息机制恐怕我学习的还是太浅了,这样AàB,B再给A发消息这//样的操作感觉非常冗余。
private Handler refreshImg = new Handler() {
@Override
publicvoid handleMessage(Message msg) {
super.handleMessage(msg);
refreshImg();
}
};
privatestaticvoid refreshImg() {
try {
URL url = new URL(strURL);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(5 * 1000);
con.setRequestMethod("POST");
con.setRequestProperty("Charset", "UTF-8"); con.setRequestProperty("Content-Type","multipart/form-data");
con.setChunkedStreamingMode(1024 * 100);
con.setDoOutput(true);
OutputStream out = con.getOutputStream();
out.flush();
out.close();
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = con.getInputStream();
String strCamera = "";
byte[] membytes = newbyte[1024];
int bLength = 0;
while ((bLength = inputStream.read(membytes)) != -1) {
strCamera += new String(membytes, 0, bLength);
}
Bitmap bitmap = null;
try {
byte[] bitmapArray;
bitmapArray = Base64.decode(strCamera, Base64.DEFAULT);
bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0,bitmapArray.length);
} catch (Exception e) {
e.printStackTrace();
}
int width = ivPlayVedio.getWidth();
int height = ivPlayVedio.getHeight();
//这里,限制Bitmap的长度和宽度与ImageView的w、h相同。
ivPlayVedio.setImageBitmap(BitMapUtils.scaleImg(bitmap, width,height));
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
客户端完毕.
服务器端,拦截到android的http请求后,执行响应的post方法,我的IPCamera的IP是XXX,端口是81,所以URL就是http://XXX:81/, IPCamera是以CGI的格式获取用户名、密码等信息的,所以这块要好好的研究一下API了,我这边是F系列的,查看了文档之后,完成的URL如下:
http://XXX:81/snapshot.cgi?user=admin&pwd=&next_url=0
CGI的参数不同的型号可能不一样,详细的自己去看相关API吧!
同样是发送HTTP请求,这边的数据流是这样处理的:
InputStream inputStream = con.getInputStream();
int len = 0;
byte[] img = newbyte[1024];
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while ((len = inputStream.read(img)) != -1) {
byteArrayOutputStream.write(img, 0, len);
}
byte byteImg[] = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.close();
inputStream.close();
result += (new BASE64Encoder().encode(byteImg));
把result发送给客户端,这样一个完整的
客户端ß-à服务器ß-àIPCamera的请求与处理就完成了。呵呵,java的InputStream和outputStream给我们节省了很多复杂的事情。三天的时间,从对IPCamera一无所知到将摄像头功能加入到项目中,真的很高兴啊!
我的xt210手机的300W像素一般啊,不过我的板子2G的内存,实现这个实时监控的功能,效果非常非常好呢!
呵呵
更多相关文章
- Android多线程下载远程图片
- android-【机型-版本-分辨率】测试点罗列
- Android(安卓)NDK 面试题汇总
- Android(安卓)各大网络请求库的比较及实战
- 深入理解Android消息处理系统——Looper、Handler、Thread
- Android之AIDL进程之间的通信
- 深入理解Android消息处理系统——Looper、Handler、Thread
- Android之Handler到HandlerThread
- Android(安卓)- Handler 、AsyncTask(一)