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