Android相机和录音的使用总结

一.使用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();
    }
}

程序运行后的结果:
camera

这里使用的是模拟器来拍照,照片会存放到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;
    }

}

}

程序运行后,点击录音的显示画面:
mediarecorder
这里的程序要添加两个权限:SD卡的权限和录音的权限。

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

还有一个要注意的就是,在Android模拟器上不一定能测试录音功能,要测试一般要用真机来测试。
MediaRecorder也可以用来录制视频,但是要复杂一些,这个可以自己去摸索。

上面就是多媒体中相机和录音器的简单使用的相关介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

峥嵘life

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值