Android录音时指针摆动的实现(附源码)

转自:http://blog.csdn.net/tangcheng_ok/article/details/7561822                      <请尊重作者的劳动成果>


文中的代码主要是移植SoundRecorder的。主要是其中的VUMeter类,VUMeter是通过Recorder.getMaxAmplitude()的值计算,画出指针的偏移摆动。下面直接上代码

    <span style="font-size:16px;">/* 
     * Copyright (C) 2011 The Android Open Source Project 
     * 
     * Licensed under the Apache License, Version 2.0 (the "License"); 
     * you may not use this file except in compliance with the License. 
     * You may obtain a copy of the License at 
     * 
     *      http://www.apache.org/licenses/LICENSE-2.0 
     * 
     * Unless required by applicable law or agreed to in writing, software 
     * distributed under the License is distributed on an "AS IS" BASIS, 
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
     * See the License for the specific language governing permissions and 
     * limitations under the License. 
     */  
      
    package com.android.soundrecorder;  
      
    import android.content.Context;  
    import android.graphics.Canvas;  
    import android.graphics.Color;  
    import android.graphics.Paint;  
    import android.graphics.drawable.Drawable;  
    import android.util.AttributeSet;  
    import android.view.View;  
      
    public class VUMeter extends View {  
        static final float PIVOT_RADIUS = 3.5f;  
        static final float PIVOT_Y_OFFSET = 10f;  
        static final float SHADOW_OFFSET = 2.0f;  
        static final float DROPOFF_STEP = 0.18f;  
        static final float SURGE_STEP = 0.35f;  
        static final long  ANIMATION_INTERVAL = 70;  
          
        Paint mPaint, mShadow;  
        float mCurrentAngle;  
          
        Recorder mRecorder;  
      
        public VUMeter(Context context) {  
            super(context);  
            init(context);  
        }  
      
        public VUMeter(Context context, AttributeSet attrs) {  
            super(context, attrs);  
            init(context);  
        }  
      
        void init(Context context) {  
            Drawable background = context.getResources().getDrawable(R.drawable.vumeter);  
            setBackgroundDrawable(background);  
              
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            mPaint.setColor(Color.WHITE);  
            mShadow = new Paint(Paint.ANTI_ALIAS_FLAG);  
            mShadow.setColor(Color.argb(60, 0, 0, 0));  
              
            mRecorder = null;  
              
            mCurrentAngle = 0;  
        }  
      
        public void setRecorder(Recorder recorder) {  
            mRecorder = recorder;  
            invalidate();  
        }  
          
        @Override  
        protected void onDraw(Canvas canvas) {  
            super.onDraw(canvas);  
      
            final float minAngle = (float)Math.PI/8;  
            final float maxAngle = (float)Math.PI*7/8;  
                      
            float angle = minAngle;  
            if (mRecorder != null)  
                angle += (float)(maxAngle - minAngle)*mRecorder.getMaxAmplitude()/32768;  
      
            if (angle > mCurrentAngle)  
                mCurrentAngle = angle;  
            else  
                mCurrentAngle = Math.max(angle, mCurrentAngle - DROPOFF_STEP);  
      
            mCurrentAngle = Math.min(maxAngle, mCurrentAngle);  
      
            float w = getWidth();  
            float h = getHeight();  
            float pivotX = w/2;  
            float pivotY = h - PIVOT_RADIUS - PIVOT_Y_OFFSET;  
            float l = h*4/5;  
            float sin = (float) Math.sin(mCurrentAngle);  
            float cos = (float) Math.cos(mCurrentAngle);  
            float x0 = pivotX - l*cos;  
            float y0 = pivotY - l*sin;  
            canvas.drawLine(x0 + SHADOW_OFFSET, y0 + SHADOW_OFFSET, pivotX + SHADOW_OFFSET, pivotY + SHADOW_OFFSET, mShadow);  
            canvas.drawCircle(pivotX + SHADOW_OFFSET, pivotY + SHADOW_OFFSET, PIVOT_RADIUS, mShadow);  
            canvas.drawLine(x0, y0, pivotX, pivotY, mPaint);  
            canvas.drawCircle(pivotX, pivotY, PIVOT_RADIUS, mPaint);  
              
            if (mRecorder != null && mRecorder.state() == Recorder.RECORDING_STATE)  
                postInvalidateDelayed(ANIMATION_INTERVAL);  
        }  
    }  
    </span>  


录音类:RecordHelper.java

