主要实现录制功能的类:Camera类和MediaRecorder类。功能描写叙述:首先进入视频录制界面,点击录像button进入录像功能界面,点击录制開始录制视频, 点击停止button,将录制的视频存放到指定文件夹下存放。以下通过Samples_10_3程序实现详细功能:

(1)新建一个Android Application Project项目取名为Samples_10_3

(2)在res/layout文件改动activity_main.xml主布局文件(主要加入一个标题和摄像button)

<?xml version="1.0" ?

>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"> <TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"/> <Button
android:id="@+id/camera_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="摄像"/>
</LinearLayout>

(3)由于要实现摄像的功能。在res/layout文件夹下加入video.xml布局文件(主要包含SurfaceView视图控件、摄像button和停止摄像button)

<?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"
android:id="@+id/linearLayout1" >
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="0.58"/>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"> <Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="录制"/>
<Button
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止"/>
</LinearLayout>
</LinearLayout>

(4)首先须要给程序必要的权限才干读/写、訪问Camera、录制音频文件、创建删除文件等权限。在程序的AndroidManifest.xml程序清单文件下加入例如以下权限:

读取Camera权限

<uses-permission android:name="android.permission.CAMERA" ></uses-permission>
视频录制权限
<span style="color:#ff0000;"><uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission></span>
读写内存卡权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
创建和删除文件文件夹权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

由于由于VideoRecord.java类是还有一个Activity所以还须要在AndroidMainifest.xml文件里加入这样一段代码(一般这里的类名须要写完整的类结构):

<activity android:name=".VideoRecord"></activity>

(5)以下就是两个Activity实现布局文件调用和详细功能的实现:MainActivity.java类(摄像主界面)和VideoRecord类(摄像功能):

A.MainActivity.java类的详细实现:

package com.example.samples_10_3;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.content.Intent; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Button button=(Button)this.findViewById(R.id.camera_button); //实例化摄像按钮对象
button.setOnClickListener(new View.OnClickListener() {
//为摄像按钮加入事件监听
@Override
public void onClick(View arg0) {
Intent intent=new Intent();
intent.setClass(MainActivity.this, VideoRecord.class); //intent对象指定的类
MainActivity.this.startActivity(intent); //启动新的Activity
}
});
} @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, menu);
return true;
} }

B.VideoRecord类的详细实现:

package com.example.samples_10_3;

