1ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen/*
2ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * Copyright (C) 2009 The Android Open Source Project
3ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen *
4ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * Licensed under the Apache License, Version 2.0 (the "License");
5ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * you may not use this file except in compliance with the License.
6ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * You may obtain a copy of the License at
7ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen *
8ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen *      http://www.apache.org/licenses/LICENSE-2.0
9ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen *
10ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * Unless required by applicable law or agreed to in writing, software
11ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * distributed under the License is distributed on an "AS IS" BASIS,
12ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * See the License for the specific language governing permissions and
14ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * limitations under the License.
15ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen */
16ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
17ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenpackage com.android.scoaudiotest;
18ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
19ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.app.Activity;
20ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.bluetooth.BluetoothAdapter;
21ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.bluetooth.BluetoothDevice;
22ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.bluetooth.BluetoothHeadset;
23ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.bluetooth.BluetoothProfile;
24ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.content.BroadcastReceiver;
25ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.content.Context;
26ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.content.Intent;
27ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.content.IntentFilter;
28ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.content.res.AssetFileDescriptor;
29ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.media.AudioManager;
30ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.media.MediaPlayer;
31ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.media.MediaRecorder;
32ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.os.Bundle;
33ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.os.Environment;
34ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.os.Handler;
35ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.speech.tts.TextToSpeech;
36ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
37ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.util.Log;
38ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.view.KeyEvent;
39ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.view.View;
40ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.view.View.OnClickListener;
41ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.ArrayAdapter;
42ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.CheckBox;
43ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.CompoundButton;
44ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.CompoundButton.OnCheckedChangeListener;
45ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.EditText;
46ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.ImageButton;
47ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.ImageView;
48ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.Spinner;
49ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.TextView;
50ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.ToggleButton;
51ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
52ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport java.io.File;
53ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport java.util.HashMap;
54ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport java.util.List;
55ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport java.util.Locale;
56ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
57ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenpublic class ScoAudioTest extends Activity {
58ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
59ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    final static String TAG = "ScoAudioTest";
60ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
61ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    AudioManager mAudioManager;
62ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    AudioManager mAudioManager2;
63ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    boolean mForceScoOn;
64ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    ToggleButton mScoButton;
65ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    ToggleButton mVoiceDialerButton;
66ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    boolean mVoiceDialerOn;
67ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    String mLastRecordedFile;
68ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    SimpleMediaController mMediaControllers[] = new SimpleMediaController[2];
69ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private TextToSpeech mTts;
70ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private HashMap<String, String> mTtsParams;
71ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private int mOriginalVoiceVolume;
72ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    EditText mSpeakText;
73ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    boolean mTtsInited;
74ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private Handler mHandler;
75ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private static final String UTTERANCE = "utterance";
76ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private static Intent sVoiceCommandIntent;
77ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private File mSampleFile;
78ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    ToggleButton mTtsToFileButton;
79ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private boolean mTtsToFile;
80ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private int mCurrentMode;
81ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    Spinner mModeSpinner;
82ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private BluetoothHeadset mBluetoothHeadset;
83ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private BluetoothDevice mBluetoothHeadsetDevice;
84ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    TextView mScoStateTxt;
85ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    TextView mVdStateTxt;
86ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
87ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private final BroadcastReceiver mReceiver = new ScoBroadcastReceiver();
88ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
89ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    public ScoAudioTest() {
90ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        Log.e(TAG, "contructor");
91ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
92ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
93ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    /** Called when the activity is first created. */
94ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    @Override
95ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    public void onCreate(Bundle icicle) {
96ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        super.onCreate(icicle);
97ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
98ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        setContentView(R.layout.scoaudiotest);
99ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
100ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mScoStateTxt = (TextView) findViewById(R.id.scoStateTxt);
101ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mVdStateTxt = (TextView) findViewById(R.id.vdStateTxt);
102ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
103ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        IntentFilter intentFilter =
104ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
105ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED);
106ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
107ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        registerReceiver(mReceiver, intentFilter);
108ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
109ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
110ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mAudioManager2 = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
111ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mHandler = new Handler();
112ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
113ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mMediaControllers[0] = new SimplePlayerController(this, R.id.playPause1, R.id.stop1,
114ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                R.raw.sine440_mo_16b_16k, AudioManager.STREAM_BLUETOOTH_SCO);
115ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        TextView name = (TextView) findViewById(R.id.playPause1Text);
116ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        name.setText("VOICE_CALL stream");
117ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
118ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mScoButton = (ToggleButton)findViewById(R.id.ForceScoButton);
119ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mScoButton.setOnCheckedChangeListener(mForceScoChanged);
120ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mForceScoOn = false;
121ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mScoButton.setChecked(mForceScoOn);
122ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
123ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mVoiceDialerButton = (ToggleButton)findViewById(R.id.VoiceDialerButton);
124ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mVoiceDialerButton.setOnCheckedChangeListener(mVoiceDialerChanged);
125ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mVoiceDialerOn = false;
126ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mVoiceDialerButton.setChecked(mVoiceDialerOn);
127ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
128ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
129ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mMediaControllers[1] = new SimpleRecordController(this, R.id.recStop1, 0, "Sco_record_");
130ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsInited = false;
131ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTts = new TextToSpeech(this, new TtsInitListener());
132ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsParams = new HashMap<String, String>();
133ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsParams.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
134ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                String.valueOf(AudioManager.STREAM_BLUETOOTH_SCO));
135ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsParams.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,
136ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                UTTERANCE);
137ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
138ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mSpeakText = (EditText) findViewById(R.id.speakTextEdit);
139ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mSpeakText.setOnKeyListener(mSpeakKeyListener);
140ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mSpeakText.setText("sco audio test sentence");
141ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsToFileButton = (ToggleButton)findViewById(R.id.TtsToFileButton);
142ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsToFileButton.setOnCheckedChangeListener(mTtsToFileChanged);
143ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsToFile = true;
144ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsToFileButton.setChecked(mTtsToFile);
145ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
146ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mModeSpinner = (Spinner) findViewById(R.id.modeSpinner);
147ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
148ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                android.R.layout.simple_spinner_item, mModeStrings);
149ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
150ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mModeSpinner.setAdapter(adapter);
151ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mModeSpinner.setOnItemSelectedListener(mModeChanged);
152ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mCurrentMode = mAudioManager.getMode();
153ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mModeSpinner.setSelection(mCurrentMode);
154ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
155ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mBluetoothHeadsetDevice = null;
156ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
157ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        if (btAdapter != null) {
158ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            btAdapter.getProfileProxy(this, mBluetoothProfileServiceListener,
159ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    BluetoothProfile.HEADSET);
160ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
161ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
162ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        sVoiceCommandIntent = new Intent(Intent.ACTION_VOICE_COMMAND);
163ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        sVoiceCommandIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
164ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
165ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
166ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    @Override
167ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    public void onDestroy() {
168ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        super.onDestroy();
169ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTts.shutdown();
170ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        unregisterReceiver(mReceiver);
171ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        if (mBluetoothHeadset != null) {
172ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
173ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (btAdapter != null) {
174ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                btAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
175ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
176ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
177ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
178ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
179ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    @Override
180ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    protected void onPause() {
181ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        super.onPause();
182ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen//        mForceScoOn = false;
183ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen//        mScoButton.setChecked(mForceScoOn);
184ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mMediaControllers[0].stop();
185ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mMediaControllers[1].stop();
186ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
187ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mOriginalVoiceVolume, 0);
188ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
189ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
190ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    @Override
191ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    protected void onResume() {
192ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        super.onResume();
193ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mLastRecordedFile = "";
194ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mMediaControllers[0].mFileName = "";
195ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mOriginalVoiceVolume = mAudioManager.getStreamVolume(
196ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                AudioManager.STREAM_BLUETOOTH_SCO);
197ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        setVolumeControlStream(AudioManager.STREAM_BLUETOOTH_SCO);
198ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mCurrentMode = mAudioManager.getMode();
199ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mModeSpinner.setSelection(mCurrentMode);
200ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
201ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
202ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private OnCheckedChangeListener mForceScoChanged
203ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    = new OnCheckedChangeListener(){
204ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
205ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onCheckedChanged(CompoundButton buttonView,
206ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                boolean isChecked) {
207ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mForceScoOn != isChecked) {
208ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mForceScoOn = isChecked;
209ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                AudioManager mngr = mAudioManager;
210ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                CheckBox box = (CheckBox) findViewById(R.id.useSecondAudioManager);
211ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (box.isChecked()) {
212ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.i(TAG, "Using 2nd audio manager");
213ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mngr = mAudioManager2;
214ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
215ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
216ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mForceScoOn) {
217ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.e(TAG, "startBluetoothSco() IN");
218ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mngr.startBluetoothSco();
219ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.e(TAG, "startBluetoothSco() OUT");
220ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                } else {
221ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.e(TAG, "stopBluetoothSco() IN");
222ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mngr.stopBluetoothSco();
223ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.e(TAG, "stopBluetoothSco() OUT");
224ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
225ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
226ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
227ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
228ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
229ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private OnCheckedChangeListener mVoiceDialerChanged
230ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    = new OnCheckedChangeListener(){
231ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
232ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onCheckedChanged(CompoundButton buttonView,
233ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                boolean isChecked) {
234ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mVoiceDialerOn != isChecked) {
235ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mVoiceDialerOn = isChecked;
236ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
237ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    if (mVoiceDialerOn) {
238ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mBluetoothHeadset.startVoiceRecognition(mBluetoothHeadsetDevice);
239ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    } else {
240ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mBluetoothHeadset.stopVoiceRecognition(mBluetoothHeadsetDevice);
241ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
242ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
243ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
244ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
245ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
246ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
247ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private OnCheckedChangeListener mTtsToFileChanged
248ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    = new OnCheckedChangeListener(){
249ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
250ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onCheckedChanged(CompoundButton buttonView,
251ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                boolean isChecked) {
252ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mTtsToFile = isChecked;
253ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
254ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
255ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
256ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private class SimpleMediaController implements OnClickListener {
257ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        int mPlayPauseButtonId;
258ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        int mStopButtonId;
259ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        Context mContext;
260ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        ImageView mPlayPauseButton;
261ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        int mPlayImageResource;
262ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        int mPauseImageResource;
263ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        String mFileNameBase;
264ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        String mFileName;
265ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        int mFileResId;
266ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
267ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        SimpleMediaController(Context context, int playPausebuttonId, int stopButtonId, String fileName) {
268ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mContext = context;
269ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButtonId = playPausebuttonId;
270ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mStopButtonId = stopButtonId;
271ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileNameBase = fileName;
272ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton = (ImageButton) findViewById(playPausebuttonId);
273ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            ImageButton stop = (ImageButton) findViewById(stopButtonId);
274ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
275ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton.setOnClickListener(this);
276ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton.requestFocus();
277ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (stop != null) {
278ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                stop.setOnClickListener(this);
279ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
280ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
281ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
282ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        SimpleMediaController(Context context, int playPausebuttonId, int stopButtonId, int fileResId) {
283ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mContext = context;
284ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButtonId = playPausebuttonId;
285ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mStopButtonId = stopButtonId;
286ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileNameBase = "";
287ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileResId = fileResId;
288ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton = (ImageButton) findViewById(playPausebuttonId);
289ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            ImageButton stop = (ImageButton) findViewById(stopButtonId);
290ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
291ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton.setOnClickListener(this);
292ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton.requestFocus();
293ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (stop != null) {
294ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                stop.setOnClickListener(this);
295ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
296ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
297ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
298ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
299ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onClick(View v) {
300ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (v.getId() == mPlayPauseButtonId) {
301ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                playOrPause();
302ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else if (v.getId() == mStopButtonId) {
303ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                stop();
304ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
305ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
306ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
307ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void playOrPause() {
308ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
309ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
310ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void stop() {
311ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
312ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
313ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public boolean isPlaying() {
314ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            return false;
315ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
316ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
317ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void updatePlayPauseButton() {
318ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton.setImageResource(isPlaying() ? mPauseImageResource : mPlayImageResource);
319ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
320ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
321ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
322ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private class SimplePlayerController extends SimpleMediaController {
323ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private MediaPlayer mMediaPlayer;
324ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private int mStreamType;
325ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        SimplePlayerController(Context context, int playPausebuttonId, int stopButtonId, String fileName, int stream) {
326ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            super(context, playPausebuttonId, stopButtonId, fileName);
327ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
328ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayImageResource = android.R.drawable.ic_media_play;
329ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPauseImageResource = android.R.drawable.ic_media_pause;
330ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mStreamType = stream;
331ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileName = Environment.getExternalStorageDirectory().toString() + "/music/" +
332ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mFileNameBase + "_" + ".wav";
333ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
334ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
335ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        SimplePlayerController(Context context, int playPausebuttonId, int stopButtonId, int fileResId, int stream) {
336ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            super(context, playPausebuttonId, stopButtonId, fileResId);
337ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
338ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayImageResource = android.R.drawable.ic_media_play;
339ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPauseImageResource = android.R.drawable.ic_media_pause;
340ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mStreamType = stream;
341ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileName = "";
342ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
343ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
344ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
345ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void playOrPause() {
346ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "playOrPause playing: "+((mMediaPlayer == null)?false:!mMediaPlayer.isPlaying())+
347ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    " mMediaPlayer: "+mMediaPlayer+
348ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    " mFileName: "+mFileName+
349ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    " mLastRecordedFile: "+mLastRecordedFile);
350ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mMediaPlayer == null || !mMediaPlayer.isPlaying()){
351ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mMediaPlayer == null) {
352ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    if (mFileName != mLastRecordedFile) {
353ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mFileName = mLastRecordedFile;
354ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        Log.e(TAG, "new recorded file: "+mFileName);
355ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
356ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    try {
357ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer = new MediaPlayer();
358ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        if (mFileName.equals("")) {
359ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            Log.e(TAG, "Playing from resource");
360ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(mFileResId);
361ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
362ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            afd.close();
363ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        } else {
364ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            Log.e(TAG, "Playing file: "+mFileName);
365ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            mMediaPlayer.setDataSource(mFileName);
366ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        }
367ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer.setAudioStreamType(mStreamType);
368ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer.prepare();
369ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer.setLooping(true);
370ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    } catch (Exception ex) {
371ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        Log.e(TAG, "mMediaPlayercreate failed:", ex);
372ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer.release();
373ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer = null;
374ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
375ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
376ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    if (mMediaPlayer != null) {
377ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
378ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            @Override
379ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            public void onCompletion(MediaPlayer mp) {
380ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                updatePlayPauseButton();
381ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            }
382ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        });
383ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
384ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
385ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mMediaPlayer != null) {
386ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaPlayer.start();
387ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
388ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
389ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaPlayer.pause();
390ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
391ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            updatePlayPauseButton();
392ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
393ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
394ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void stop() {
395ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mMediaPlayer != null) {
396ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaPlayer.stop();
397ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaPlayer.release();
398ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaPlayer = null;
399ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
400ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            updatePlayPauseButton();
401ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
402ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
403ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
404ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public boolean isPlaying() {
405ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mMediaPlayer != null) {
406ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return mMediaPlayer.isPlaying();
407ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
408ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return false;
409ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
410ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
411ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
412ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
413ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private class SimpleRecordController extends SimpleMediaController {
414ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private MediaRecorder mMediaRecorder;
415ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private int mFileCount = 0;
416ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private int mState = 0;
417ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        SimpleRecordController(Context context, int playPausebuttonId, int stopButtonId, String fileName) {
418ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            super(context, playPausebuttonId, stopButtonId, fileName);
419ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "SimpleRecordController cstor");
420ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayImageResource = R.drawable.record;
421ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPauseImageResource = R.drawable.stop;
422ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
423ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
424ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
425ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void playOrPause() {
426ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mState == 0) {
427ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                setup();
428ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                try {
429ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder.start();
430ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mState = 1;
431ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                } catch (Exception e) {
432ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.e(TAG, "Could start MediaRecorder: " + e.toString());
433ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder.release();
434ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder = null;
435ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mState = 0;
436ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
437ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
438ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                try {
439ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder.stop();
440ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder.reset();
441ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                } catch (Exception e) {
442ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.e(TAG, "Could not stop MediaRecorder: " + e.toString());
443ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder.release();
444ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder = null;
445ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                } finally {
446ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mState = 0;
447ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
448ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
449ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            updatePlayPauseButton();
450ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
451ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
452ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void setup() {
453ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "SimpleRecordController setup()");
454ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mMediaRecorder == null) {
455ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaRecorder = new MediaRecorder();
456ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
457ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
458ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
459ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
460ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileName = Environment.getExternalStorageDirectory().toString() + "/music/" +
461ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mFileNameBase + "_" + ++mFileCount + ".amr";
462ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mLastRecordedFile = mFileName;
463ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "recording to file: "+mLastRecordedFile);
464ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mMediaRecorder.setOutputFile(mFileName);
465ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            try {
466ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaRecorder.prepare();
467ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
468ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            catch (Exception e) {
469ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "Could not prepare MediaRecorder: " + e.toString());
470ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaRecorder.release();
471ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaRecorder = null;
472ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
473ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
474ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
475ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
476ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void stop() {
477ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mMediaRecorder != null) {
478ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaRecorder.stop();
479ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaRecorder.release();
480ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaRecorder = null;
481ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
482ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            updatePlayPauseButton();
483ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
484ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
485ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
486ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public boolean isPlaying() {
487ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mState == 1) {
488ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return true;
489ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
490ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return false;
491ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
492ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
493ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
494ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
495ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    class TtsInitListener implements TextToSpeech.OnInitListener {
496ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
497ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onInit(int status) {
498ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            // status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR.
499ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "onInit for tts");
500ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (status != TextToSpeech.SUCCESS) {
501ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                // Initialization failed.
502ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "Could not initialize TextToSpeech.");
503ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return;
504ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
505ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
506ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mTts == null) {
507ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "null tts");
508ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return;
509ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
510ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
511ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            int result = mTts.setLanguage(Locale.US);
512ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (result == TextToSpeech.LANG_MISSING_DATA ||
513ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                result == TextToSpeech.LANG_NOT_SUPPORTED) {
514ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen               // Lanuage data is missing or the language is not supported.
515ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "Language is not available.");
516ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return;
517ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
518ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mTts.setOnUtteranceCompletedListener(new MyUtteranceCompletedListener(UTTERANCE));
519ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mTtsInited = true;
520ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen         }
521ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
522ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
523ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    class MyUtteranceCompletedListener implements OnUtteranceCompletedListener {
524ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private final String mExpectedUtterance;
525ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
526ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public MyUtteranceCompletedListener(String expectedUtteranceId) {
527ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mExpectedUtterance = expectedUtteranceId;
528ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
529ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
530ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
531ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onUtteranceCompleted(String utteranceId) {
532ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "onUtteranceCompleted " + utteranceId);
533ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mTtsToFile) {
534ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mSampleFile != null && mSampleFile.exists()) {
535ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    MediaPlayer mediaPlayer = new MediaPlayer();
536ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    try {
537ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.setDataSource(mSampleFile.getPath());
538ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.setAudioStreamType(AudioManager.STREAM_BLUETOOTH_SCO);
539ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.prepare();
540ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    } catch (Exception ex) {
541ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        Log.e(TAG, "mMediaPlayercreate failed:", ex);
542ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.release();
543ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer = null;
544ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
545ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
546ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    if (mediaPlayer != null) {
547ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
548ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            @Override
549ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            public void onCompletion(MediaPlayer mp) {
550ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                mp.release();
551ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                if (mSampleFile != null && mSampleFile.exists()) {
552ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    mSampleFile.delete();
553ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    mSampleFile = null;
554ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                }
555ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                              mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
556ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                              mOriginalVoiceVolume, 0);
557ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen//                              Debug.stopMethodTracing();
558ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            }
559ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        });
560ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.start();
561ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
562ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                } else {
563ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.e(TAG, "synthesizeToFile did not create file");
564ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
565ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
566ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
567ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mOriginalVoiceVolume, 0);
568ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen//                Debug.stopMethodTracing();
569ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
570ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
571ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "end speak, volume: "+mOriginalVoiceVolume);
572ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
573ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
574ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
575ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
576ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private View.OnKeyListener mSpeakKeyListener
577ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    = new View.OnKeyListener() {
578ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
579ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public boolean onKey(View v, int keyCode, KeyEvent event) {
580ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (event.getAction() == KeyEvent.ACTION_DOWN) {
581ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                switch (keyCode) {
582ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    case KeyEvent.KEYCODE_DPAD_CENTER:
583ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    case KeyEvent.KEYCODE_ENTER:
584ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        if (!mTtsInited) {
585ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            Log.e(TAG, "Tts not inited ");
586ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            return false;
587ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        }
588ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mOriginalVoiceVolume = mAudioManager.getStreamVolume(
589ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                AudioManager.STREAM_BLUETOOTH_SCO);
590ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        Log.e(TAG, "start speak, volume: "+mOriginalVoiceVolume);
591ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
592ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                mOriginalVoiceVolume/2, 0);
593ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
594ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        // we now have SCO connection and TTS, so we can start.
595ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mHandler.post(new Runnable() {
596ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            @Override
597ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            public void run() {
598ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen//                                Debug.startMethodTracing("tts");
599ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
600ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                if (mTtsToFile) {
601ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    if (mSampleFile != null && mSampleFile.exists()) {
602ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                        mSampleFile.delete();
603ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                        mSampleFile = null;
604ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    }
605ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    mSampleFile = new File(Environment.getExternalStorageDirectory(), "mytts.wav");
606ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    mTts.synthesizeToFile(mSpeakText.getText().toString(), mTtsParams, mSampleFile.getPath());
607ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                } else {
608ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    mTts.speak(mSpeakText.getText().toString(),
609ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                        TextToSpeech.QUEUE_FLUSH,
610ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                        mTtsParams);
611ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                }
612ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            }
613ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        });
614ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        return true;
615ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
616ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
617ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            return false;
618ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
619ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
620ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
621ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private static final String[] mModeStrings = {
622ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        "NORMAL", "RINGTONE", "IN_CALL", "IN_COMMUNICATION"
623ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
624ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
625ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private Spinner.OnItemSelectedListener mModeChanged
626ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        = new Spinner.OnItemSelectedListener() {
627ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
628ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onItemSelected(android.widget.AdapterView av, View v,
629ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    int position, long id) {
630ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mCurrentMode != position) {
631ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mCurrentMode = position;
632ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mAudioManager.setMode(mCurrentMode);
633ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
634ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
635ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
636ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
637ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onNothingSelected(android.widget.AdapterView av) {
638ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
639ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
640ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
641ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
642ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        new BluetoothProfile.ServiceListener() {
643ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
644ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onServiceConnected(int profile, BluetoothProfile proxy) {
645ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mBluetoothHeadset = (BluetoothHeadset) proxy;
646ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
647ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (deviceList.size() > 0) {
648ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mBluetoothHeadsetDevice = deviceList.get(0);
649ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
650ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mBluetoothHeadsetDevice = null;
651ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
652ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
653ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
654ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onServiceDisconnected(int profile) {
655ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mBluetoothHeadset != null) {
656ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
657ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (devices.size() == 0) {
658ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mBluetoothHeadsetDevice = null;
659ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
660ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mBluetoothHeadset = null;
661ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
662ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
663ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
664ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
665ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private int mChangedState = -1;
666ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private int mUpdatedState = -1;
667ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private int mUpdatedPrevState = -1;
668ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
669ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private class ScoBroadcastReceiver extends BroadcastReceiver {
670ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
671ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onReceive(Context context, Intent intent) {
672ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            String action = intent.getAction();
673ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
674ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
675ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
676ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mVdStateTxt.setText(Integer.toString(state));
677ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED: "+state);
678ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED)) {
679ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mChangedState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
680ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "ACTION_SCO_AUDIO_STATE_CHANGED: "+mChangedState);
681ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mScoStateTxt.setText("changed: "+Integer.toString(mChangedState)+
682ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        " updated: "+Integer.toString(mUpdatedState)+
683ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        " prev updated: "+Integer.toString(mUpdatedPrevState));
684ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
685ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mUpdatedState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
686ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mUpdatedPrevState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE, -1);
687ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "ACTION_SCO_AUDIO_STATE_UPDATED, state: "+mUpdatedState+" prev state: "+mUpdatedPrevState);
688ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mScoStateTxt.setText("changed: "+Integer.toString(mChangedState)+
689ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        " updated: "+Integer.toString(mUpdatedState)+
690ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        " prev updated: "+Integer.toString(mUpdatedPrevState));
691ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mForceScoOn && mUpdatedState == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
692ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mForceScoOn = false;
693ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mScoButton.setChecked(mForceScoOn);
694ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mAudioManager.stopBluetoothSco();
695ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
696ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
697ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
698ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
699ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
700ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen}
701