在OPhone上实现视频监控  

编辑文档

 

目录

1 一、登陆界面  

2 二、主界面  

3 三 现场界面  

4 四、帮助界面  

5 总结  

6 作者  

2009 年1 月,工信部宣布3G 牌照的正式发放,自此运营商全面布局各类业务竞争尤其激烈,3G 安防业务(手机视频)也包含其中,应该说手机视频监控业务是3G 时代的亮点业务,也是运营商炒作最热的亮点业务之一。然而,从消费和生活习惯来说,国内真正使用手机视频通话和手机电视的人群并不多,因此,手机视频监控受到运营商们的一致青睐,甚至被称为3G 业务中的“杀手级”业务!由于三大运营商有着巨大的客户资源,其推动的手机视频监控的业务得到了众多安防企业的追捧,各个安防厂商都希望在提供分得一杯羹。     目前国内很多的安防厂商都开发了自己的监控软件,但主要集中在windows mobile 和Symbian平台上面。Android手机系统自推出以来得到了很多手机厂商的支持和相应,Android系统得到了快速发展,而国内最大的移动运营商中国移动也推出了基于Android的操作系统OPhone。本文主要介绍如何在OPhone上实现视频监控。

登陆界面

 

 

编辑本段 回目录一、登陆界面

 

登陆界面主要完成相关信息的输入,提供了记忆功能,方便用户快捷输入。

 

(1)图片替换

图片可以替换成其他的LOGO,方便不同的定制需求。只需修改android:background参数,指定相应的文件即可

<ImageView 
     android:id="@+id/ImageView01" 
     xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" 
     android:layout_height="150dip"
     android:background="@drawable/logo"
     ></ImageView>

(2)界面组织

        界面编排采用了LinearLayout嵌套。使用LinearLayout中android:orientation参数进行横竖组织。         整体的XML布局采用了vertical方式

<LinearLayout
   android:layout_width="fill_parent"
   android:layout_height="fill_parent" 
   android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"></LinearLayout>

        在局部需要水平对齐的地方使用了horizontal方式  

<LinearLayout
   android:layout_width="fill_parent"
   android:layout_height="fill_parent" 
   android:orientation="horizontal" xmlns:android="http://schemas.android.com/apk/res/android"></LinearLayout>

 

(3)LinearLayout 和AbsoluteLayout 区别

Android 的UI 布局以Layout 作为容器,而LinearLayout和AbsoluteLayout 是两种最为常见的布局方式。LinearLayout以水平和垂直进行定位,采用的是相对坐标,而AbsoluteLayout 采用的是绝对坐标。如果要想实现软件界面在不同的手机上做到自适应,应该使用LinearLayout进行定位,避免使用AbsoluteLayout 。

主界面  

 

编辑本段 回目录二、主界面

 

      主界面采用了现在手机流行的九宫格布局方式。九宫格的布局看起来比较复杂,但是由于系统提供了GridView控件,使得实现起来变得非常简单。         GridView的XML文件布局如下

<GridView android:id="@+id/GridView01" android:layout_width="fill_parent" android:layout_height="fill_parent" android:numColumns="3" android:verticalSpacing="45dp" android:horizontalSpacing="35dp" android:columnWidth="80dp" android:gravity="center" android:layout_marginTop="10dip" android:layout_marginBottom="10dip" android:layout_marginLeft="10dip" android:layout_marginRight="10dip" android:focusable="false"></GridView>

为GridView添加相应函数:

gridview.setOnItemClickListener(new ItemClickListener()); class ItemClickListener implements OnItemClickListener { public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { switch(arg2) { case 0: break; case 1: break; case 2: break; case 3: break; case 4: break; case 5: break; case 6: break; case 7: break; case 8: break; } } }

    为switch的分支提供不同的响应函数即可。九个自界面均采用了activity进行显示, 需要在AndroidManifest.xml添加不同的activity, 否则运行的时候会出现异常. 由于笔者对Android平台开发不是很熟悉,在这个地方也花费了不少的时间。     由于篇幅和界面的相关性, 下面主要对现场界面和帮助界面进行说明,其他的不再重复

 

 

 

编辑本段 回目录三 现场界面

 

现场界面

现场界面是整个工程当中最关键的部分,也是工作量最大的部分。主要包含了网络协议实现,视频的解码, 视频的显示,音频的解码,音频的采集和播放,录像文件的读写和界面控制逻辑模块。     网络协议部分主要是用了TCP协议。在使用OPhone平台使用网络连接时, 需要在AndroidManifest.xml文件当中添加网络访问的能力,<uses-permission  android:name="android.permission.INTERNET"></uses-permission>,否则会报异常错误。     下面介绍下在客户端在OPhone平台下用Socket连接数据通信的过程  

(1)创建socket连接

m_Socket = new Socket(“192.168.3.123”,”8002”); 

 

(2)获取Socket上的输入输出流,进行数据的收发  

InputStream m_Reader = m_Socket.getInputStream();                                                                           

