2011年5月27日 星期五

AudioRecorder功能

AudioRecorder功能
AudioRecorder這個物件可以設定錄音的品質(頻率、取樣數、聲道)
但是錄出來的資料是原始音頻檔(PCM)
後續還要加Header將其轉換成可播放的格式,例如WAV
下面是使用AudioRecorder做錄音的範例
在範例中,AudioRecorder需要放在另一個線程(Thread)執行
    // 按鈕操作
    public void onClick(View v) {
        // Press start record
        if (v.getId() == R.id.recStart) {
        isRecording = true;
            thread = new Thread(new Runnable() {
                public void run() {
                    record();
                }
            });
            thread.start();

        }
        // Press stop record        else if (v.getId() == R.id.recStop) {
        isRecording = false;
        // 可以用"thread.join()"讓thread進入blocked狀態,目前直接在結束的地方寫"thread.stop();"
        // try {
        //     thread.join();
        // } catch (InterruptedExpection e) { }
        }
    }

    private void record() {
        pcmFile = new File(myDataPath.getAbsolutePath() + "/record.pcm");
        // Delete any previous recording.
        if (pcmFile.exists())
            pcmFile.delete();
        // Create the new file.
        try {
            pcmFile.createNewFile();
        } catch (IOException e) {
            throw new IllegalStateException("Failed to create " + pcmFile.toString());
        }
        // Start record pcm data        try {
            // Create a DataOuputStream to write the audio data into the saved file.            OutputStream os = new FileOutputStream(pcmFile);
            BufferedOutputStream bos = new BufferedOutputStream(os);
            DataOutputStream dos = new DataOutputStream(bos);
  
            // Create a new AudioRecord object to record the audio.
            int bufferSize =
            AudioRecord.getMinBufferSize(
                sampleRateInHz,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT);
  
            AudioRecord audioRecord =
                new AudioRecord(
                    MediaRecorder.AudioSource.MIC,
                    sampleRateInHz,
                    AudioFormat.CHANNEL_IN_MONO,
                    AudioFormat.ENCODING_PCM_16BIT,
                    bufferSize);
            byte[] buffer = new byte[bufferSize];
            audioRecord.startRecording();
            while (isRecording) {
                int bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
                for (int i = 0; i < bufferReadResult; i++)
                    dos.write(buffer[i]);
            }
  
            // filler, data size need can %8 = 0            if (dos.size()%8  != 0) {
                int filler = 0;
                filler = 8 - (dos.size()%8);
                for (int i = 0 ; i < filler ; i++) {
                    dos.writeByte(0);
                }
            }
  
            // stop record and close the file.            audioRecord.stop();
            dos.close();
        } catch (Throwable t) { }
        // stop thread, this method may be not great, we can use the "thread.join( )" method
        thread.stop();
    }

2011年5月25日 星期三

目錄

目錄
Android基礎知識
    Activity類別
    Intent & Bundle物件
    Service類別
    BroadcastReceiver物件
    SharedPreferences物件
    Notification
Android版面設計
    LinearLayout版面配置
    RelativeLayout版面配置
    ScrollView物件 
Android物件應用
    SeekBar物件
    Rating Bar物件
    Toggle Button物件
    Radio Button物件
    CheckBox物件
    Gallery物件
    ProgressBar物件
    MediaPlayer物件
    AudioManager物件
    EditText物件   
    ListView物件
    Menu物件
    Toast & Log物件
    Timer物件
    Dialog物件
    Button物件
    Spinner物件
Android資料讀取
    KeyEven接收
    Battery資訊
    DisplayResolution資訊
    NMEA資訊
Android感測器
    Accelerometer感測器
    OnTouchEvent偵測
    Light感測器
    Gyroscope感測器
    Orientation感測器
Android功能設計
    Wake up lock功能
    設定Brightness功能
    SD card read/write功能
    WiFi功能
    FingerPaint功能

    AudioRecorder功能 - 5/27
Android其他問題
    Rotation問題
    Application類別
    Load Image
    System Settings修改
    How to scan a barcode from another Android application via Intents   

   

SeekBar物件

SeekBar物件
    public void onCreate(Bundle savedInstanceState) {
        .........
        skb_seekbar = (SeekBar)findViewById(R.id.seekbar);
        skb_seekbar.setOnSeekBarChangeListener(change);
    }

    private OnSeekBarChangeListener change = new OnSeekBarChangeListener() {
        public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
        txv_percentage.setText(String.valueOf(arg1));
        set_brightness(arg1);
    }
    public void onStartTrackingTouch(SeekBar seekBar) {}
    public void onStopTrackingTouch(SeekBar seekBar) {}

Orientation感測器

Orientation感測器
方向感測器
    sensor = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);
    sm.registerListener(oriSensor, sensor, SensorManager.SENSOR_DELAY_NORMAL);

    // Azimuth : 0=North, 90=East, 180=South, 270=West     private SensorEventListener oriSensor = new SensorEventListener() {
        public void onAccuracyChanged(Sensor sensor, int accuracy) { }

        public void onSensorChanged(SensorEvent event) {
        txtMsg.setText(
            "(Azimuth, Pitch, Roll) = \n" + event.values[0] + "\n" + event.values[1] + "\n" + event.values[2]);
        }
    };

Gyroscope感測器

Gyroscope感測器
陀螺儀感測器
    sensor = sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
    sm.registerListener(gyroSensor, sensor, SensorManager.SENSOR_DELAY_NORMAL);

    private SensorEventListener gyroSensor = new SensorEventListener() {
         public void onAccuracyChanged(Sensor sensor, int accuracy) { }

         public void onSensorChanged(SensorEvent event) {
             txtMsg.setText("(x, y, z) = \n" + event.values[0] + "\n" + event.values[1] + "\n" + event.values[2]);
        }
    };

2011年5月24日 星期二

ScrollView物件

ScrollView物件當資料訊息過大,導致物件僅顯示部分資料時
可以使用ScrollView物件,將所有的訊息顯示出來

<ScrollView
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"    >
    <TextView 
        android:id="@+id/msg"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text=""    />
</ScrollView>

RelativeLayout版面配置

RelativeLayout版面配置相對佈局版面配置,可指定一物件位於另一物件的相對位置(上下左右)
Default設定,物件位於左上角

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"    >
    <TextView
        android:id="@+id/key_msg"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="15pt"
        android:text="Please press all keys."  />
    <TextView
        android:id="@+id/key_menu"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/key_msg"
        android:text="Menu"  />
    <TextView
        android:id="@+id/key_back"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/key_menu"
        android:text="Back"  />
    <TextView
        android:id="@+id/key_vol_add"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/key_back"
        android:text="Volume +"  />
    <TextView
        android:id="@+id/key_vol_dec"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/key_vol_add"
        android:text="Volume -"  />
    <Button
        android:id="@+id/pass"
        android:layout_width="150px"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"        android:text="PASS"  />
    <Button
        android:id="@+id/fail"
        android:layout_width="150px"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"        android:layout_alignParentRight="true"        android:text="FAIL"  />
</RelativeLayout>