blob: 0304640345169dd99acfbb13343842a20a91bfd3 [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) {
Eric Laurent1b7dba82013-04-19 17:25:03 -0700432 Log.e(TAG, "Could start MediaRecorder: ", e);
Marco Nelissenef02abd2011-08-11 10:41:33 -0700433 mMediaRecorder.release();
434 mMediaRecorder = null;
435 mState = 0;
436 }
437 } else {
438 try {
439 mMediaRecorder.stop();
440 mMediaRecorder.reset();
441 } catch (Exception e) {
Eric Laurent1b7dba82013-04-19 17:25:03 -0700442 Log.e(TAG, "Could not stop MediaRecorder: ", e);
Marco Nelissenef02abd2011-08-11 10:41:33 -0700443 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) {
Eric Laurent1b7dba82013-04-19 17:25:03 -0700469 Log.e(TAG, "Could not prepare MediaRecorder: ", e);
Marco Nelissenef02abd2011-08-11 10:41:33 -0700470 mMediaRecorder.release();
471 mMediaRecorder = null;
472 }
473 }
474
475 @Override
476 public void stop() {
477 if (mMediaRecorder != null) {
Eric Laurent1b7dba82013-04-19 17:25:03 -0700478 try {
479 mMediaRecorder.stop();
480 } catch (Exception e) {
481 Log.e(TAG, "Could not stop MediaRecorder: ", e);
482 } finally {
483 mMediaRecorder.release();
484 mMediaRecorder = null;
485 }
Marco Nelissenef02abd2011-08-11 10:41:33 -0700486 }
487 updatePlayPauseButton();
488 }
489
490 @Override
491 public boolean isPlaying() {
492 if (mState == 1) {
493 return true;
494 } else {
495 return false;
496 }
497 }
498 }
499
500 class TtsInitListener implements TextToSpeech.OnInitListener {
501 @Override
502 public void onInit(int status) {
503 // status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR.
504 Log.e(TAG, "onInit for tts");
505 if (status != TextToSpeech.SUCCESS) {
506 // Initialization failed.
507 Log.e(TAG, "Could not initialize TextToSpeech.");
508 return;
509 }
510
511 if (mTts == null) {
512 Log.e(TAG, "null tts");
513 return;
514 }
515
516 int result = mTts.setLanguage(Locale.US);
517 if (result == TextToSpeech.LANG_MISSING_DATA ||
518 result == TextToSpeech.LANG_NOT_SUPPORTED) {
519 // Lanuage data is missing or the language is not supported.
520 Log.e(TAG, "Language is not available.");
521 return;
522 }
523 mTts.setOnUtteranceCompletedListener(new MyUtteranceCompletedListener(UTTERANCE));
524 mTtsInited = true;
525 }
526 }
527
528 class MyUtteranceCompletedListener implements OnUtteranceCompletedListener {
529 private final String mExpectedUtterance;
530
531 public MyUtteranceCompletedListener(String expectedUtteranceId) {
532 mExpectedUtterance = expectedUtteranceId;
533 }
534
535 @Override
536 public void onUtteranceCompleted(String utteranceId) {
537 Log.e(TAG, "onUtteranceCompleted " + utteranceId);
538 if (mTtsToFile) {
539 if (mSampleFile != null && mSampleFile.exists()) {
540 MediaPlayer mediaPlayer = new MediaPlayer();
541 try {
542 mediaPlayer.setDataSource(mSampleFile.getPath());
543 mediaPlayer.setAudioStreamType(AudioManager.STREAM_BLUETOOTH_SCO);
544 mediaPlayer.prepare();
545 } catch (Exception ex) {
546 Log.e(TAG, "mMediaPlayercreate failed:", ex);
547 mediaPlayer.release();
548 mediaPlayer = null;
549 }
550
551 if (mediaPlayer != null) {
552 mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
553 @Override
554 public void onCompletion(MediaPlayer mp) {
555 mp.release();
556 if (mSampleFile != null && mSampleFile.exists()) {
557 mSampleFile.delete();
558 mSampleFile = null;
559 }
560 mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
561 mOriginalVoiceVolume, 0);
562// Debug.stopMethodTracing();
563 }
564 });
565 mediaPlayer.start();
566 }
567 } else {
568 Log.e(TAG, "synthesizeToFile did not create file");
569 }
570 } else {
571 mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
572 mOriginalVoiceVolume, 0);
573// Debug.stopMethodTracing();
574 }
575
576 Log.e(TAG, "end speak, volume: "+mOriginalVoiceVolume);
577 }
578 }
579
580
581 private View.OnKeyListener mSpeakKeyListener
582 = new View.OnKeyListener() {
583 @Override
584 public boolean onKey(View v, int keyCode, KeyEvent event) {
585 if (event.getAction() == KeyEvent.ACTION_DOWN) {
586 switch (keyCode) {
587 case KeyEvent.KEYCODE_DPAD_CENTER:
588 case KeyEvent.KEYCODE_ENTER:
589 if (!mTtsInited) {
590 Log.e(TAG, "Tts not inited ");
591 return false;
592 }
593 mOriginalVoiceVolume = mAudioManager.getStreamVolume(
594 AudioManager.STREAM_BLUETOOTH_SCO);
595 Log.e(TAG, "start speak, volume: "+mOriginalVoiceVolume);
596 mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
597 mOriginalVoiceVolume/2, 0);
598
599 // we now have SCO connection and TTS, so we can start.
600 mHandler.post(new Runnable() {
601 @Override
602 public void run() {
603// Debug.startMethodTracing("tts");
604
605 if (mTtsToFile) {
606 if (mSampleFile != null && mSampleFile.exists()) {
607 mSampleFile.delete();
608 mSampleFile = null;
609 }
610 mSampleFile = new File(Environment.getExternalStorageDirectory(), "mytts.wav");
611 mTts.synthesizeToFile(mSpeakText.getText().toString(), mTtsParams, mSampleFile.getPath());
612 } else {
613 mTts.speak(mSpeakText.getText().toString(),
614 TextToSpeech.QUEUE_FLUSH,
615 mTtsParams);
616 }
617 }
618 });
619 return true;
620 }
621 }
622 return false;
623 }
624 };
625
626 private static final String[] mModeStrings = {
627 "NORMAL", "RINGTONE", "IN_CALL", "IN_COMMUNICATION"
628 };
629
630 private Spinner.OnItemSelectedListener mModeChanged
631 = new Spinner.OnItemSelectedListener() {
632 @Override
633 public void onItemSelected(android.widget.AdapterView av, View v,
634 int position, long id) {
635 if (mCurrentMode != position) {
636 mCurrentMode = position;
637 mAudioManager.setMode(mCurrentMode);
638 }
639 }
640
641 @Override
642 public void onNothingSelected(android.widget.AdapterView av) {
643 }
644 };
645
646 private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
647 new BluetoothProfile.ServiceListener() {
648 @Override
649 public void onServiceConnected(int profile, BluetoothProfile proxy) {
650 mBluetoothHeadset = (BluetoothHeadset) proxy;
651 List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
652 if (deviceList.size() > 0) {
653 mBluetoothHeadsetDevice = deviceList.get(0);
654 } else {
655 mBluetoothHeadsetDevice = null;
656 }
657 }
658 @Override
659 public void onServiceDisconnected(int profile) {
660 if (mBluetoothHeadset != null) {
661 List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
662 if (devices.size() == 0) {
663 mBluetoothHeadsetDevice = null;
664 }
665 mBluetoothHeadset = null;
666 }
667 }
668 };
669
670 private int mChangedState = -1;
671 private int mUpdatedState = -1;
672 private int mUpdatedPrevState = -1;
673
674 private class ScoBroadcastReceiver extends BroadcastReceiver {
675 @Override
676 public void onReceive(Context context, Intent intent) {
677 String action = intent.getAction();
678
679 if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
680 int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
681 mVdStateTxt.setText(Integer.toString(state));
682 Log.e(TAG, "BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED: "+state);
683 } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED)) {
684 mChangedState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
685 Log.e(TAG, "ACTION_SCO_AUDIO_STATE_CHANGED: "+mChangedState);
686 mScoStateTxt.setText("changed: "+Integer.toString(mChangedState)+
687 " updated: "+Integer.toString(mUpdatedState)+
688 " prev updated: "+Integer.toString(mUpdatedPrevState));
689 } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
690 mUpdatedState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
691 mUpdatedPrevState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE, -1);
692 Log.e(TAG, "ACTION_SCO_AUDIO_STATE_UPDATED, state: "+mUpdatedState+" prev state: "+mUpdatedPrevState);
693 mScoStateTxt.setText("changed: "+Integer.toString(mChangedState)+
694 " updated: "+Integer.toString(mUpdatedState)+
695 " prev updated: "+Integer.toString(mUpdatedPrevState));
696 if (mForceScoOn && mUpdatedState == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
697 mForceScoOn = false;
698 mScoButton.setChecked(mForceScoOn);
699 mAudioManager.stopBluetoothSco();
700 }
701 }
702 }
703 }
704
705}