(3)关闭连接 m_Socket.shutdownInput(); m_Socket.shutdownOutput(); m_Socket.close(); 

  建议在步骤二完成后,创建一个单独的线程用于数据的接收,可以避免因长时间接收不到数据造成的阻塞现象。   

Thread thread = new Thread(null, doBackgroundThreadProcessing, "Background"); thread.start(); public Runnable doBackgroundThreadProcessing = new Runnable() { public void run() { backgroundThreadProcessing(); } }; public void backgroundThreadProcessing() { while(isSocketRunning) { try { //接收数据 int iReadLenght = m_Reader.read(test); //处理数据,送去解码播放 } catch(Exception e) { e.printStackTrace(); break; } } System.out.println("Socket Client Exit"); } 

视频和音频的解码, 录像文件的读写主要是采用了Java的JNI技术,移植了相关的库文件。 解码库的移植可以参考OPhone开*坛上的一篇《H264×××移植到OPhone》的文章。由于以前在Wince和Symbian平台上均开发过类似的解码库, 所以不用在移植解码库上花费时间。 如果没有相关的解码库,可以参考ffmpeg项目中的libavcodec进行移植。 这里好像一笔带过, 但相信做过解码库移植的朋友肯定能体会其中的滋味, 呵呵。

        这里给大家提供几个JNI当中常见的类型转换,避免在相同的问题上浪费时间。  (1).  Char*转jbyteArray

Thread thread = new Thread(null, doBackgroundThreadProcessing, "Background"); thread.start(); public Runnable doBackgroundThreadProcessing = new Runnable() { public void run() { backgroundThreadProcessing(); } }; public void backgroundThreadProcessing() { while(isSocketRunning) { try { //接收数据 int iReadLenght = m_Reader.read(test); //处理数据,送去解码播放 } catch(Exception e) { e.printStackTrace(); break; } } System.out.println("Socket Client Exit"); } 

 (2).  jbyteArray转char* char * strBuffer = NULL; jsize len = env->GetArrayLength(pInBuffer); jbyte *arrayBody = env->GetByteArrayElements(pInBuffer, 0); if(len>0) { strBuffer = new char[len + 1]; memcpy(strBuffer, arrayBody, len); strBuffer[len] = 0; } 

在Wince和Symbian平台上, 视频的现实可以直接通过写屏幕的方式实现, 效率更高。但是在搜索了相关的信息后,发现在OPhone上没有提供写屏的相关函数,所以采用了贴图的方式, 即将解码完的RGB565的数据写成BMP, 然后再ImageView上显示, 效率并没有先前担心的那么差, 可以接受。         由于OPhone平台只允许在主线程中调用相关View的方法来更新界面。如果返回结果在新线程中获得,那么必须借助Handler来更新界面。所以视频的现实也采用了Handler来刷新显示。 Handler myhandle = new Handler() { public void handleMessage(Message msg) { //刷新界面 super.handleMessage(msg); } }; 

如果要全屏显示, 主要将bitmap进行缩放至屏幕大小,并进行90度的旋转即可 Matrix matrix = new Matrix(); matrix.postScale(1, 1); matrix.postRotate(90); Bitmap temp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); Bitmap resizedBitmap =Bitmap.createScaledBitmap(temp, NewWidth , NewHeight, false); 

 

 

编辑本段 回目录四、帮助界面

 

帮助界面

帮助界面主要采用了一个WebView显示一个网页。  

<?xml version="1.0" encoding="utf-8"?>   
 <LinearLayout   
   xmlns:android="http://schemas.android.com/apk/res/android"  
   android:layout_width="fill_parent"  
   android:layout_height="fill_parent">   
     
   <WebView   
     android:id="@+id/web"  
     android:layout_width="fill_parent"  
     android:layout_height="fill_parent"  
     android:text="Help"  
     />   
 </LinearLayout>

显示一个单纯的文本的网页很简单,只需将help.html放到res目录的Raw文件夹下面,按下面的代码即可完成调用:

WebView web = (WebView)findViewById(R.id.web); final String mimetype = "text/html"; final String encoding = "UTF-8"; String htmldata = "<html><body>boo</body></html>"; { String data = loadResToString(R.raw.help, this); if (data != null) htmldata = data; } web.loadDataWithBaseURL("fake://not/needed",htmldata,mimetype, encoding,"");

但是如果要显示带图片的网页,就必须将网页相关的图片放到assets目录下, 并将help.html链接图片的地方改为file:///android_asset/xxx.JPG即可

 

 

编辑本段 回目录总结

 

    本文主要介绍了如何在OPhone平台下实现视频监控功能,为以后需要从事相关开发的程序员提供一个参考。由于自己本人也是一个OPhone的初学者, 难免文章中会出现一些纰漏, 欢迎大家交流指正。

 

 

编辑本段 回目录作者

 

    深圳同为数码科技有限公司  仲阳

转载于:https://blog.51cto.com/2397078/433784