主要实现录制功能的类: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. mysql反向解析导致连接缓慢

    Content 0.序 1.问题 2.原因 3.解决办法 0.序 本文主要是记录Mysql安装在 VMWARE下,本地连接Mysql速度很慢的原因及解决办法. 1.问题 本地的一个网站使用mysql数 ...

  2. Android 5.0 源代码结构

    本节书摘来自异步社区<深入理解Android 5 源代码>一书中的第2章,第2.2节分析Android源代码结构,作者 李骏. 网址:https://yq.aliyun.com/artic ...

  3. Memcached (第一篇)

    Memcached是“分布式”的内存对象缓存系统,那么不需要“分布”的.不需要共享的或者干脆规模小到只有一台服务器的应用,Memcached不会带来任何好处,相反还会拖慢系统效率,因为网络连接同样需要 ...

  4. python文本 拼接或合并字符串

    python文本 拼接.合并字符串 场景: 拼接.合并字符串 在这个场景中,我们首先想到的当然是使用+或者+=将两个字符串连接起来 >>> a='a'    >>> ...

  5. python接口自动化5-Json数据处理

    前言 有些post的请求参数是json格式的,这个前面第二篇post请求里面提到过,需要导入json模块处理. 一般常见的接口返回数据也是json格式的,我们在做判断时候,往往只需要提取其中几个关键的 ...

  6. longest-substring-with-at-least-k-repeating-characters

    https://leetcode.com/problems/longest-substring-with-at-least-k-repeating-characters/ public class S ...

  7. Java 连接MS Access数据库

    java连接MS Access的两种方式: 1.JDBC-ODBC Java连接Access可以使用MS自带的管理工具-->数据源(ODBC)设置建立连接,这样就不需要导入jar.但是,如此一来 ...

  8. C语言数字与字符串转换 atoi()函数、itoa()函数、sprintf()函数

    在编程中经常需要用到数字与字符串的转换,下面就总结一下. 1.atoi() C/C++标准库函数,用于字符串到整数的转换. 函数原型:int atoi (const char * str); #inc ...

  9. iOS开发-UI基础Demo

    现在更多的学习资料都是xCode4.X的,发现xCode6.1还是很多东西,如果有正在学习iOS开发的可以通过Demo简单了解下iOS的UI开发~ 1.新建单视图文件: 2.新建项目名称,语言选择OC ...

  10. Valid Parentheses leetcode java

    题目: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the ...