随想录(一个android原生app的代码赏析)

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

今天下午,无意看到android一个原生的app代码,也就一个文件SpeechRecorderActivity.java。开发android app原来不难。插句话,android所有的自带app都是开源的,它们其实才是最好的学习资料。接着大家可以看一下,具体内容如下,

/*
 * Copyright (C) 2007 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.speechrecorder;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.speech.srec.Recognizer;
import android.speech.srec.WaveHeader;
import android.speech.srec.MicrophoneInputStream;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.TextView;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class SpeechRecorderActivity extends Activity {
    private static final String TAG = "SpeechRecorderActivity";

    private static final int DURATION_SEC = 7;

    private Handler mHandler;

    private TextView mCommand;
    private TextView mStatus;
    private Button mRecord;
    private Button mRedo;
    private RadioButton m8KHz;
    private RadioButton m11KHz;
    private RadioButton mCall;
    private RadioButton mDialNanp;
    private RadioButton mDialPairs;

    private InputStream mMicrophone;
    private ByteArrayOutputStream mBaos;

    private File mUtterance;
    private int mSampleRate;
    private Thread mThread;
    private boolean mStoppedListening;

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        mHandler = new Handler();

        setContentView(R.layout.recorder);
        mCommand = (TextView) findViewById(R.id.commandText);
        mStatus = (TextView) findViewById(R.id.statusText);
        mRecord = (Button) findViewById(R.id.recordButton);
        mRedo = (Button) findViewById(R.id.redoButton);
        m8KHz = (RadioButton)findViewById(R.id.codec8KHzRadioButton);
        m11KHz = (RadioButton)findViewById(R.id.codec11KHzRadioButton);
        mCall = (RadioButton)findViewById(R.id.callRadioButton);
        mDialNanp = (RadioButton)findViewById(R.id.dialNanpRadioButton);
        mDialPairs = (RadioButton)findViewById(R.id.dialPairsRadioButton);

        mCommand.setText("Please click ‘Record‘ to begin");
        mRecord.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if (false) {
                    Log.d(TAG, "mRecord.OnClickListener.onClick");
                }

                setupRecording();
            }
        });

        mRedo.setEnabled(false);
        mRedo.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if (false) {
                    Log.d(TAG, "mRedo.onClickListener.onClick");
                }

                mUtterance.delete();

                setupRecording();
            }
        });

        m8KHz.setText("PCM/16bit/8KHz");
        m11KHz.setText("PCM/16bit/11KHz");
        m11KHz.setChecked(true);
        mCall.setChecked(true);
    }

    private void setupRecording() {
        Log.d(TAG, "setupRecording");
        // disable buttons
        mRedo.setEnabled(false);
        mRecord.setEnabled(false);
        m8KHz.setFocusable(false);
        m11KHz.setFocusable(false);
        mCall.setFocusable(false);
        mDialNanp.setFocusable(false);
        mDialPairs.setFocusable(false);

        // find the first utterance not covered
        String[] utterances = mCall.isChecked() ? mCallUtterances :
            mDialNanp.isChecked() ? mDialNanpUtterances :
            mDialPairs.isChecked() ? mDialPairsUtterances :
                null;
        mUtterance = null;
        int index = -1;
        for (int i = 0; i < utterances.length; i++) {
            File u = new File(getDir("recordings", MODE_PRIVATE),
                    utterances[i].toLowerCase().replace(‘ ‘, ‘_‘) + ".wav");
            if (!u.exists()) {
                mUtterance = u;
                index = i;
                break;
            }
        }

        // check if done
        if (mUtterance == null) {
            mCommand.setText("Finished: Thank You!");
            return;
        }
        Log.d(TAG, "going to record " + mUtterance.toString());

        // fix up UI
        mCommand.setText("Say: \"" + utterances[index] + "\"");
        final String status = "item " + (index + 1) + "/" + utterances.length;

        // start the microphone
        mSampleRate = m8KHz.isChecked()? 8000 :
                m11KHz.isChecked() ? 11025 :
                11025;
        mBaos = new ByteArrayOutputStream(mSampleRate * 2 * 20);
        try {
            mMicrophone = new MicrophoneInputStream(mSampleRate, mSampleRate * 15);

//            mMicrophone = logInputStream(mUtterance.toString(), mMicrophone, mSampleRate);
        } catch (IOException e) {

        }

        // post a number of delayed events to update the UI and to stop recording
        // after a few seconds.
        for (int i = 0; i <= DURATION_SEC; i++) {
            final int remain = DURATION_SEC - i;
            mHandler.postDelayed(new Runnable() {
                public void run() {
                    if (remain > 0) {
                        mStatus.setText(status + "  Recording... " + remain);
                    }
                    else {
                        mStatus.setText(status);
                        stopRecording();
                    }
                }
            }, i * 1000);
        }

        // now start a thread to store the audio.
        mStoppedListening = false;
        mThread = new Thread() {
            public void run() {
                Log.d(TAG, "run audio capture thread");
                byte buffer[] = new byte[512];
                while (!mStoppedListening) {
                    try {
                        int rtn = 0;
                        rtn = mMicrophone.read(buffer, 0, 512);
                        if (rtn > 0) mBaos.write(buffer, 0, rtn);
                    } catch (IOException e) {
                    }
                }
            }
        };
        mThread.start();

        // to avoid the button click
        try {
            Thread.sleep(100);
        } catch (InterruptedException ie) {
        }

    }

    private void stopRecording() {
        Log.d(TAG, "stopRecording");
        mStoppedListening = true;
        try {
            mThread.join();
        } catch (InterruptedException e) {

        }
        try {
            OutputStream out = new FileOutputStream(mUtterance.toString());
            try {
                byte[] pcm = mBaos.toByteArray();
                Log.d(TAG, "byteArray length " + pcm.length);
                WaveHeader hdr = new WaveHeader(WaveHeader.FORMAT_PCM,
                        (short)1, mSampleRate, (short)16, pcm.length);
                hdr.write(out);
                out.write(pcm);
            } finally {
                out.close();
                mMicrophone.close();
                mBaos.close();
            }
        } catch (IOException e) {

        } finally {
        }

        // stop the recording
        mRecord.setEnabled(true);

        mRedo.setEnabled(true);

        mCommand.setText("Got it!");
    }

    private final static String[] mCallUtterances = new String[] {
        "Call Adam Varro",
        "Call Alex Lloyd",
        "Call Amod Karve",
        "Call Ana Maria Lopez",
        "Call Ben Sigelman",
        "Call Chris Vennard",
        "Call Dana Pogoda",
        "Call Daryl Pregibon",
        "Call Davi Robison",
        "Call David Barrett Kahn",
        "Call David Hyman",
        "Call Douglas Gordin",
        "Call Gregor Rothfuss",
        "Call James Sheridan",
        "Call Jason Charo",
        "Call Jeff Reynar",
        "Call Joel Ward",
        "Call John Milton",
        "Call Lajos Nagy",
        "Call Lori Sobel",
        "Call Martin Jansche",
        "Call Meghan McGarry",
        "Call Meghan Shakar",
        "Call Nilka Thomas",
        "Call Pedro Colijn",
        "Call Pramod Adiddam",
        "Call Rajeev Sivaram",
        "Call Rich Armstrong",
        "Call Robin Watson",
        "Call Sam Morales",
    };

    private final static String[] mDialPairsUtterances = new String[] {
        // all possible pairs
        "Dial 000 000 0000",

        "Dial 101 010 1010",
        "Dial 111 111 1111",

        "Dial 202 020 2020",
        "Dial 212 121 2121",
        "Dial 222 222 2222",

        "Dial 303 030 3030",
        "Dial 313 131 3131",
        "Dial 323 232 3232",
        "Dial 333 333 3333",

        "Dial 404 040 4040",
        "Dial 414 141 4141",
        "Dial 424 242 4242",
        "Dial 434 343 4343",
        "Dial 444 444 4444",

        "Dial 505 050 5050",
        "Dial 515 151 5151",
        "Dial 525 252 5252",
        "Dial 535 353 5353",
        "Dial 545 454 5454",
        "Dial 555 555 5555",

        "Dial 606 060 6060",
        "Dial 616 161 6161",
        "Dial 626 262 6262",
        "Dial 636 363 6363",
        "Dial 646 464 6464",
        "Dial 656 565 6565",
        "Dial 666 666 6666",

        "Dial 707 070 7070",
        "Dial 717 171 7171",
        "Dial 727 272 7272",
        "Dial 737 373 7373",
        "Dial 747 474 7474",
        "Dial 757 575 7575",
        "Dial 767 676 7676",
        "Dial 777 777 7777",

        "Dial 808 080 8080",
        "Dial 818 181 8181",
        "Dial 828 282 8282",
        "Dial 838 383 8383",
        "Dial 848 484 8484",
        "Dial 858 585 8585",
        "Dial 868 686 8686",
        "Dial 878 787 8787",
        "Dial 888 888 8888",

        "Dial 909 090 9090",
        "Dial 919 191 9191",
        "Dial 929 292 9292",
        "Dial 939 393 9393",
        "Dial 949 494 9494",
        "Dial 959 595 9595",
        "Dial 969 696 9696",
        "Dial 979 797 9797",
        "Dial 989 898 9898",
        "Dial 999 999 9999",

    };

    private final static String[] mDialNanpUtterances = new String[] {
        "Dial 211",
        "Dial 411",
        "Dial 511",
        "Dial 811",
        "Dial 911",
        // random numbers
        "Dial 653 5763",
        "Dial 263 9072",
        "Dial 202 9781",
        "Dial 379 8229",
        "Dial 874 9139",
        "Dial 236 0163",
        "Dial 656 7455",
        "Dial 474 5254",
        "Dial 348 8687",
        "Dial 629 8602",

        //"Dial 272 717 8405",
        //"Dial 949 516 0162",
        //"Dial 795 117 7190",
        //"Dial 493 656 3767",
        //"Dial 588 093 9218",
        "Dial 511 658 3690",
        "Dial 440 301 8489",
        "Dial 695 713 6744",
        "Dial 581 475 8712",
        "Dial 981 388 3579",

        "Dial 840 683 3346",
        "Dial 303 467 7988",
        "Dial 649 504 5290",
        "Dial 184 577 4229",
        "Dial 212 286 3982",
        "Dial 646 258 0115",
        "Dial 427 482 6852",
        "Dial 231 809 9260",
        "Dial 681 930 4301",
        "Dial 246 650 8339",
    };
}

这份代码是从2.*版本的android上发现的,但是现在还在不在就不知道了。代码的主要功能就是setupRecording和stopRecording。app的创建主要是由一个create函数完成的。如果还有一点难度的话,那么就是Thread的创建和等待了。

时间: 2024-10-11 01:11:42

随想录(一个android原生app的代码赏析)的相关文章

android对app进行代码混淆

接到一个新的任务,对现有项目进行代码混淆.之前对混淆有过一些了解,但是不够详细和完整,知道有些东西混淆起来还是比较棘手的.不过幸好目前的项目不是太复杂(针对混淆这块来说),提前完成--现总结之. 第一部分 介绍下操作流程(eclipse): 1.打开混淆器:找到项目根目录下的project.properties文件,将"#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt"

Android TV 开发笔记二:创建第一个Android TV App

一:创建 New Project 1. 2. 3. 4. 创建成果后发现已经帮你创建好了一些demo页面,并且数据都已经绑定好了 二:解决错误 1.创建成功后,build发现报错了,如下: 这个错误是因为版本问题导致的 解决方法,将版本号修改为以下的: 接着又会报错: 作为一个程序员,这点小错误相信难不倒你,自己解决吧,是HeaderItem用的构造函数不对导致的 至此终于得到了一个可以运行的AndroidTV Demo

Android 重启APP application 代码 code restart android app

System.exit(0); Intent i =new Intent(getBaseContext(), POU2.class); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(i);

第一课--建立第一个Android App

本课通过创建一个Android的App程序,达到三个目的: 第一:让大家了解在Eclipse中如何创建Android应用程序. 第二:了解Android应用程序中包的重要意义. 第三:了解Android最小SDK版本的作用. 这段程序甚至不需要写一行代码,就可以全自动地创建好. 步骤1 打开Eclipse,选择菜单File->New->And-roid Application Project,如下图所示的创建Android程序界面. 在Application Name文本框中输入应用名称,在P

使用PhoneGap搭建一个山寨京东APP

为什么要写一个App 首先解释下写出来的这个App,其实无任何功能,只是用HTML和CSS模仿JD移动端界面写的一个适配移动端的Web界面.本篇主要内容是介绍如何使用PhoneGap把开发出来的mobile web app快速打包成Native App.最近还在学习HTML&CSS以及Javascript,偶然想想学这些有什么用,一方面可以做Web系统的前端开发,另一方面也可以做移动端的Web App.刚好最近了解到PhoneGap,研究了一下它的框架平台,花了两个晚上终于把一个web系统变成了

PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码

PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码 看看新闻网>看引擎>开源产品 0人收藏此文章, 发表于8小时前(2013-09-06 00:39) , 已有13次阅读 ,共0个评论 依照我一惯得套路,我会先说一点废话. PhoneGap和Cordova什么关系?为什么有的地方叫Cordova而有的地方叫PhoneGap ?PhoneGap是一款HTML5平台.通过它,开发商能够使用HTML.CSS及JavaScript来开发本地移动应用程序.因此,眼下开

怎么判断一个APP是原生APP、混合APP还是WEB APP ?

1.看断网情况 通过断开网络,刷新页面,观察内容缓存情况来有个大致的判断,可以正常显示的就是原生写的,显示404或者错误页面的就是html页面. 2.看布局编辑 3.看复制文章的提示,需要通过对比才能得出结果. 比如文章资讯页面可以长按页面试试,如果出现文字选择,粘贴功能的是H5页面,否则是native原生的页面. 有些原生APP开放了复制粘贴功能或者关闭了,而H5的CSS屏蔽了复制选择功能等情况,需要通过对目标测试APP进行对比才可知. 在支付宝APP.蚂蚁聚宝是可以判断的. 4.看加载的方式

VS2015下的Android开发系列02——用VS开发第一个Android APP

配置Android模拟器 这算是第一篇漏下说的,配置好VS的各参数,新建Android项目后,会发现菜单下的工具栏会多出Android相关的工具栏,红色圈出的就是AVD. 打开AVD后可以从模版处选一个设备,然后自己再做细节参数调整. 然后选择要模拟的版本,因为APP有蓝牙BLE的支持需求,所以选择了至少API Level18,注意如果安装了HAXM,CPU/ABI项一定要选"Intel Atom (x86)",如果没有,说明组件未安装,赶紧去下载后再来:另外一个注意点是内存至少3G,

Android Studio新建一个HelloWorld 程序(App)

Android Studio新建一个HelloWorld程序(App) 新建 或者直接启动程序(注:如果已有程序,此方法会直接打开最近一次关闭从程序) 更改App名 选择App运行平台 选择模板 更改主视图名 等待程序编译 此过程需要较长时间,耐心等待- 直到底部状态栏不再有动作执行. AS默认打开主视图代码 打开设计界面 运行程序 首先手机开启调试模式,并连接电脑 注1:此过程有可能会因为某些原因App不能正常运行 注2:此过程需要较长时间,耐心等待,直到手机上App启动成功 程序运行完成 G