import android.app.Activity;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.widget.Button;
import android.media.MediaRecorder;
import android.hardware.Camera;
import java.io.File;
import android.os.Bundle;
import android.graphics.PixelFormat;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.content.pm.ActivityInfo;
import android.os.Environment;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.media.MediaRecorder.OnErrorListener;
import java.io.IOException;
import android.view.KeyEvent;
import android.content.Intent; public class VideoRecord extends Activity implements Callback {
private SurfaceView surfaceView=null; //创建一个空的SurfaceView对象
private SurfaceHolder surfaceHolder=null; //创建一个空的SurfaceHolder对象
private Button startButton=null; //创建一个開始录制Button组件对象
private Button stopButton=null; //创建一个停止录制Button组件对象
private MediaRecorder mediaRecorder=null; //创建一个空的MediaRecorder对象
private Camera camera=null; //创建一个空的Camera对象
private boolean previewRunning=false; //预览状态
private File videoFile=null; //录制视频文件的File对象
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.getWindow().setFormat(PixelFormat.TRANSLUCENT); //窗体设为半透明
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //窗体去掉标题
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //窗体设置为全屏
//setRequestedOrientation类翻转Preview
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //设置预览水平翻转
this.setContentView(R.layout.video); surfaceView=(SurfaceView)this.findViewById(R.id.surface_view); //实例化SurfaceView对象
surfaceHolder=surfaceView.getHolder(); //获取SurfaceHolder对象
surfaceHolder.addCallback(this); //注冊实现好的Callback
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); //设置缓存类型
startButton=(Button)this.findViewById(R.id.start); //实例化開始录制button的Button组件对象
stopButton=(Button)this.findViewById(R.id.stop); //实例化停止录制button的Button组件对象
startButton.setEnabled(true);
stopButton.setEnabled(false); //加入摄像button单击监听
startButton.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
// 调用開始摄像方法
startRecording();
}
});
//加入停止button单击监听
stopButton.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
//调用停止摄像方法
stopRecording();
}
});
}
/**
* 開始摄像方法
*/
public void startRecording()
{
try
{
stopCamera(); //调用停止Camera方法
if(!getStorageState()) //推断是否有存储卡。假设没有就关闭页面
{
VideoRecord.this.finish();
}
//获取存储(sdCard)的根文件夹
String sdCard=Environment.getExternalStorageDirectory().getPath();
//设置相片存放的文件夹
String dirFilePath=sdCard+File.separator+"MyVideo";
//获取录制文件夹路径的File对象
File dirFile=new File(dirFilePath);
if(!dirFile.exists()) //推断文件夹是否存在
{
dirFile.mkdir(); //创建文件
}
//创建录制视频暂时文件
videoFile=File.createTempFile("video", ".3gp",dirFile);
//初始化MediaRecorder对象
mediaRecorder=new MediaRecorder(); mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); //设置预览
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); //Camera视频源
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); //录音源为麦克风 //输出格式为3gp格式
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setVideoSize(480, 320); //视频尺寸
mediaRecorder.setVideoFrameRate(15); //视频帧的频率
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); //视频编码
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //音频编码
mediaRecorder.setMaxDuration(10000); //最大期限
mediaRecorder.setOutputFile(videoFile.getAbsolutePath()); //保存路径
mediaRecorder.prepare(); //准备录制
mediaRecorder.start(); //開始录制
//文件录制错误监听
mediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() { @Override
public void onError(MediaRecorder arg0, int arg1, int arg2) {
// 停止摄像方法
stopRecording();
}
});
startButton.setText("录制中");
startButton.setEnabled(false); //開始录制button失效
stopButton.setEnabled(true); //停止录制button生效
}catch(Exception e)
{
e.printStackTrace();
}
}
/**
* 手机按键监听事件
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
//推断手机按键按下是否是返回键
if(keyCode==KeyEvent.KEYCODE_BACK)
{
stopRecording(); //调用停止摄像方法
Intent intent=new Intent(); //初始化Intent
intent.setClass(VideoRecord.this, MainActivity.class); //指定Intent对象启动的类
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //清楚该进程空间中的全部Activity
this.startActivity(intent); //启动新的Activity
VideoRecord.this.finish(); //销毁这个Activity
}
return super.onKeyDown(keyCode, event);
}
/**
* 获取sdCard存储状态
* @return 手机sd卡的存储状态
*/
public boolean getStorageState()
{
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) //推断sdCard的存储状态
{
return true;
}else
{
new AlertDialog.Builder(this) //创建AlertDialog对象
.setTitle("提示信息") //设置信息标题
.setMessage("未安装SD卡,请检查你的设备") //设置信息内容
.setPositiveButton("确定", new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// 结束应用程序
VideoRecord.this.finish();
}
})
.show(); //设置弹出提示框
return false;
}
}
/**
* 停止摄像
*/
public void stopRecording()
{
if(mediaRecorder!=null) //判定MediaRecorder对象是否为空
{
mediaRecorder.stop(); //停止摄像
mediaRecorder.release(); //释放资源
mediaRecorder=null; //置空MediaRecorder对象 startButton.setEnabled(true); //摄像button生效
stopButton.setEnabled(false); //停止button生效 startButton.setText("录制");
isSave(); //调用是否保存方法
}
stopCamera(); //调用停止Camera方法
prepareCamera(); //调用初始化Camera对象
startCamera(); //调用開始Camera方法
}
/**
* 開始Camera
*/
public void startCamera() //推断预览开启
{
if(previewRunning)
{
camera.stopPreview(); //停止预览
}
try
{
//设置用SurfaceView作为承载镜头取景画面显示
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview(); //開始预览
previewRunning=true; //设置预览状态为true
}catch(IOException e)
{
e.printStackTrace();
}
}
/**
* 初始化Camera方法
*/
public void prepareCamera()
{
camera=Camera.open(); //初始化Camera
try
{
camera.setPreviewDisplay(surfaceHolder); //设置预览
}catch(IOException e)
{
camera.release(); //释放相机资源
camera=null; //置空Camera对象
}
}
/**
* 是否保存视频录制的文件
*/
public void isSave()
{
AlertDialog alertDialog=new AlertDialog.Builder(this).create(); //创建AlertDialog对象
alertDialog.setTitle("提示信息");
alertDialog.setMessage("是否保存"+videoFile.getName()+"视频文件?"); //设置信息内容
//设置确认button,并加入button监听事件
alertDialog.setButton("确认", new android.content.DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub }
});
alertDialog.setButton("取消", new android.content.DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface arg0, int arg1) {
//推断文件是否存在,存在删除文件
if(videoFile.exists())
{
videoFile.delete();
} }
});
alertDialog.show(); //设置弹出提示框
}
/**
* 停止Camera
*/
public void stopCamera()
{
if(camera!=null) //推断Camera对象不为空
{
camera.stopPreview(); //停止预览
camera.release(); //释放Camera资源
camera=null;
previewRunning=false; //设置预览状态为false
}
}
/**
* 初次实例化,预览界面创建时,该方法被调用
*/
@Override
public void surfaceCreated(SurfaceHolder arg0)
{
prepareCamera(); //调用初始化Camera
}
/**
* 当预览界面的格式和大小发生变化时,该方法调用
*/
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
{
startCamera(); //调用開始Camera
}
/**
* 当预览界面关闭时,该方法被调用
*/
@Override
public void surfaceDestroyed(SurfaceHolder arg0)
{
stopCamera();
} }

