Android 自定义拍照音效 问题

来源:互联网 发布:淘宝领阿里小号 编辑:程序博客网 时间:2024/05/29 17:06

package com.platomix.babyshow.activity;import com.example.demo_imagecreate.R;import com.platomix.babyshow.util.BitmapUtil;import com.platomix.babyshow.util.Loger;import com.platomix.babyshow.util.SoundPlayer;import com.platomix.babyshow.widget.ToggleButton;import com.platomix.babyshow.widget.ToggleButton.OnSwitchStatusListener;import android.os.Bundle;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.hardware.Camera;import android.hardware.Camera.AutoFocusCallback;import android.hardware.Camera.Parameters;import android.hardware.Camera.PictureCallback;import android.util.Log;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.SurfaceHolder.Callback;import android.view.View.OnClickListener;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.Toast;public class TakePhotoActivity extends Activity implements OnClickListener{private static final String TAG = "TakePhotoActivity";private Context context;private static int[] photoFrames = {R.drawable.photo_frame1,R.drawable.photo_frame2};private SurfaceView previewPhoto;        //照片private Camera camera;private ImageView photoFrame;   //相框private  ToggleButton takephoto_switch;private ImageButton btn_camera_photo;  private ImageView btn_frame;  private ImageView btn_thumbnail;private ImageView arrow_right;   //下一个private ImageView arrow_left;    //上一个private ImageView btn_back;private boolean haveFrame ;          //是否有相框  true:有private int currentPhotoFrameIndex;  //当前相框的资源id的数组下标private int photoFramesCount;private boolean isTakePhoto ;//是否是拍照:true:拍照   false:录像//1.声明一个手势识别器private GestureDetector mGestureDetector;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.takephoto_activity);context = this.getApplicationContext();SoundPlayer.init(context);haveFrame = false;isTakePhoto = true;currentPhotoFrameIndex = 0;photoFramesCount = photoFrames.length;takephoto_switch = (ToggleButton) findViewById(R.id.takephoto_switch);takephoto_switch.setSwitchStyle(R.drawable.bkg_take_photo_switch, R.drawable.icon_photo, R.drawable.icon_camera);takephoto_switch.setTop(true);//添加开关状态改变监听器takephoto_switch.setOnSwitchStatusListener(new OnSwitchStatusListener() {@Overridepublic void onSwitch(boolean isTop) {if(isTop){//拍照isTakePhoto = true;btn_camera_photo.setBackgroundResource(R.drawable.btn_photo);} else {//录像isTakePhoto = false;btn_camera_photo.setBackgroundResource(R.drawable.btn_camera);}}});previewPhoto = (SurfaceView) findViewById(R.id.previewPhoto);previewPhoto.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);previewPhoto.getHolder().addCallback(new MyCallback());//camera = Camera.open();photoFrame = (ImageView) findViewById(R.id.photoFrame);btn_camera_photo = (ImageButton) findViewById(R.id.btn_camera_photo);btn_camera_photo.setClickable(true);btn_camera_photo.setOnClickListener(this);btn_frame = (ImageView) findViewById(R.id.btn_frame);btn_frame.setOnClickListener(this);btn_thumbnail = (ImageView) findViewById(R.id.btn_thumbnail);btn_thumbnail.setOnClickListener(this);arrow_right = (ImageView) findViewById(R.id.arrow_right);arrow_right.setOnClickListener(this);arrow_left = (ImageView) findViewById(R.id.arrow_left);arrow_left.setOnClickListener(this);btn_back = (ImageView) findViewById(R.id.btn_back);btn_back.setOnClickListener(this);//Bitmap  bitmap1 = BitmapFactory.decodeResource(this.getResources(), R.drawable.arrow_right);//Bitmap  bitmap2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.photo_frame1);//bitmapTemp = BitmapUtil.createBitmap(bitmap1,bitmap2);//////photo.setImageBitmap(bitmapTemp);////ornament = new MoveWithFingerView(this, R.drawable.ic_launcher);////main_RL.addView(ornament);setPhotoFrame(haveFrame);//2.初始化手势识别器//Basic Default Base SimplemGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener(){/**划屏对应的方法. * e1 手指第一次触摸屏幕 * e2 手指离开屏幕瞬间 * velocityX 水平方向移动的速度 px/s * velocityY 竖直方向移动的速度 */@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2,float velocityX, float velocityY) {if(haveFrame){//使用相框if(Math.abs(velocityX)<100){Loger.d(TAG,"移动的太慢,动作不合法");return true;}if((e2.getRawX()-e1.getRawX()) >200){Loger.d(TAG,"上一张,同:arrow_left");photoFrame.setBackgroundResource(photoFrames[1]);if(currentPhotoFrameIndex == 0){currentPhotoFrameIndex = photoFramesCount;}photoFrame.setBackgroundResource(photoFrames[(--currentPhotoFrameIndex)%photoFramesCount]);return true;}if((e1.getRawX()-e2.getRawX()) >200){Loger.d(TAG,"下一张,同:arrow_right");photoFrame.setBackgroundResource(photoFrames[(++currentPhotoFrameIndex)%photoFramesCount]);return true;}}return super.onFling(e1, e2, velocityX, velocityY);}});}/********相机**********/private class MyCallback implements Callback {//打开摄像头,开始预览public void surfaceCreated(SurfaceHolder holder) {Loger.d(TAG, "surfaceCreated");try {camera = Camera.open();  //打开摄像头Loger.d(TAG, "camera="+camera);Parameters params = camera.getParameters();// 获取默认参数System.out.println(params.flatten());// 打印params.setPictureSize(800, 480);// 拍照尺寸params.setPreviewSize(800, 480);        // 预览尺寸params.setFlashMode("on");              // 闪光灯打开params.setJpegQuality(50);              // 照片质量,100是最高质量camera.setParameters(params);// 把修改后的参数设置到摄像头camera.setPreviewDisplay(previewPhoto.getHolder());// 设置预览显示位置,在 previewSVcamera.startPreview();// 开始预览} catch (Exception e) {e.printStackTrace();}}//停止预览,释放摄像头public void surfaceDestroyed(SurfaceHolder holder) {Loger.d(TAG, "surfaceDestroyed"); //activity 返回时候,surfaceView自动销毁if (camera != null) {camera.stopPreview();// 停止预览camera.release();// 释放资源camera = null;// 垃圾回收}}public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}}private class MyAutoFocusCallback implements AutoFocusCallback {public void onAutoFocus(boolean success, Camera camera) {/* * 4个回调对象 * 1: 当按下快门时执行其中方法, 通常用来播放一个提示音 * 2: 当获取到原始数据时会执行其中方法 * 3: 当生成预览图片时调用(有的设备不支持) * 4: 当压缩成JPG格式之后调用, 通常在这个方法中获取数据 */camera.takePicture(null, null, null, new MyPictureCallback());// 对焦结束后拍照}}private class MyPictureCallback implements PictureCallback {public void onPictureTaken(byte[] data, Camera camera) {// 获取到数据后, 写到文件String path = "/mnt/sdcard/DCIM";String thumbnailFileName = "thumbnail_"+System.currentTimeMillis() + ".png";String photoFileName = System.currentTimeMillis() + ".png";if(haveFrame){ //有相框Bitmap  bitmapPhoto = BitmapFactory.decodeByteArray(data, 0, data.length);Bitmap  bitmapPhotoFrame = BitmapFactory.decodeResource(getResources(), photoFrames[currentPhotoFrameIndex]);Bitmap  bitmapResult = BitmapUtil.createBitmap(context, bitmapPhoto, photoFrames[currentPhotoFrameIndex]);//缩略图BitmapUtil.savePhotoThumbnailToFile(path,thumbnailFileName,0.5, bitmapResult);//照片BitmapUtil.saveBitmapToFile(path,photoFileName, bitmapResult);camera.startPreview();}else{Bitmap  bitmapPhoto = BitmapFactory.decodeByteArray(data, 0, data.length);BitmapUtil.savePhotoThumbnailToFile(path,thumbnailFileName,0.5, bitmapPhoto);BitmapUtil.saveBitmapToFile(path, photoFileName, bitmapPhoto);camera.startPreview();}//照片截图Bitmap photoScreenshot = BitmapFactory.decodeFile(path +"/"+ thumbnailFileName);if(photoScreenshot != null){Loger.d(TAG, path +"/"+ thumbnailFileName);btn_thumbnail.setImageBitmap(photoScreenshot);}}}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_camera_photo:if(isTakePhoto){//拍照Loger.d(TAG, "对焦,拍照");//SoundPlayer.init(this);SoundPlayer.playSound(1);camera.autoFocus(new MyAutoFocusCallback()); // 自动对焦,拍照}else{//录像Loger.d(TAG, "切换到录像");Intent intent = new Intent();intent.setClass(this, VideoRecodActivity.class);startActivity(intent);}break;case R.id.btn_frame:Loger.d(TAG,"btn_frame");haveFrame = !haveFrame;setPhotoFrame(haveFrame);break;case R.id.btn_thumbnail: Loger.d(TAG, "btn_thumbnail");break;case R.id.arrow_right: Loger.d(TAG, "arrow_right");photoFrame.setBackgroundResource(photoFrames[(++currentPhotoFrameIndex)%photoFramesCount]);break;case R.id.arrow_left:Loger.d(TAG, "arrow_left");photoFrame.setBackgroundResource(photoFrames[1]);if(currentPhotoFrameIndex == 0){currentPhotoFrameIndex = photoFramesCount;}photoFrame.setBackgroundResource(photoFrames[(--currentPhotoFrameIndex)%photoFramesCount]);break;case R.id.btn_back:System.out.println("btn_back");break;default:break;}}//@Override//public boolean onKeyDown(int keyCode, KeyEvent event) {//if (keyCode == KeyEvent.KEYCODE_BACK) {//bitmapLast = createBitmap(bitmapTemp,bitmapOrnament);//photo.setImageBitmap(bitmapLast);//String path = "";//"/mnt/sdcard/Android";//String fileName = "p10.png";////System.out.println("result="+BitmapUtil.saveBitmapToFile(path,fileName,bitmapLast));//System.out.println("result="+BitmapUtil.savePhotoThumbnailToFile(path, fileName, null));//return true;//}// return super.onKeyDown(keyCode, event);//}/** * 设置相框是否显示 * @param haveFrame  true:显示   应该吧btn_frame图片切换 */private void setPhotoFrame(boolean haveFrame){if(haveFrame){ //有相框arrow_left.setVisibility(View.VISIBLE);arrow_right.setVisibility(View.VISIBLE);photoFrame.setBackgroundResource(photoFrames[0]);}else{arrow_left.setVisibility(View.GONE);arrow_right.setVisibility(View.GONE);photoFrame.setBackgroundResource(0);}}//3.activity被触摸的时候调用的方法 , 需要在这个里面让手势识别器 生效@Overridepublic boolean onTouchEvent(MotionEvent event) {//让手势识别器 生效mGestureDetector.onTouchEvent(event);return super.onTouchEvent(event);}}

下面这个值转载的:是播放声音的工具类,声音的资源文件放到 res/raw 目录下,MP3,wav 都行

package com.platomix.babyshow.util;import java.util.HashMap;import java.util.Map;import java.util.Random;import com.example.demo_imagecreate.R;import android.content.Context;import android.media.AudioManager;import android.media.MediaPlayer;import android.media.SoundPool;/** * 声音控制类 * @author wyf */public class SoundPlayer {private static MediaPlayer music;private static SoundPool soundPool;private static boolean musicSt = true; //音乐开关private static boolean soundSt = true; //音效开关private static Context context;private static final int[] musicId = {R.raw.cs1};private static Map<Integer,Integer> soundMap; //音效资源id与加载过后的音源id的映射关系表/** * 初始化方法 * @param c */public static void init(Context c){context = c;initMusic();initSound();}//初始化音效播放器private static void initSound(){soundPool = new SoundPool(10,AudioManager.STREAM_MUSIC,0);soundMap = new HashMap<Integer,Integer>();soundMap.put(1, soundPool.load(context, R.raw.cs1, 1));soundMap.put(2, soundPool.load(context, R.raw.cs2, 1));}//初始化音乐播放器private static void initMusic(){int r = new Random().nextInt(musicId.length);music = MediaPlayer.create(context,musicId[r]);music.setLooping(true);}/** * 播放音效 * @param resId 音效资源id */public static void playSound(int resId){if(soundSt == false){return;}Integer soundId = soundMap.get(resId);if(soundId != null){soundPool.play(soundId, 1, 1, 1, 0, 1);}}/** * 暂停音乐 */public static void pauseMusic(){if(music.isPlaying()){music.pause();}}/** * 播放音乐 */public static void startMusic(){if(musicSt){music.start();}}/** * 切换一首音乐并播放 */public static void changeAndPlayMusic(){if(music != null){music.release();}initMusic();startMusic();}/** * 获得音乐开关状态 * @return */public static boolean isMusicSt() {return musicSt;}/** * 设置音乐开关 * @param musicSt */public static void setMusicSt(boolean musicSt) {SoundPlayer.musicSt = musicSt;if(musicSt)music.start();elsemusic.stop();}/** * 获得音效开关状态 * @return */public static boolean isSoundSt() {return soundSt;}/** * 设置音效开关 * @param soundSt */public static void setSoundSt(boolean soundSt) {SoundPlayer.soundSt = soundSt;}/** * 发出‘邦’的声音 */public static void boom(){playSound(1);}}


有个问题,先 mark 一下:SoundPlayer.init(context); 放在 activity 的onCreate 中,音效可以正常播放;

但是 SoundPlayer.init(context); 放到按钮的监听 onClick 方法中就没声音了。但是拍照可以继续

目前猜测:SoundPlayer.init(context) 是在另一个子线程中加载文件,所有才会这样子


0 0
原创粉丝点击