[java] view plaincopy

    <span style="font-size:16px;">package org.winplus.sh;  
      
    import java.io.File;  
    import java.io.IOException;  
      
    import android.content.Context;  
    import android.media.AudioManager;  
    import android.media.MediaPlayer;  
    import android.media.MediaRecorder;  
    import android.media.MediaPlayer.OnCompletionListener;  
    import android.media.MediaPlayer.OnErrorListener;  
    import android.os.Bundle;  
    import android.os.Environment;  
      
    public class RecordHelper implements OnCompletionListener, OnErrorListener {  
        static final String SAMPLE_PREFIX = "recording";  
        static final String SAMPLE_PATH_KEY = "sample_path";  
        static final String SAMPLE_LENGTH_KEY = "sample_length";  
      
        public static final int IDLE_STATE = 0;  
        public static final int RECORDING_STATE = 1;  
        public static final int PLAYING_STATE = 2;  
          
        int mState = IDLE_STATE;  
      
        public static final int NO_ERROR = 0;  
        public static final int SDCARD_ACCESS_ERROR = 1;  
        public static final int INTERNAL_ERROR = 2;  
        public static final int IN_CALL_RECORD_ERROR = 3;  
          
        public interface OnStateChangedListener {  
            public void onStateChanged(int state);  
            public void onError(int error);  
        }  
        OnStateChangedListener mOnStateChangedListener = null;  
          
        long mSampleStart = 0;       // time at which latest record or play operation started  
        int mSampleLength = 0;      // length of current sample  
        File mSampleFile = null;  
          
        MediaRecorder mRecorder = null;  
        MediaPlayer mPlayer = null;  
          
        public RecordHelper() {  
        }  
          
        public void saveState(Bundle recorderState) {  
            recorderState.putString(SAMPLE_PATH_KEY, mSampleFile.getAbsolutePath());  
            recorderState.putInt(SAMPLE_LENGTH_KEY, mSampleLength);  
        }  
          
        public int getMaxAmplitude() {  
            if (mState != RECORDING_STATE)  
                return 0;  
            return mRecorder.getMaxAmplitude();  
        }  
          
        public void restoreState(Bundle recorderState) {  
            String samplePath = recorderState.getString(SAMPLE_PATH_KEY);  
            if (samplePath == null)  
                return;  
            int sampleLength = recorderState.getInt(SAMPLE_LENGTH_KEY, -1);  
            if (sampleLength == -1)  
                return;  
      
            File file = new File(samplePath);  
            if (!file.exists())  
                return;  
            if (mSampleFile != null  
                    && mSampleFile.getAbsolutePath().compareTo(file.getAbsolutePath()) == 0)  
                return;  
              
            delete();  
            mSampleFile = file;  
            mSampleLength = sampleLength;  
      
            signalStateChanged(IDLE_STATE);  
        }  
          
        public void setOnStateChangedListener(OnStateChangedListener listener) {  
            mOnStateChangedListener = listener;  
        }  
          
        public int state() {  
            return mState;  
        }  
          
        public int progress() {  
            if (mState == RECORDING_STATE || mState == PLAYING_STATE)  
                return (int) ((System.currentTimeMillis() - mSampleStart)/1000);  
            return 0;  
        }  
          
        public int sampleLength() {  
            return mSampleLength;  
        }  
      
        public File sampleFile() {  
            return mSampleFile;  
        }  
          
        /** 
         * Resets the recorder state. If a sample was recorded, the file is deleted. 
         */  
        public void delete() {  
            stop();  
              
            if (mSampleFile != null)  
                mSampleFile.delete();  
      
            mSampleFile = null;  
            mSampleLength = 0;  
              
            signalStateChanged(IDLE_STATE);  
        }  
          
        /** 
         * Resets the recorder state. If a sample was recorded, the file is left on disk and will  
         * be reused for a new recording. 
         */  
        public void clear() {  
            stop();  
              
            mSampleLength = 0;  
              
            signalStateChanged(IDLE_STATE);  
        }  
          
        public void startRecording(int outputfileformat, String extension, Context context) {  
            stop();  
              
            if (mSampleFile == null) {  
                File sampleDir = Environment.getExternalStorageDirectory();  
                if (!sampleDir.canWrite()) // Workaround for broken sdcard support on the device.  
                    sampleDir = new File("/sdcard/sdcard");  
                  
                try {  
                    mSampleFile = File.createTempFile(SAMPLE_PREFIX, extension, sampleDir);  
                } catch (IOException e) {  
                    setError(SDCARD_ACCESS_ERROR);  
                    return;  
                }  
            }  
              
            mRecorder = new MediaRecorder();  
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  
            mRecorder.setOutputFormat(outputfileformat);  
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  
            mRecorder.setOutputFile(mSampleFile.getAbsolutePath());  
      
            // Handle IOException  
            try {  
                mRecorder.prepare();  
            } catch(IOException exception) {  
                setError(INTERNAL_ERROR);  
                mRecorder.reset();  
                mRecorder.release();  
                mRecorder = null;  
                return;  
            }  
            // Handle RuntimeException if the recording couldn't start  
            try {  
                mRecorder.start();  
            } catch (RuntimeException exception) {  
                AudioManager audioMngr = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);  
                boolean isInCall = ((audioMngr.getMode() == AudioManager.MODE_IN_CALL) ||  
                        (audioMngr.getMode() == AudioManager.MODE_IN_COMMUNICATION));  
                if (isInCall) {  
                    setError(IN_CALL_RECORD_ERROR);  
                } else {  
                    setError(INTERNAL_ERROR);  
                }  
                mRecorder.reset();  
                mRecorder.release();  
                mRecorder = null;  
                return;  
            }  
            mSampleStart = System.currentTimeMillis();  
            setState(RECORDING_STATE);  
        }  
          
        public void stopRecording() {  
            if (mRecorder == null)  
                return;  
      
            mRecorder.stop();  
            mRecorder.release();  
            mRecorder = null;  
      
            mSampleLength = (int)( (System.currentTimeMillis() - mSampleStart)/1000 );  
            setState(IDLE_STATE);  
        }  
          
        public void startPlayback() {  
            stop();  
              
            mPlayer = new MediaPlayer();  
            try {  
                mPlayer.setDataSource(mSampleFile.getAbsolutePath());  
                mPlayer.setOnCompletionListener(this);  
                mPlayer.setOnErrorListener(this);  
                mPlayer.prepare();  
                mPlayer.start();  
            } catch (IllegalArgumentException e) {  
                setError(INTERNAL_ERROR);  
                mPlayer = null;  
                return;  
            } catch (IOException e) {  
                setError(SDCARD_ACCESS_ERROR);  
                mPlayer = null;  
                return;  
            }  
              
            mSampleStart = System.currentTimeMillis();  
            setState(PLAYING_STATE);  
        }  
          
        public void stopPlayback() {  
            if (mPlayer == null) // we were not in playback  
                return;  
      
            mPlayer.stop();  
            mPlayer.release();  
            mPlayer = null;  
            setState(IDLE_STATE);  
        }  
          
        public void stop() {  
            stopRecording();  
            stopPlayback();  
        }  
      
        public boolean onError(MediaPlayer mp, int what, int extra) {  
            stop();  
            setError(SDCARD_ACCESS_ERROR);  
            return true;  
        }  
      
        public void onCompletion(MediaPlayer mp) {  
            stop();  
        }  
          
        private void setState(int state) {  
            if (state == mState)  
                return;  
              
            mState = state;  
            signalStateChanged(mState);  
        }  
          
        private void signalStateChanged(int state) {  
            if (mOnStateChangedListener != null)  
                mOnStateChangedListener.onStateChanged(state);  
        }  
          
        private void setError(int error) {  
            if (mOnStateChangedListener != null)  
                mOnStateChangedListener.onError(error);  
        }  
    }  
    </span>  