(6)程序执行的结果如图所看到的:

A.进入视频录制界面:





B.点击摄像button进入视频预览功能:





C.点击录制button后视频文件被保存在MyVideo目录以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">



D.MyVideo目录下录制好的文件:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">



(7)代码程序具体具体解释:

                       //获取存储(sdCard)的根文件夹
String sdCard=Environment.getExternalStorageDirectory().getPath();
//设置相片存放的文件夹
String dirFilePath=sdCard+File.separator+"MyVideo";
//获取录制文件夹路径的File对象
File dirFile=new File(dirFilePath);
if(!dirFile.exists()) //推断文件夹是否存在
{
dirFile.mkdir(); //创建文件
}
//创建录制视频暂时文件
videoFile=File.createTempFile("video", ".3gp",dirFile);

获取手机sdCard根文件夹。指定根文件夹下自己定义文件夹用于存放录制视频文件,以3gp格式存储。video为前缀。

<span style="white-space:pre">		</span>//推断手机按键按下是否是返回键
if(keyCode==KeyEvent.KEYCODE_BACK)
{
stopRecording(); //调用停止摄像方法
Intent intent=new Intent(); //初始化Intent
intent.setClass(VideoRecord.this, MainActivity.class); //指定Intent对象启动的类
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //清楚该进程空间中的全部Activity
this.startActivity(intent); //启动新的Activity
VideoRecord.this.finish(); //销毁这个Activity
}

这是Activity类的onKeyDown事件用于监听,点击手机返回键时,回到MainActivity窗口并销毁VideoRecord这个Activity.指定Intent.FLAG_ACTIVITY_CLEAR_TOP,比如如今的栈情况为:A
B C D 。D此时通过intent跳转到B,假设这个intent加入FLAG_ACTIVITY_CLEAR_TOP标记,则栈情况变为:A B。


至此全部的摄像功能的介绍都已经结束了,录制视频须要考虑调用摄像头功能和音频录制功能。





使用Android编写录制视频小程序演示样例的更多相关文章

  1. MapGuide应用程序演示样例——你好,MapGuide!

    图 3‑4显示了基于MapGuide的Web应用程序的开发流程,整个开发流程能够分为五个阶段.图中,矩形代表任务,椭圆形被任务使用的或被任务创建的实体,箭头代表数据流. 1) 载入文件类型的数据,配置 ...

  2. 【UNIX网络编程(三)】TCP客户/server程序演示样例

    上一节给出了TCP网络编程的函数.这一节使用那些基本函数编写一个完毕的TCP客户/server程序演示样例. 该样例运行的过程例如以下: 1.客户从标准输入读入一行文本,并写给server. 2.se ...

  3. Android通过startService播放背景音乐简单演示样例

    关于startService的基本使用概述及其生命周期可參见博客<Android中startService的使用及Service生命周期>. 本文通过播放背景音乐的简单演示样例,演示sta ...

  4. android动画-动画分类及代码演示样例

    原来一直对动画一知半解,仅仅知道依照网上的方法会用即可了,可是自己写起来感觉确实有点费劲,今天最终研究了代码实现,一下子感觉清晰多了.先把总结例如以下,代码中有具体的凝视. 动画分类 1.Peoper ...

  5. 使用JavaScript定义一个微信小程序插件样例

    var wxTimer = new wxTimer({ beginTime: "00:00:20", complete: function () { wx.redirectTo({ ...

  6. Android之——流量管理程序演示样例

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47680811 眼下.市面上有非常多管理手机流量的软件,能够让用户实时获取到自己手机 ...

  7. 手牵手,使用uni-app从零开发一款视频小程序 (系列上 准备工作篇)

    系列文章 手牵手,使用uni-app从零开发一款视频小程序 (系列上 准备工作篇) 手牵手,使用uni-app从零开发一款视频小程序 (系列下 开发实战篇) 前言 好久不见,很久没更新博客了,前段时间 ...

  8. 手牵手,使用uni-app从零开发一款视频小程序 (系列下 开发实战篇)

    系列文章 手牵手,使用uni-app从零开发一款视频小程序 (系列上 准备工作篇) 手牵手,使用uni-app从零开发一款视频小程序 (系列下 开发实战篇) 扫码体验,先睹为快 可以扫描下微信小程序的 ...

  9. uni-app微信小程序开发之引入腾讯视频小程序播放插件

    登录微信小程序管理后台添加腾讯视频播放插件: 正式开始使用腾讯视频小程序插件之前需先在微信公众平台 -> 第三方设置 -> 插件管理处添加插件,如下图所示: 在uni-app中引入插件代码 ...

随机推荐

  1. 封装scroll.js 获取滚动条的值

    function Obj(){} Obj.prototype={ scroll:function(){ /* 主要是做兼容处理 这里必须时!=null 因为默认值和每次滚动的时侯 都可以值为0 但是 ...

  2. 重温PHP面向对象的三大特性

    PHP面向对象的三大特性:封装性.继承性.多态性. 1. 封装性: 也称为信息隐藏,就是将一个类的使用和实现分开,只保留部分接口和方法与外部联系,或者说只公开了一些供开发人员使用的方法. 于是开发人员 ...

  3. js:深入prototype(上:内存分析)

    /**  * 下面演示了通过原型的创建方式,使用基于原型的创建能够将属性和方法  * 设置为Person专有的,不能通过window来调用.  * 原型是javascript中的一个特殊对象,当一个函 ...

  4. 服务器返回的“未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0提供程序””错误解决

    未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0提供程序”

  5. [翻译] 极具动感的 FRDLivelyButton

    FRDLivelyButton https://github.com/sebastienwindal/FRDLivelyButton FRDLivelyButton is a simple UIBut ...

  6. 使用IP访问Mantis显示空白页的解决办法

    使用http://localhost/mantis/ 可成功访问Mantis,但使用IP地址:http://172.16.20.111/Mantis却访不了,显示“无法显示网页”. 在aphache中 ...

  7. Ladda 应用提交表单的时候显示loading载入中 包含不同位置,不同效果

    Ladda 应用提交表单的时候显示loading载入中 包含不同位置,不同效果 不同大小.位置,效果,进度条等 演示 XML/HTML Code <article class="exa ...

  8. inline

    inline 大学在教科书上学习过inline函数,定义为inline函数之后,会省去函数调用的开销,直接嵌套汇编代码,取代函数调用,提高效率.工作后项目中也很少用到inline来定义函数,近几天在研 ...

  9. C# 指南

    C# 指南提供了许多有关 C# 语言的资源. 此网站面向许多不同的受众群体. 你可能希望探索本指南的不同部分,具体视你的编程经验或 C# 语言和 .NET 使用经验而定. 对于从未接触过编程的开发者: ...

  10. vijos p1729 Knights

    描述 在一个N*N的正方形棋盘上,放置了一些骑士.我们将棋盘的行用1开始的N个自然数标记,将列用'A'开始的N个大写英文字母标记.举个例子来说,一个标准的8*8的国际象棋棋盘的行标记为1..8,列标记 ...