一.使用Camera拍照
现在的手机和平板电脑一般都会提供相机功能,而且相机功能应用越来越广泛,在android中提供 了专门用于处理相机相关事件的来,它就是android.hardware包中的Camera类。
Camera类没有构造方法,可以通过其提供的open()方法打开相机,APP要有打开的权限 打开相机后,可以通过Camera.Parameters类处理相机的拍照参数.
拍照参数设置完成后,可以调用startPreview()方法预览拍照画面,可以使用SurfceView来预览画面也可以调用takePicture()方法进行拍照,结束程序时,可以调用Camera类stopPreview()方 法结束预览,并调用Camera类的release() 方法释放相机资源。
Camera类常用的方法及子类
1. getParameters()
用于获取相机参数
2. Camera.open()
用于打开相机
3. release()
用于释放相机资源
4. setParameters(Camera.Parameters params)
用于设置相机的拍照参数
5. setPreviewDisplay(SurfaceHolder holder)
用于为相机指定一个用来显示相机预览画 面的SurfaceView
6. startPreview()
用于开始预览画面
7. stopPreview()
用于停止预览画面
8.takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw , Camera.PictureCallback jpeg)
shutter: /* 按快门瞬间会执行这里的代码 / raw: / 如需要处理raw则在这里写代码 / jpeg: / 当拍照后存储jpg文件到sd卡 */
这里要注意:拍照方法,执行后会停止预览效果
如果要一直可以拍照,在拍完照后马上调用startPreview()方法就可以了。
保存图片需要添加SD卡权限
注意:很多手机不允许设置相机属性,直接打开预览即可
使用系统相机
1. 创建打开系统相机的意图
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
2.使用一个File的对象,把数据存到我们想要的地方 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(currentFile));
3. 实现页面的跳转
startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
这里展示一下照相机的使用
(一)xml文件的设计
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lwz.camera.MainActivity">
<SurfaceView
android:id="@+id/main_sv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:onClick="takePhoto"
android:text="拍照" />
</RelativeLayout>
这里只设计了一个拍照按钮。
(2)java代码设计
package com.lwz.camera;
import android.Manifest;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import java.io.FileOutputStream;
import java.io.IOException;
import static android.support.v4.content.PermissionChecker.PERMISSION_GRANTED;
/**
* 这里使用Camera对象进行照相
* 结合SurfaceView显示摄像头的图像
* 这里设置一下动态的权限的设置,在Android6.0以上才用,这里只是做了判断,
* 无论是低版本或高版本都可以使用
*/
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
//定义一个Camera对象
Camera camera;
//定义布局内的控件
SurfaceView surfaceView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
//初始化数据
private void initView() {
//实例化布局
surfaceView = (SurfaceView) findViewById(R.id.main_sv);
//这里必选给SurfaceView对象的控制器添加监听事件
surfaceView.getHolder().addCallback(this);
}
//SurfaceView创建时回调的方法,这里有一个holder对象可以直接使用
@Override
public void surfaceCreated(SurfaceHolder holder) {
//6.0动态权限
if (Build.VERSION.SDK_INT >= 23) {
//Manifest.permission.CAMERA
//如果用户并没有同意该权限
if (checkSelfPermission(Manifest.permission.CAMERA) != PERMISSION_GRANTED) {
//申请权限
requestPermissions(new String[]{Manifest.permission.CAMERA}, 100);
} else {
open(holder);
}
} else {
open(holder);
}
}
//请求权限后的回调方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//如果用户同意了我的权限
if (requestCode == 100 && grantResults[0] == PERMISSION_GRANTED) {
open(surfaceView.getHolder());
}
}
private void open(SurfaceHolder holder) {
//实例化摄像头
camera = Camera.open();
//设置旋转90度,默认情况是-90度
camera.setDisplayOrientation(90);
try {
//设置相机的预览窗口的位置
camera.setPreviewDisplay(holder);
//设置Camera的布局大小
// Camera.Parameters parameters = camera.getParameters();
// parameters.setPictureSize(720, 1080);
// camera.setParameters(parameters);
} catch (IOException e) {
e.printStackTrace();
}
//预编译
camera.startPreview();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
//点击拍照按钮的监听事件
public void takePhoto(View v) {
camera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
//拍到的数据保存到文件中
//这里的date是数据
String file = Environment.getExternalStorageDirectory().getAbsolutePath();
try {
long time = System.currentTimeMillis() % 1000;
FileOutputStream fos = new FileOutputStream(file + "/" + time + "+m.jpg");
fos.write(data);
fos.flush();
fos.close();
//让照相机对象再次预编译
camera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
@Override
protected void onDestroy() {
if (camera != null) {
camera.release();
}
super.onDestroy();
}
}
程序运行后的结果:
这里使用的是模拟器来拍照,照片会存放到SD卡根目录下的位置。并且可以进行不断的拍照和保存。
二.使用MediaRecord录音
基本步骤:
1.mediaRecorder = new MediaRecorder();
//创建一个音频对象
2.mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 指定录音硬件 3.mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_WB );
//指定输出格式 4.mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB );
//指定编码格式 5.mediaRecorder.setOutputFile(soundFile.getAbsolutePath());
//把音 频输出到手机的某个文件中
6..prepare();
// 准备录制
7..start();
// 开始录制
8..stop();
// 停止刻录,并保存文件
上面这几个步骤一定是要按顺序来执行的,否则会报错。
需要添
<uses-permission android:name="android.permission.RECORD_AUDIO" />
设计一个录音机的简单程序:
录音机是没有界面显示的,所以要在页面上设计一个计时器!
(一)xml布局文件代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.lwz.mediaRecord.MainActivity">
<TextView
android:id="@+id/main_tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00:00" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="toRecord"
android:text="录音" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="save"
android:text="保存" />
</LinearLayout>
(二)java代码
package com.lwz.mediaRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
//定义一个MediaRecorder对象
MediaRecorder mediaRecorder;
//显示时间的文本
TextView tv_time;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_time = (TextView) findViewById(R.id.main_tv_time);
}
public void toRecord(View view) {
try {
// 1.创建一个音频对象
mediaRecorder = new MediaRecorder();
//2. 指定录音硬件, 设置MediaRecorder的音频源为麦克风
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 3.指定输出格式
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// 4.指定编码格式
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);
//5.把音 频输出到手机的某个文件中,视频的格式.amr
long time = System.currentTimeMillis() % 1000;
String soundFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/m" + time + ".amr";
mediaRecorder.setOutputFile(soundFile);
// 6.准备录制
mediaRecorder.prepare();
// 7.开始录制
mediaRecorder.start();
startTime();//开始计时
} catch (Exception e) {
e.printStackTrace();
}
}
public void save(View v) {
toSave();
tv_time.setText("00 : 00 : 00");
//时间置零
HH = ss = MM = 0;
}
private void toSave() {
if (timer != null) {
timer.cancel();//关闭计数器
}
if (mediaRecorder != null) {
mediaRecorder.stop();// 停止刻录
// recorder.reset(); // 重新启动MediaRecorder.
mediaRecorder.release(); // 刻录完成一定要释放资源
mediaRecorder = null;
}
}
Timer timer;
//时分秒的时间显示
int HH = 0;
int MM = 0;
int ss = 0;
private void startTime() {
timer = new Timer();
//一秒之后每秒执行一次的任务
timer.schedule(new TimerTask() {
@Override
public void run() {
ss++;//秒数每次加一
if (ss >= 60) {
ss = 0;
MM++;
}
if (MM >= 60) {
MM = 0;
HH++;
}
//改变文本内容要在主线程执行
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_time.setText(NumberUtils.getDigits(HH, 2) + " : " + NumberUtils.getDigits(MM, 2) + ": " + NumberUtils.getDigits(ss, 2));
}
});
}
}, 1000, 1000);
}
@Override
protected void onDestroy() {
toSave();
super.onDestroy();
}
/**
* 关于数据显示的一些工具
* 比如:让1显示01,这个在计时器中有用
*/
class NumberUtils {
private static String[] numDigits = {"0", "00", "000", "0000", "000000",};
//输入一个数获得,对应的位数的字符串
public static String getDigits(int number, int digits) {
String newNum = "";
switch (digits) {
case 1:
newNum = "" + number;
break;
case 2:
if (number < 10) {
newNum = numDigits[0] + number;
} else {
newNum = "" + number;
}
break;
//其他的位数应用不大就不写了
}
return newNum;
}
}
}
程序运行后,点击录音的显示画面:
这里的程序要添加两个权限:SD卡的权限和录音的权限。
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
还有一个要注意的就是,在Android模拟器上不一定能测试录音功能,要测试一般要用真机来测试。
MediaRecorder也可以用来录制视频,但是要复杂一些,这个可以自己去摸索。
上面就是多媒体中相机和录音器的简单使用的相关介绍。