Demo 1录音机

下面来分析:

Android之多媒体数据采集
各种引用的创建(比较特殊的ImageButton 和 MediaRecorder)
Android之多媒体数据采集
初始化我就不多说
Android之多媒体数据采集
Handler的使用 上篇博文谈过不多说
Android之多媒体数据采集
关于这种写法的监听可以借鉴(毕竟所有控件只不过是View的子类而已)
然后读取有没有内存卡
Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)
Android之多媒体数据采集
初始化临时文件File.createTempFile( 参数一基本文件名 参数二后缀 参数三目录路径)

Android之多媒体数据采集
不多说下面看settime的代码
Android之多媒体数据采集
发送Bundle 不多谈

Android之多媒体数据采集
结束录音的时候
源代码如下

public class MyAudioRecorderActivity extends Activity implements OnClickListener{
	public static final int UPDATE_TIME=0;//更新录音时间的消息编号

	ImageButton ibRecord;//录制按钮
	ImageButton ibStop;//停止按钮

	TextView tvTime;//时间长度显示
	Handler hd;//消息处理器

	File myFile ;//用于存放音轨的文件
	MediaRecorder myMediaRecorder;//媒体录音机
	int countSecond=0;//录制的秒数
	boolean recordFlag=false;//录制中标志

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		//初始化按钮引用
		ibRecord=(ImageButton)findViewById(R.id.ImageButton01);
		ibStop=(ImageButton)findViewById(R.id.ImageButton02);
		//初始化显示录音时长的文本框
		tvTime=(TextView)findViewById(R.id.TextView02);
		//为录制按钮添加监听器
		ibRecord.setOnClickListener(this);
		//为停止按钮添加监听器
		ibStop.setOnClickListener(this);
		//初始化消息处理器对象
		//本案例中希望通过附加线程修改TextView中的内容,因此要在主
		//线程中创建一个Handler
		hd=new Handler()
		{
			@Override
			public void handleMessage(Message msg)
			{
				//调用父类处理
				super.handleMessage(msg);
				//根据消息what编号的不同,执行不同的业务逻辑
				switch(msg.what)
				{
					//将消息中的内容提取出来显示在Toast中
					case UPDATE_TIME:
						//获取消息中的数据
						Bundle b=msg.getData();
						//获取内容字符串
						String msgStr=b.getString("msg");
						//设置字符串到显示录音时长的文本框中
						tvTime.setText(msgStr);
						break;
				}
			}
		};
	}

	@Override
	public void onClick(View v) {
		if(v == ibRecord){//按下录音按钮
			if(!Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
			{//若没有插闪存卡则报错
				Toast.makeText(this, "请检测内存卡", Toast.LENGTH_SHORT).show();
				return;
			}
			try
			{
				if(recordFlag==true)
				{//若已经在录音中则提示并返回
					Toast.makeText(this, "录音中,请结束本次录音再开始新录音!", Toast.LENGTH_SHORT).show();
					return;
				}

				//初始化临时文件对象
				myFile = File.createTempFile
						(
								"myAudio",  //基本文件名
								".amr",     //后缀
								Environment.getExternalStorageDirectory() //目录路径
						);
				//创建录音机对象
				myMediaRecorder = new MediaRecorder();
				//设置输入设备为麦克风
				myMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
				//设置输出格式为默认的amr格式
				myMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
				//设置音频编码器为默认的编码器
				myMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
				//设置输出文件的路径
				myMediaRecorder.setOutputFile(myFile.getAbsolutePath());
				//准备录音
				myMediaRecorder.prepare();
				//开始录音
				myMediaRecorder.start();
				//设置录音中标记为true
				recordFlag=true;
				//启动一个线程进行计时
				new Thread()
				{
					public void run()
					{
						while(recordFlag)
						{
							//计时器加一
							countSecond++;
							//调用方法设置新时长
							setTime();
							//休息1000ms
							try {
								Thread.sleep(1000);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
						}
					}
				}.start();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		else if(v == ibStop){//按下停止按钮
			if(myFile != null&&myMediaRecorder!=null)
			{
				//停止录音
				myMediaRecorder.stop();
				//释放录音机对象
				myMediaRecorder.release();
				//将录音机对象引用设置为null
				myMediaRecorder = null;
			}
			//设置录音中标记为false
			recordFlag=false;
			//计时器清0
			countSecond=0;
			//调用方法设置新时长
			setTime();
		}
	}

	//设置显示时间的方法
	public void setTime()
	{
		//计算分钟和秒
		int second=countSecond%60;
		int minute=countSecond/60;
		//创建内容字符串
		String msgStr=minute+"m:"+second+"s";
		//创建消息数据Bundle
		Bundle b=new Bundle();
		//将内容字符串放进数据Bundle中
		b.putString("msg", msgStr);
		//创建消息对象
		Message msg=new Message();
		//设置数据Bundle到消息中
		msg.setData(b);
		//设置消息的what值
		msg.what=UPDATE_TIME;
		//发送消息
		hd.sendMessage(msg);
	}

最后注意要
Android之多媒体数据采集
声明权限!!!!

=================================================================================

Demo2 照相机

重点分析:
Uri 的临时存储
Android之多媒体数据采集
由于使用了startActivityForResult来发送intent的所有必须要实现该方法
Android之多媒体数据采集
自定义的图片保存进手机闪存的方法
Android之多媒体数据采集
flush 方法
Android之多媒体数据采集

照片路径处理的工具类代码

public class StoreFileUtil
{
    //当前存储照片对应的文件
    static File currFile;

    //获取下一个可以存储的文件
    public static File nextFile()
    {
        //获取闪存卡路径
        String path= Environment.getExternalStorageDirectory().getAbsolutePath();
        //寻找可以使用的文件名
        int c=0;
        File fTest=new File(path+"/mc"+c+".jpg");
        while(fTest.exists())
        {
            c++;
            fTest=new File(path+"/mc"+c+".jpg");
        }
        currFile=fTest;
        return fTest;
    }

    //临时文件
    public static File tempFile()
    {
        //获取闪存卡路径
        String path= Environment.getExternalStorageDirectory().getAbsolutePath();
        File fTest=new File(path+"/BNtemp.jpg");
        return fTest;
    }

Activity代码

@SuppressLint("HandlerLeak")
public class MyCameraActivity extends Activity
{
	private static int REQUEST_ORIGINAL=0;// 请求图片信号标识

	private Button  photo;//拍照按钮
	private Button save;//保存按钮
	private ImageView picture;//用于显示图片的ImageView
	public static Bitmap bitmap;//当前拍的照片

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//获取显示图片的ImageView
		picture = (ImageView) findViewById(R.id.picture_imageView);
		//获取拍照按钮
		photo = (Button) findViewById(R.id.main_Button_paizhao);
		//给拍照按钮添加监听器
		photo.setOnClickListener(new View.OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				//调用系统相机的Intent
				Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
				//临时照片文件的位置
				Uri uri = Uri.fromFile(StoreFileUtil.tempFile());
				//将照片文件的位置传入intent
				intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
				//发出intent启动系统相机
				startActivityForResult(intent, REQUEST_ORIGINAL);
			}
		});
		//保存按钮
		save = (Button) findViewById(R.id.main_Button_baocun);
		//为保存按钮添加监听器
		save.setOnClickListener(new View.OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				if(bitmap==null)
				{
					Toast.makeText(MyCameraActivity.this, "请先拍照再保存!", Toast.LENGTH_SHORT)	.show();
				}
				//保存照片
				setInSDBitmap(bitmap);
				Toast.makeText(MyCameraActivity.this, "保存成功:"+StoreFileUtil.currFile.getName()+"!", Toast.LENGTH_SHORT)	.show();
			}
		});
	}

	//系统相机返回时的回调方法
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_OK)
		{
			if(requestCode == REQUEST_ORIGINAL)
			{
				//从临时照片文件的位置加载照片
				bitmap=BitmapFactory.decodeFile(StoreFileUtil.tempFile().getAbsolutePath());
				//将图片设置给ImageView显示
				picture.setImageBitmap(bitmap);
			}
		}
	}
	//将图片保存进手机闪存的方法
	public static void setInSDBitmap(Bitmap bitmapToStore)
	{
		File file=StoreFileUtil.nextFile();
		try
		{
			FileOutputStream fos=new FileOutputStream(file);
			bitmapToStore.compress(Bitmap.CompressFormat.JPEG, 70, fos);
			fos.flush();
			fos.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	//重写返回按钮按下的处理方法
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		if(keyCode == KeyEvent.KEYCODE_BACK)
		{
			finish();
		}
		return false;
	}

相关文章: