Android-使用SoundPool实现语音计算器

        Android计算器的代码直接使用Android系统里面的Calculator。先找到Android 工程源码中的 Calculator(./package/app/Calculator)。导入到Eclipse或者AS。
        一、Eclipse导入Android系统自带的Calculator。
         在找到Calculator代码以后,在Eclipse中执行:file->New-Project->Android Project from Exsting Code:
         Android-使用SoundPool实现语音计算器_第1张图片
        -Next->选择Calculator(并Copy projects into workspace)。
        导入完成以后会出现很多错误,这是很正常的。要修改这些错误,需要修改targetSDK和配置应用需要的jar库等。
        1)首先要确定 Calculator是Android是那个版本的,我用的Android5.1源码中的Calculator,导入完成以后看到Calculator中的targetSdk却是19(Android4.4)
        
        要让Calculator使用 Android 5.1的SDK,需要修改配置project.properties,将其中的target=android-19改成target=android-22。在Manifest文件中加入:
       
        android:minSdkVersion="11"
        android:targetSdkVersion="22" />
         Android-使用SoundPool实现语音计算器_第2张图片
        当然也可以使用Android4.4的SDK,只不过Android 5.1中的源码都使用了Theme.Material,来实现扁平化的风格。而 Android4.4-SDK并不支持这一风格。当然要保持这一风格也不是不可以,需要使用support 库。
     2)经过上面修改以后,资源中的style错误基本搞定。然后处理java文件中的错误。主要是库没配置好,Calculator不光使用了support库,还使用了一个第三方库:arity-2.1.2(这个不光是在修改错误的时候可以看到,在Calculator的 Android.mk文件中也可以看到),如果源码中找不到对应的库,就要编译Android源码,然后到out目录下去找。可以在Calculator中新建一个libs文件夹,将arity-2.1.2放在里面。然后配置其 build  path:
      Android-使用SoundPool实现语音计算器_第3张图片
    使用Add External JARS...来增加依赖库和私有库。经过这些操作以后,Calculator应用上的错误基本上都处理完了。错误是没有了,但是这样生成的apk是不能安装到任何手机上的。
    因为这样,这个应用的包名和签名等都和Android系统的计算器都是一样的,在安装的时候并不能安装成功,所以必须要修改包名,让这个应用变成自己的应用。
     Android-使用SoundPool实现语音计算器_第4张图片     Android-使用SoundPool实现语音计算器_第5张图片
    重命名包名以后,会提示很多错误,不要紧,虽然Eclipse的重命名会自动更新一些文件,但是仍有一些地方会处理不到。所以先要检查下资源有那些资源文件涉及到包名的使用,比如layout中有个文件要使用src中自定义的类来布局,其路径就包括包名,而这些地方有可能没有全部更新。例如:
     Android-使用SoundPool实现语音计算器_第6张图片
    像上图中展示的,在修改了包名以后,文件并没有全部更新,就需要手动修改,这个只要耐心修改。这部分处理完成以后,还要检查Manifest文件:
    
    上图中的package=“com.android.calculator2”是一定要改成package="com.conway.calculator。这个属性的定义跟R.java文件的生成有关系。看下面修改前后的对比图:
      Android-使用SoundPool实现语音计算器_第7张图片  Android-使用SoundPool实现语音计算器_第8张图片
     然后删掉gen目录下的com.android.calculator2,并将java文件中import com.android.calculator2.R 全部删掉,就算修改完成了。

二、使用SoundPool实现语音计算器:
    经过上面的处理,Calculator就可以安装到手机上了,但是仅限于Android5.1版本的手机,因为Calculator部分控件和theme使用了Material。如果要让它支持所有Android 版本的手机,需要使用support库去实现那些控件和theme。这里就不去处理这些,仅在Genymotion模拟器上运行修改以后的Calculator。
    要实现语音计算器,就要准备音频,在网上找个这类的app然后借用他们的资源来满足自己的学习和实践。而音频资源格式最好选择ogg格式,最起码在Android源码中这类音频都是
使用的ogg格式,这种存在肯定不是偶然性,最起码可以说明ogg格式比较适合SoundPool,对于其他音频格式是否如ogg一样适合SoundPool,我也不得而知。
    SoundPool简单介绍可参考: Android-MediaPlayer 和 SoundPool
    1)初始化SoundPool和加载音频资源:
    在res目录下创建一个raw文件用来存放音频资源:
     Android-使用SoundPool实现语音计算器_第9张图片
    如何将这些资源跟计算器对应的button匹配在一起,这个很容易就会联想到键值对,从而确定使用HashMap来完成资源的加载和配对。     
...
     private Map mSoundResource;
     ...
     protected void initSoundResource(){
        mSoundResource = new HashMap<>();
        if(mSoundPool == null){
            mSoundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
        }
        mSoundResource.put(R.id.digit_0, mSoundPool.load(this, R.raw.num0, 1));
       
        mSoundResource.put(R.id.digit_1, mSoundPool.load(this, R.raw.num1, 1));
       
        mSoundResource.put(R.id.digit_2, mSoundPool.load(this, R.raw.num2, 1));
       
        mSoundResource.put(R.id.digit_3, mSoundPool.load(this, R.raw.num3, 1));
       
        mSoundResource.put(R.id.digit_4, mSoundPool.load(this, R.raw.num4, 1));
       
        mSoundResource.put(R.id.digit_5, mSoundPool.load(this, R.raw.num5, 1));
       
        mSoundResource.put(R.id.digit_6, mSoundPool.load(this, R.raw.num6, 1));
       
        mSoundResource.put(R.id.digit_7, mSoundPool.load(this, R.raw.num7, 1));
       
        mSoundResource.put(R.id.digit_8, mSoundPool.load(this, R.raw.num8, 1));
       
        mSoundResource.put(R.id.digit_9, mSoundPool.load(this, R.raw.num9, 1));
       
        mSoundResource.put(R.id.dec_point, mSoundPool.load(this, R.raw.point, 1));
       
        mSoundResource.put(R.id.eq, mSoundPool.load(this, R.raw.equal, 1));
       
        mSoundResource.put(R.id.del, mSoundPool.load(this, R.raw.delete, 1));
       
        mSoundResource.put(R.id.clr, mSoundPool.load(this, R.raw.delete, 1));
       
        mSoundResource.put(R.id.op_div, mSoundPool.load(this, R.raw.divide, 1));
       
        mSoundResource.put(R.id.op_mul, mSoundPool.load(this, R.raw.multiply, 1));
       
        mSoundResource.put(R.id.op_sub, mSoundPool.load(this, R.raw.minus, 1));
       
        mSoundResource.put(R.id.op_add, mSoundPool.load(this, R.raw.plus, 1));
    }

    在onCreate方法中调用此方法,完成资源的配对和SoundPool的Load。

    2)实现播放功能:   
protected void playSound(int id){
        if(id == 0){
            return;
        }
        if(mAudioManager == null){
            mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        }
        int mSoundVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
               
        if(mSoundResource.get(id) != null){
            mSoundPool.stop(mSoundStreamId);
            mSoundStreamId = mSoundPool.play(mSoundResource.get(id), mSoundVolume, mSoundVolume, 1, 0, (float) 1.0);
        }
    }
 public void onButtonClick(View view) {
        switch (view.getId()) {
            case R.id.eq:
                onEquals();
                playSound(R.id.eq);
                break;
            case R.id.del:
                onDelete();
                playSound(R.id.del);
                break;
            case R.id.clr:
                onClear();
                playSound(R.id.clr);
                break;
            case R.id.fun_cos:
            case R.id.fun_ln:
            case R.id.fun_log:
            case R.id.fun_sin:
            case R.id.fun_tan:
                // Add left parenthesis after functions.
                mFormulaEditText.append(((Button) view).getText() + "(");
                break;
            default:
                mFormulaEditText.append(((Button) view).getText());
                playSound(view.getId());
                break;
        }
    }
    3)释放资源:    
@Override
    protected void onDestroy() {
        super.onDestroy();
        if(mAudioManager != null){
            mAudioManager = null;
        }
       
        if(mSoundPool != null){
            mSoundPool.release();
            mSoundPool = null;
        }
       
        if(mSoundResource != null){
            mSoundResource.clear();
            mSoundResource = null;
        }
    }

    至此一个简单的语音计算器就算完成了!当然我并没有去优化和美化它。
       
    源码链接:http://pan.baidu.com/s/1iEZuQ 密码:1jdq 。(Calculator.zip)
    
        

你可能感兴趣的:(Android-实践)