界面:

    <span style="font-size:16px;">package org.winplus.sh;  
      
    import android.app.Activity;  
    import android.content.Context;  
    import android.media.MediaRecorder;  
    import android.os.Bundle;  
    import android.os.PowerManager;  
    import android.os.PowerManager.WakeLock;  
    import android.util.Log;  
    import android.view.View;  
    import android.view.View.OnClickListener;  
    import android.widget.Button;  
      
    public class SoundHandActivity extends Activity implements OnClickListener,  
            RecordHelper.OnStateChangedListener {  
      
        private static final String TAG = "SoundHandActivity";  
          
        private VUMeter mVUMeter;  
        private RecordHelper mRecorder;  
      
        private Button btnStart;  
        private Button btnStop;  
      
        WakeLock mWakeLock;  
      
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.main);  
            setupViews();  
        }  
      
        public void setupViews() {  
      
            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);  
            mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,  
                    "SoundRecorder");  
            mRecorder = new RecordHelper();  
            mRecorder.setOnStateChangedListener(this);  
            mVUMeter = (VUMeter) findViewById(R.id.uvMeter);  
            mVUMeter.setRecorder(mRecorder);  
      
            btnStart = (Button) findViewById(R.id.button1);  
            btnStop = (Button) findViewById(R.id.button2);  
            btnStart.setOnClickListener(this);  
            btnStop.setOnClickListener(this);  
        }  
      
        @Override  
        public void onClick(View v) {  
            switch (v.getId()) {  
            case R.id.button1:  
                mRecorder.startRecording(MediaRecorder.OutputFormat.AMR_NB, ".amr",  
                        this);  
                  
                break;  
      
            case R.id.button2:  
                mRecorder.stop();  
                break;  
            }  
        }  
          
        private void updateUi() {  
            Log.e(TAG, "=======================updateUi");  
              
            mVUMeter.invalidate();  
        }  
      
        @Override  
        public void onStateChanged(int state) {  
            if (state == RecordHelper.PLAYING_STATE  
                    || state == RecordHelper.RECORDING_STATE) {  
                mWakeLock.acquire(); // we don't want to go to sleep while recording  
                                        // or playing  
            } else {  
                if (mWakeLock.isHeld())  
                    mWakeLock.release();  
            }  
             updateUi();  
        }  
      
        @Override  
        public void onError(int error) {  
            // TODO Auto-generated method stub  
      
        }  
    }</span>  

源码下载


你可能感兴趣的:(android,File,null,import,float,PIVOT)