diff options
author | Marco Nelissen <marcone@google.com> | 2011-08-11 10:41:33 -0700 |
---|---|---|
committer | Marco Nelissen <marcone@google.com> | 2011-08-11 10:42:17 -0700 |
commit | ef02abd50531952b263061eeff6003f2605e91d5 (patch) | |
tree | b061adfd2311e6882adc8face934d41dcf9a1c22 /media | |
parent | 08633c79164c8ab7362d6af1cf9ab576916fa7e0 (diff) | |
download | frameworks_base-ef02abd50531952b263061eeff6003f2605e91d5.zip frameworks_base-ef02abd50531952b263061eeff6003f2605e91d5.tar.gz frameworks_base-ef02abd50531952b263061eeff6003f2605e91d5.tar.bz2 |
Add Bluetooth SCO test app
Change-Id: I6c0c267fbb546b6db544e5ddb03e65276895e0e0
Diffstat (limited to 'media')
-rwxr-xr-x | media/tests/ScoAudioTest/Android.mk | 12 | ||||
-rwxr-xr-x | media/tests/ScoAudioTest/AndroidManifest.xml | 36 | ||||
-rwxr-xr-x | media/tests/ScoAudioTest/res/drawable/icon.png | bin | 0 -> 6094 bytes | |||
-rwxr-xr-x | media/tests/ScoAudioTest/res/drawable/record.png | bin | 0 -> 688 bytes | |||
-rwxr-xr-x | media/tests/ScoAudioTest/res/drawable/stop.png | bin | 0 -> 369 bytes | |||
-rwxr-xr-x | media/tests/ScoAudioTest/res/layout/scoaudiotest.xml | 181 | ||||
-rw-r--r-- | media/tests/ScoAudioTest/res/raw/sine440_mo_16b_16k.wav | bin | 0 -> 320044 bytes | |||
-rwxr-xr-x | media/tests/ScoAudioTest/res/values/strings.xml | 14 | ||||
-rw-r--r-- | media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java | 700 |
9 files changed, 943 insertions, 0 deletions
diff --git a/media/tests/ScoAudioTest/Android.mk b/media/tests/ScoAudioTest/Android.mk new file mode 100755 index 0000000..ab12865 --- /dev/null +++ b/media/tests/ScoAudioTest/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +#LOCAL_SDK_VERSION := current + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := scoaudiotest + +include $(BUILD_PACKAGE) diff --git a/media/tests/ScoAudioTest/AndroidManifest.xml b/media/tests/ScoAudioTest/AndroidManifest.xml new file mode 100755 index 0000000..8ff973e --- /dev/null +++ b/media/tests/ScoAudioTest/AndroidManifest.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.scoaudiotest"> + + <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> + <uses-permission android:name="android.permission.RECORD_AUDIO" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.BROADCAST_STICKY" /> + <uses-permission android:name="android.permission.BLUETOOTH" /> + + <application> + <activity android:label="@string/app_name" + android:name="ScoAudioTest"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + + </application> +</manifest> diff --git a/media/tests/ScoAudioTest/res/drawable/icon.png b/media/tests/ScoAudioTest/res/drawable/icon.png Binary files differnew file mode 100755 index 0000000..64e3601 --- /dev/null +++ b/media/tests/ScoAudioTest/res/drawable/icon.png diff --git a/media/tests/ScoAudioTest/res/drawable/record.png b/media/tests/ScoAudioTest/res/drawable/record.png Binary files differnew file mode 100755 index 0000000..ae518d5 --- /dev/null +++ b/media/tests/ScoAudioTest/res/drawable/record.png diff --git a/media/tests/ScoAudioTest/res/drawable/stop.png b/media/tests/ScoAudioTest/res/drawable/stop.png Binary files differnew file mode 100755 index 0000000..83f012c --- /dev/null +++ b/media/tests/ScoAudioTest/res/drawable/stop.png diff --git a/media/tests/ScoAudioTest/res/layout/scoaudiotest.xml b/media/tests/ScoAudioTest/res/layout/scoaudiotest.xml new file mode 100755 index 0000000..b769a0c --- /dev/null +++ b/media/tests/ScoAudioTest/res/layout/scoaudiotest.xml @@ -0,0 +1,181 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2009 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <LinearLayout android:id="@+id/playPause1Frame" + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginLeft="10dip" + android:layout_marginTop="3dip" + android:layout_marginRight="10dip" + android:layout_marginBottom="3dip" > + + <TextView android:id="@+id/playPause1Text" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_weight="1.0" + android:text="@string/playback_name" + android:layout_gravity="center_vertical|left" + style="@android:style/TextAppearance.Medium" /> + + <ImageButton android:id="@+id/stop1" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:layout_gravity="center_vertical|right" + android:layout_weight="0.0" + android:src="@drawable/stop"/> + + <ImageButton android:id="@+id/playPause1" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:layout_gravity="center_vertical|right" + android:layout_weight="0.0" + android:src="@android:drawable/ic_media_play"/> + + </LinearLayout> + + </LinearLayout> + + <LinearLayout + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <LinearLayout android:id="@+id/record1Frame" + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginLeft="10dip" + android:layout_marginTop="3dip" + android:layout_marginRight="10dip" + android:layout_marginBottom="3dip" > + + <TextView android:id="@+id/record1Text" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_weight="1.0" + android:text="@string/record_name" + android:layout_gravity="center_vertical|left" + style="@android:style/TextAppearance.Medium" /> + + <ImageButton android:id="@+id/recStop1" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:layout_gravity="center_vertical|right" + android:layout_weight="0.0" + android:src="@drawable/record"/> + </LinearLayout> + + </LinearLayout> + + <LinearLayout + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <LinearLayout android:id="@+id/forceFrame" + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginLeft="10dip" + android:layout_marginTop="3dip" + android:layout_marginRight="10dip" + android:layout_marginBottom="3dip" > + + <ToggleButton android:id="@+id/ForceScoButton" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:layout_gravity="center_vertical|left" + android:layout_weight="0.0" + android:textOff="@string/force_sco_off" + android:textOn="@string/force_sco_on" /> + + <TextView android:id="@+id/scoStateTxt" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_weight="1.0" + android:layout_gravity="center_vertical|right" + style="@android:style/TextAppearance.Medium" /> + </LinearLayout> + <CheckBox + android:id="@+id/useSecondAudioManager" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/audiomanagertwo" /> + + </LinearLayout> + + <LinearLayout + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <LinearLayout android:id="@+id/voiceDialerFrame" + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginLeft="10dip" + android:layout_marginTop="3dip" + android:layout_marginRight="10dip" + android:layout_marginBottom="3dip" > + + <ToggleButton android:id="@+id/VoiceDialerButton" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:layout_gravity="center_vertical|left" + android:layout_weight="0.0" + android:textOff="@string/vd_off" + android:textOn="@string/vd_on" /> + + <TextView android:id="@+id/vdStateTxt" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_weight="1.0" + android:layout_gravity="center_vertical|right" + style="@android:style/TextAppearance.Medium" /> + + </LinearLayout> + + </LinearLayout> + + <EditText android:id="@+id/speakTextEdit" + android:layout_width="fill_parent" + android:layout_height="wrap_content" /> + + <ToggleButton android:id="@+id/TtsToFileButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textOff="@string/tts_speak" + android:textOn="@string/tts_to_file" /> + + + <Spinner android:id="@+id/modeSpinner" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:drawSelectorOnTop="true" + /> + +</LinearLayout> diff --git a/media/tests/ScoAudioTest/res/raw/sine440_mo_16b_16k.wav b/media/tests/ScoAudioTest/res/raw/sine440_mo_16b_16k.wav Binary files differnew file mode 100644 index 0000000..2538b4d6 --- /dev/null +++ b/media/tests/ScoAudioTest/res/raw/sine440_mo_16b_16k.wav diff --git a/media/tests/ScoAudioTest/res/values/strings.xml b/media/tests/ScoAudioTest/res/values/strings.xml new file mode 100755 index 0000000..c3ff6d5 --- /dev/null +++ b/media/tests/ScoAudioTest/res/values/strings.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">Sco Audio Test</string> + <string name="playback_name">Playback</string> + <string name="record_name">Record</string> + <string name="force_sco_off">NO SCO</string> + <string name="force_sco_on">USE SCO</string> + <string name="vd_off">Start Voice Dialer</string> + <string name="vd_on">Voice Dialer On</string> + <string name="tts_speak">Speak TTS</string> + <string name="tts_to_file">TTS to file</string> + <string name="audiomanagertwo">Use different AudioManager for starting SCO</string> + +</resources> diff --git a/media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java b/media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java new file mode 100644 index 0000000..fe3929d --- /dev/null +++ b/media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java @@ -0,0 +1,700 @@ +/* + * Copyright (C) 2009 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.scoaudiotest; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHeadset; +import android.bluetooth.BluetoothProfile; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.AssetFileDescriptor; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.media.MediaRecorder; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.speech.tts.TextToSpeech; +import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.ToggleButton; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; + +public class ScoAudioTest extends Activity { + + final static String TAG = "ScoAudioTest"; + + AudioManager mAudioManager; + AudioManager mAudioManager2; + boolean mForceScoOn; + ToggleButton mScoButton; + ToggleButton mVoiceDialerButton; + boolean mVoiceDialerOn; + String mLastRecordedFile; + SimpleMediaController mMediaControllers[] = new SimpleMediaController[2]; + private TextToSpeech mTts; + private HashMap<String, String> mTtsParams; + private int mOriginalVoiceVolume; + EditText mSpeakText; + boolean mTtsInited; + private Handler mHandler; + private static final String UTTERANCE = "utterance"; + private static Intent sVoiceCommandIntent; + private File mSampleFile; + ToggleButton mTtsToFileButton; + private boolean mTtsToFile; + private int mCurrentMode; + Spinner mModeSpinner; + private BluetoothHeadset mBluetoothHeadset; + private BluetoothDevice mBluetoothHeadsetDevice; + TextView mScoStateTxt; + TextView mVdStateTxt; + + private final BroadcastReceiver mReceiver = new ScoBroadcastReceiver(); + + public ScoAudioTest() { + Log.e(TAG, "contructor"); + } + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + setContentView(R.layout.scoaudiotest); + + mScoStateTxt = (TextView) findViewById(R.id.scoStateTxt); + mVdStateTxt = (TextView) findViewById(R.id.vdStateTxt); + + IntentFilter intentFilter = + new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); + intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED); + intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED); + registerReceiver(mReceiver, intentFilter); + + mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + mAudioManager2 = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE); + mHandler = new Handler(); + + mMediaControllers[0] = new SimplePlayerController(this, R.id.playPause1, R.id.stop1, + R.raw.sine440_mo_16b_16k, AudioManager.STREAM_BLUETOOTH_SCO); + TextView name = (TextView) findViewById(R.id.playPause1Text); + name.setText("VOICE_CALL stream"); + + mScoButton = (ToggleButton)findViewById(R.id.ForceScoButton); + mScoButton.setOnCheckedChangeListener(mForceScoChanged); + mForceScoOn = false; + mScoButton.setChecked(mForceScoOn); + + mVoiceDialerButton = (ToggleButton)findViewById(R.id.VoiceDialerButton); + mVoiceDialerButton.setOnCheckedChangeListener(mVoiceDialerChanged); + mVoiceDialerOn = false; + mVoiceDialerButton.setChecked(mVoiceDialerOn); + + + mMediaControllers[1] = new SimpleRecordController(this, R.id.recStop1, 0, "Sco_record_"); + mTtsInited = false; + mTts = new TextToSpeech(this, new TtsInitListener()); + mTtsParams = new HashMap<String, String>(); + mTtsParams.put(TextToSpeech.Engine.KEY_PARAM_STREAM, + String.valueOf(AudioManager.STREAM_BLUETOOTH_SCO)); + mTtsParams.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, + UTTERANCE); + + mSpeakText = (EditText) findViewById(R.id.speakTextEdit); + mSpeakText.setOnKeyListener(mSpeakKeyListener); + mSpeakText.setText("sco audio test sentence"); + mTtsToFileButton = (ToggleButton)findViewById(R.id.TtsToFileButton); + mTtsToFileButton.setOnCheckedChangeListener(mTtsToFileChanged); + mTtsToFile = true; + mTtsToFileButton.setChecked(mTtsToFile); + + mModeSpinner = (Spinner) findViewById(R.id.modeSpinner); + ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, + android.R.layout.simple_spinner_item, mModeStrings); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + mModeSpinner.setAdapter(adapter); + mModeSpinner.setOnItemSelectedListener(mModeChanged); + mCurrentMode = mAudioManager.getMode(); + mModeSpinner.setSelection(mCurrentMode); + + mBluetoothHeadsetDevice = null; + BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); + if (btAdapter != null) { + btAdapter.getProfileProxy(this, mBluetoothProfileServiceListener, + BluetoothProfile.HEADSET); + } + + sVoiceCommandIntent = new Intent(Intent.ACTION_VOICE_COMMAND); + sVoiceCommandIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } + + @Override + public void onDestroy() { + super.onDestroy(); + mTts.shutdown(); + unregisterReceiver(mReceiver); + if (mBluetoothHeadset != null) { + BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); + if (btAdapter != null) { + btAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset); + } + } + } + + @Override + protected void onPause() { + super.onPause(); +// mForceScoOn = false; +// mScoButton.setChecked(mForceScoOn); + mMediaControllers[0].stop(); + mMediaControllers[1].stop(); + mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO, + mOriginalVoiceVolume, 0); + } + + @Override + protected void onResume() { + super.onResume(); + mLastRecordedFile = ""; + mMediaControllers[0].mFileName = ""; + mOriginalVoiceVolume = mAudioManager.getStreamVolume( + AudioManager.STREAM_BLUETOOTH_SCO); + setVolumeControlStream(AudioManager.STREAM_BLUETOOTH_SCO); + mCurrentMode = mAudioManager.getMode(); + mModeSpinner.setSelection(mCurrentMode); + } + + private OnCheckedChangeListener mForceScoChanged + = new OnCheckedChangeListener(){ + @Override + public void onCheckedChanged(CompoundButton buttonView, + boolean isChecked) { + if (mForceScoOn != isChecked) { + mForceScoOn = isChecked; + AudioManager mngr = mAudioManager; + CheckBox box = (CheckBox) findViewById(R.id.useSecondAudioManager); + if (box.isChecked()) { + Log.i(TAG, "Using 2nd audio manager"); + mngr = mAudioManager2; + } + + if (mForceScoOn) { + Log.e(TAG, "startBluetoothSco() IN"); + mngr.startBluetoothSco(); + Log.e(TAG, "startBluetoothSco() OUT"); + } else { + Log.e(TAG, "stopBluetoothSco() IN"); + mngr.stopBluetoothSco(); + Log.e(TAG, "stopBluetoothSco() OUT"); + } + } + } + }; + + private OnCheckedChangeListener mVoiceDialerChanged + = new OnCheckedChangeListener(){ + @Override + public void onCheckedChanged(CompoundButton buttonView, + boolean isChecked) { + if (mVoiceDialerOn != isChecked) { + mVoiceDialerOn = isChecked; + if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) { + if (mVoiceDialerOn) { + mBluetoothHeadset.startVoiceRecognition(mBluetoothHeadsetDevice); + } else { + mBluetoothHeadset.stopVoiceRecognition(mBluetoothHeadsetDevice); + } + } + } + } + }; + + private OnCheckedChangeListener mTtsToFileChanged + = new OnCheckedChangeListener(){ + @Override + public void onCheckedChanged(CompoundButton buttonView, + boolean isChecked) { + mTtsToFile = isChecked; + } + }; + + private class SimpleMediaController implements OnClickListener { + int mPlayPauseButtonId; + int mStopButtonId; + Context mContext; + ImageView mPlayPauseButton; + int mPlayImageResource; + int mPauseImageResource; + String mFileNameBase; + String mFileName; + int mFileResId; + + SimpleMediaController(Context context, int playPausebuttonId, int stopButtonId, String fileName) { + mContext = context; + mPlayPauseButtonId = playPausebuttonId; + mStopButtonId = stopButtonId; + mFileNameBase = fileName; + mPlayPauseButton = (ImageButton) findViewById(playPausebuttonId); + ImageButton stop = (ImageButton) findViewById(stopButtonId); + + mPlayPauseButton.setOnClickListener(this); + mPlayPauseButton.requestFocus(); + if (stop != null) { + stop.setOnClickListener(this); + } + } + + SimpleMediaController(Context context, int playPausebuttonId, int stopButtonId, int fileResId) { + mContext = context; + mPlayPauseButtonId = playPausebuttonId; + mStopButtonId = stopButtonId; + mFileNameBase = ""; + mFileResId = fileResId; + mPlayPauseButton = (ImageButton) findViewById(playPausebuttonId); + ImageButton stop = (ImageButton) findViewById(stopButtonId); + + mPlayPauseButton.setOnClickListener(this); + mPlayPauseButton.requestFocus(); + if (stop != null) { + stop.setOnClickListener(this); + } + } + + @Override + public void onClick(View v) { + if (v.getId() == mPlayPauseButtonId) { + playOrPause(); + } else if (v.getId() == mStopButtonId) { + stop(); + } + } + + public void playOrPause() { + } + + public void stop() { + } + + public boolean isPlaying() { + return false; + } + + public void updatePlayPauseButton() { + mPlayPauseButton.setImageResource(isPlaying() ? mPauseImageResource : mPlayImageResource); + } + } + + private class SimplePlayerController extends SimpleMediaController { + private MediaPlayer mMediaPlayer; + private int mStreamType; + SimplePlayerController(Context context, int playPausebuttonId, int stopButtonId, String fileName, int stream) { + super(context, playPausebuttonId, stopButtonId, fileName); + + mPlayImageResource = android.R.drawable.ic_media_play; + mPauseImageResource = android.R.drawable.ic_media_pause; + mStreamType = stream; + mFileName = Environment.getExternalStorageDirectory().toString() + "/music/" + + mFileNameBase + "_" + ".wav"; + } + + SimplePlayerController(Context context, int playPausebuttonId, int stopButtonId, int fileResId, int stream) { + super(context, playPausebuttonId, stopButtonId, fileResId); + + mPlayImageResource = android.R.drawable.ic_media_play; + mPauseImageResource = android.R.drawable.ic_media_pause; + mStreamType = stream; + mFileName = ""; + } + + @Override + public void playOrPause() { + Log.e(TAG, "playOrPause playing: "+((mMediaPlayer == null)?false:!mMediaPlayer.isPlaying())+ + " mMediaPlayer: "+mMediaPlayer+ + " mFileName: "+mFileName+ + " mLastRecordedFile: "+mLastRecordedFile); + if (mMediaPlayer == null || !mMediaPlayer.isPlaying()){ + if (mMediaPlayer == null) { + if (mFileName != mLastRecordedFile) { + mFileName = mLastRecordedFile; + Log.e(TAG, "new recorded file: "+mFileName); + } + try { + mMediaPlayer = new MediaPlayer(); + if (mFileName.equals("")) { + Log.e(TAG, "Playing from resource"); + AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(mFileResId); + mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); + afd.close(); + } else { + Log.e(TAG, "Playing file: "+mFileName); + mMediaPlayer.setDataSource(mFileName); + } + mMediaPlayer.setAudioStreamType(mStreamType); + mMediaPlayer.prepare(); + mMediaPlayer.setLooping(true); + } catch (Exception ex) { + Log.e(TAG, "mMediaPlayercreate failed:", ex); + mMediaPlayer.release(); + mMediaPlayer = null; + } + + if (mMediaPlayer != null) { + mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override + public void onCompletion(MediaPlayer mp) { + updatePlayPauseButton(); + } + }); + } + } + if (mMediaPlayer != null) { + mMediaPlayer.start(); + } + } else { + mMediaPlayer.pause(); + } + updatePlayPauseButton(); + } + @Override + public void stop() { + if (mMediaPlayer != null) { + mMediaPlayer.stop(); + mMediaPlayer.release(); + mMediaPlayer = null; + } + updatePlayPauseButton(); + } + + @Override + public boolean isPlaying() { + if (mMediaPlayer != null) { + return mMediaPlayer.isPlaying(); + } else { + return false; + } + } + } + + private class SimpleRecordController extends SimpleMediaController { + private MediaRecorder mMediaRecorder; + private int mFileCount = 0; + private int mState = 0; + SimpleRecordController(Context context, int playPausebuttonId, int stopButtonId, String fileName) { + super(context, playPausebuttonId, stopButtonId, fileName); + Log.e(TAG, "SimpleRecordController cstor"); + mPlayImageResource = R.drawable.record; + mPauseImageResource = R.drawable.stop; + } + + @Override + public void playOrPause() { + if (mState == 0) { + setup(); + try { + mMediaRecorder.start(); + mState = 1; + } catch (Exception e) { + Log.e(TAG, "Could start MediaRecorder: " + e.toString()); + mMediaRecorder.release(); + mMediaRecorder = null; + mState = 0; + } + } else { + try { + mMediaRecorder.stop(); + mMediaRecorder.reset(); + } catch (Exception e) { + Log.e(TAG, "Could not stop MediaRecorder: " + e.toString()); + mMediaRecorder.release(); + mMediaRecorder = null; + } finally { + mState = 0; + } + } + updatePlayPauseButton(); + } + + public void setup() { + Log.e(TAG, "SimpleRecordController setup()"); + if (mMediaRecorder == null) { + mMediaRecorder = new MediaRecorder(); + } + mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); + mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); + mFileName = Environment.getExternalStorageDirectory().toString() + "/music/" + + mFileNameBase + "_" + ++mFileCount + ".amr"; + mLastRecordedFile = mFileName; + Log.e(TAG, "recording to file: "+mLastRecordedFile); + mMediaRecorder.setOutputFile(mFileName); + try { + mMediaRecorder.prepare(); + } + catch (Exception e) { + Log.e(TAG, "Could not prepare MediaRecorder: " + e.toString()); + mMediaRecorder.release(); + mMediaRecorder = null; + } + } + + @Override + public void stop() { + if (mMediaRecorder != null) { + mMediaRecorder.stop(); + mMediaRecorder.release(); + mMediaRecorder = null; + } + updatePlayPauseButton(); + } + + @Override + public boolean isPlaying() { + if (mState == 1) { + return true; + } else { + return false; + } + } + } + + class TtsInitListener implements TextToSpeech.OnInitListener { + @Override + public void onInit(int status) { + // status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR. + Log.e(TAG, "onInit for tts"); + if (status != TextToSpeech.SUCCESS) { + // Initialization failed. + Log.e(TAG, "Could not initialize TextToSpeech."); + return; + } + + if (mTts == null) { + Log.e(TAG, "null tts"); + return; + } + + int result = mTts.setLanguage(Locale.US); + if (result == TextToSpeech.LANG_MISSING_DATA || + result == TextToSpeech.LANG_NOT_SUPPORTED) { + // Lanuage data is missing or the language is not supported. + Log.e(TAG, "Language is not available."); + return; + } + mTts.setOnUtteranceCompletedListener(new MyUtteranceCompletedListener(UTTERANCE)); + mTtsInited = true; + } + } + + class MyUtteranceCompletedListener implements OnUtteranceCompletedListener { + private final String mExpectedUtterance; + + public MyUtteranceCompletedListener(String expectedUtteranceId) { + mExpectedUtterance = expectedUtteranceId; + } + + @Override + public void onUtteranceCompleted(String utteranceId) { + Log.e(TAG, "onUtteranceCompleted " + utteranceId); + if (mTtsToFile) { + if (mSampleFile != null && mSampleFile.exists()) { + MediaPlayer mediaPlayer = new MediaPlayer(); + try { + mediaPlayer.setDataSource(mSampleFile.getPath()); + mediaPlayer.setAudioStreamType(AudioManager.STREAM_BLUETOOTH_SCO); + mediaPlayer.prepare(); + } catch (Exception ex) { + Log.e(TAG, "mMediaPlayercreate failed:", ex); + mediaPlayer.release(); + mediaPlayer = null; + } + + if (mediaPlayer != null) { + mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override + public void onCompletion(MediaPlayer mp) { + mp.release(); + if (mSampleFile != null && mSampleFile.exists()) { + mSampleFile.delete(); + mSampleFile = null; + } + mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO, + mOriginalVoiceVolume, 0); +// Debug.stopMethodTracing(); + } + }); + mediaPlayer.start(); + } + } else { + Log.e(TAG, "synthesizeToFile did not create file"); + } + } else { + mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO, + mOriginalVoiceVolume, 0); +// Debug.stopMethodTracing(); + } + + Log.e(TAG, "end speak, volume: "+mOriginalVoiceVolume); + } + } + + + private View.OnKeyListener mSpeakKeyListener + = new View.OnKeyListener() { + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_DOWN) { + switch (keyCode) { + case KeyEvent.KEYCODE_DPAD_CENTER: + case KeyEvent.KEYCODE_ENTER: + if (!mTtsInited) { + Log.e(TAG, "Tts not inited "); + return false; + } + mOriginalVoiceVolume = mAudioManager.getStreamVolume( + AudioManager.STREAM_BLUETOOTH_SCO); + Log.e(TAG, "start speak, volume: "+mOriginalVoiceVolume); + mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO, + mOriginalVoiceVolume/2, 0); + + // we now have SCO connection and TTS, so we can start. + mHandler.post(new Runnable() { + @Override + public void run() { +// Debug.startMethodTracing("tts"); + + if (mTtsToFile) { + if (mSampleFile != null && mSampleFile.exists()) { + mSampleFile.delete(); + mSampleFile = null; + } + mSampleFile = new File(Environment.getExternalStorageDirectory(), "mytts.wav"); + mTts.synthesizeToFile(mSpeakText.getText().toString(), mTtsParams, mSampleFile.getPath()); + } else { + mTts.speak(mSpeakText.getText().toString(), + TextToSpeech.QUEUE_FLUSH, + mTtsParams); + } + } + }); + return true; + } + } + return false; + } + }; + + private static final String[] mModeStrings = { + "NORMAL", "RINGTONE", "IN_CALL", "IN_COMMUNICATION" + }; + + private Spinner.OnItemSelectedListener mModeChanged + = new Spinner.OnItemSelectedListener() { + @Override + public void onItemSelected(android.widget.AdapterView av, View v, + int position, long id) { + if (mCurrentMode != position) { + mCurrentMode = position; + mAudioManager.setMode(mCurrentMode); + } + } + + @Override + public void onNothingSelected(android.widget.AdapterView av) { + } + }; + + private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = + new BluetoothProfile.ServiceListener() { + @Override + public void onServiceConnected(int profile, BluetoothProfile proxy) { + mBluetoothHeadset = (BluetoothHeadset) proxy; + List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices(); + if (deviceList.size() > 0) { + mBluetoothHeadsetDevice = deviceList.get(0); + } else { + mBluetoothHeadsetDevice = null; + } + } + @Override + public void onServiceDisconnected(int profile) { + if (mBluetoothHeadset != null) { + List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices(); + if (devices.size() == 0) { + mBluetoothHeadsetDevice = null; + } + mBluetoothHeadset = null; + } + } + }; + + private int mChangedState = -1; + private int mUpdatedState = -1; + private int mUpdatedPrevState = -1; + + private class ScoBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + + if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { + int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); + mVdStateTxt.setText(Integer.toString(state)); + Log.e(TAG, "BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED: "+state); + } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED)) { + mChangedState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1); + Log.e(TAG, "ACTION_SCO_AUDIO_STATE_CHANGED: "+mChangedState); + mScoStateTxt.setText("changed: "+Integer.toString(mChangedState)+ + " updated: "+Integer.toString(mUpdatedState)+ + " prev updated: "+Integer.toString(mUpdatedPrevState)); + } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) { + mUpdatedState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1); + mUpdatedPrevState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE, -1); + Log.e(TAG, "ACTION_SCO_AUDIO_STATE_UPDATED, state: "+mUpdatedState+" prev state: "+mUpdatedPrevState); + mScoStateTxt.setText("changed: "+Integer.toString(mChangedState)+ + " updated: "+Integer.toString(mUpdatedState)+ + " prev updated: "+Integer.toString(mUpdatedPrevState)); + if (mForceScoOn && mUpdatedState == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) { + mForceScoOn = false; + mScoButton.setChecked(mForceScoOn); + mAudioManager.stopBluetoothSco(); + } + } + } + } + +} |