1*90c8c64dSAndroid Build Coastguard Worker /* 2*90c8c64dSAndroid Build Coastguard Worker * Copyright (C) 2015 Google Inc. All Rights Reserved. 3*90c8c64dSAndroid Build Coastguard Worker * 4*90c8c64dSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*90c8c64dSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*90c8c64dSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*90c8c64dSAndroid Build Coastguard Worker * 8*90c8c64dSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*90c8c64dSAndroid Build Coastguard Worker * 10*90c8c64dSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*90c8c64dSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*90c8c64dSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*90c8c64dSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*90c8c64dSAndroid Build Coastguard Worker * limitations under the License. 15*90c8c64dSAndroid Build Coastguard Worker */ 16*90c8c64dSAndroid Build Coastguard Worker 17*90c8c64dSAndroid Build Coastguard Worker package com.example.android.wearable.speaker; 18*90c8c64dSAndroid Build Coastguard Worker 19*90c8c64dSAndroid Build Coastguard Worker import android.Manifest; 20*90c8c64dSAndroid Build Coastguard Worker import android.content.Context; 21*90c8c64dSAndroid Build Coastguard Worker import android.content.pm.PackageManager; 22*90c8c64dSAndroid Build Coastguard Worker import android.media.AudioDeviceInfo; 23*90c8c64dSAndroid Build Coastguard Worker import android.media.AudioManager; 24*90c8c64dSAndroid Build Coastguard Worker import android.media.MediaPlayer; 25*90c8c64dSAndroid Build Coastguard Worker import android.os.Build; 26*90c8c64dSAndroid Build Coastguard Worker import android.os.Bundle; 27*90c8c64dSAndroid Build Coastguard Worker import android.os.CountDownTimer; 28*90c8c64dSAndroid Build Coastguard Worker import android.support.v4.app.ActivityCompat; 29*90c8c64dSAndroid Build Coastguard Worker import android.support.v4.content.ContextCompat; 30*90c8c64dSAndroid Build Coastguard Worker import android.support.wearable.activity.WearableActivity; 31*90c8c64dSAndroid Build Coastguard Worker import android.util.Log; 32*90c8c64dSAndroid Build Coastguard Worker import android.view.View; 33*90c8c64dSAndroid Build Coastguard Worker import android.widget.ImageView; 34*90c8c64dSAndroid Build Coastguard Worker import android.widget.ProgressBar; 35*90c8c64dSAndroid Build Coastguard Worker import android.widget.Toast; 36*90c8c64dSAndroid Build Coastguard Worker 37*90c8c64dSAndroid Build Coastguard Worker import java.util.concurrent.TimeUnit; 38*90c8c64dSAndroid Build Coastguard Worker 39*90c8c64dSAndroid Build Coastguard Worker /** 40*90c8c64dSAndroid Build Coastguard Worker * We first get the required permission to use the MIC. If it is granted, then we continue with 41*90c8c64dSAndroid Build Coastguard Worker * the application and present the UI with three icons: a MIC icon (if pressed, user can record up 42*90c8c64dSAndroid Build Coastguard Worker * to 10 seconds), a Play icon (if clicked, it wil playback the recorded audio file) and a music 43*90c8c64dSAndroid Build Coastguard Worker * note icon (if clicked, it plays an MP3 file that is included in the app). 44*90c8c64dSAndroid Build Coastguard Worker */ 45*90c8c64dSAndroid Build Coastguard Worker public class MainActivity extends WearableActivity implements UIAnimation.UIStateListener, 46*90c8c64dSAndroid Build Coastguard Worker SoundRecorder.OnVoicePlaybackStateChangedListener { 47*90c8c64dSAndroid Build Coastguard Worker 48*90c8c64dSAndroid Build Coastguard Worker private static final String TAG = "MainActivity"; 49*90c8c64dSAndroid Build Coastguard Worker private static final int PERMISSIONS_REQUEST_CODE = 100; 50*90c8c64dSAndroid Build Coastguard Worker private static final long COUNT_DOWN_MS = TimeUnit.SECONDS.toMillis(10); 51*90c8c64dSAndroid Build Coastguard Worker private static final long MILLIS_IN_SECOND = TimeUnit.SECONDS.toMillis(1); 52*90c8c64dSAndroid Build Coastguard Worker private static final String VOICE_FILE_NAME = "audiorecord.pcm"; 53*90c8c64dSAndroid Build Coastguard Worker private MediaPlayer mMediaPlayer; 54*90c8c64dSAndroid Build Coastguard Worker private AppState mState = AppState.READY; 55*90c8c64dSAndroid Build Coastguard Worker private UIAnimation.UIState mUiState = UIAnimation.UIState.HOME; 56*90c8c64dSAndroid Build Coastguard Worker private SoundRecorder mSoundRecorder; 57*90c8c64dSAndroid Build Coastguard Worker 58*90c8c64dSAndroid Build Coastguard Worker private UIAnimation mUIAnimation; 59*90c8c64dSAndroid Build Coastguard Worker private ProgressBar mProgressBar; 60*90c8c64dSAndroid Build Coastguard Worker private CountDownTimer mCountDownTimer; 61*90c8c64dSAndroid Build Coastguard Worker 62*90c8c64dSAndroid Build Coastguard Worker enum AppState { 63*90c8c64dSAndroid Build Coastguard Worker READY, PLAYING_VOICE, PLAYING_MUSIC, RECORDING 64*90c8c64dSAndroid Build Coastguard Worker } 65*90c8c64dSAndroid Build Coastguard Worker 66*90c8c64dSAndroid Build Coastguard Worker @Override onCreate(Bundle savedInstanceState)67*90c8c64dSAndroid Build Coastguard Worker protected void onCreate(Bundle savedInstanceState) { 68*90c8c64dSAndroid Build Coastguard Worker super.onCreate(savedInstanceState); 69*90c8c64dSAndroid Build Coastguard Worker setContentView(R.layout.main_activity); 70*90c8c64dSAndroid Build Coastguard Worker mProgressBar = (ProgressBar) findViewById(R.id.progress); 71*90c8c64dSAndroid Build Coastguard Worker mProgressBar.setMax((int) (COUNT_DOWN_MS / MILLIS_IN_SECOND)); 72*90c8c64dSAndroid Build Coastguard Worker setAmbientEnabled(); 73*90c8c64dSAndroid Build Coastguard Worker } 74*90c8c64dSAndroid Build Coastguard Worker setProgressBar(long progressInMillis)75*90c8c64dSAndroid Build Coastguard Worker private void setProgressBar(long progressInMillis) { 76*90c8c64dSAndroid Build Coastguard Worker mProgressBar.setProgress((int) (progressInMillis / MILLIS_IN_SECOND)); 77*90c8c64dSAndroid Build Coastguard Worker } 78*90c8c64dSAndroid Build Coastguard Worker 79*90c8c64dSAndroid Build Coastguard Worker @Override onUIStateChanged(UIAnimation.UIState state)80*90c8c64dSAndroid Build Coastguard Worker public void onUIStateChanged(UIAnimation.UIState state) { 81*90c8c64dSAndroid Build Coastguard Worker Log.d(TAG, "UI State is: " + state); 82*90c8c64dSAndroid Build Coastguard Worker if (mUiState == state) { 83*90c8c64dSAndroid Build Coastguard Worker return; 84*90c8c64dSAndroid Build Coastguard Worker } 85*90c8c64dSAndroid Build Coastguard Worker switch (state) { 86*90c8c64dSAndroid Build Coastguard Worker case MUSIC_UP: 87*90c8c64dSAndroid Build Coastguard Worker mState = AppState.PLAYING_MUSIC; 88*90c8c64dSAndroid Build Coastguard Worker mUiState = state; 89*90c8c64dSAndroid Build Coastguard Worker playMusic(); 90*90c8c64dSAndroid Build Coastguard Worker break; 91*90c8c64dSAndroid Build Coastguard Worker case MIC_UP: 92*90c8c64dSAndroid Build Coastguard Worker mState = AppState.RECORDING; 93*90c8c64dSAndroid Build Coastguard Worker mUiState = state; 94*90c8c64dSAndroid Build Coastguard Worker mSoundRecorder.startRecording(); 95*90c8c64dSAndroid Build Coastguard Worker setProgressBar(COUNT_DOWN_MS); 96*90c8c64dSAndroid Build Coastguard Worker mCountDownTimer = new CountDownTimer(COUNT_DOWN_MS, MILLIS_IN_SECOND) { 97*90c8c64dSAndroid Build Coastguard Worker @Override 98*90c8c64dSAndroid Build Coastguard Worker public void onTick(long millisUntilFinished) { 99*90c8c64dSAndroid Build Coastguard Worker mProgressBar.setVisibility(View.VISIBLE); 100*90c8c64dSAndroid Build Coastguard Worker setProgressBar(millisUntilFinished); 101*90c8c64dSAndroid Build Coastguard Worker Log.d(TAG, "Time Left: " + millisUntilFinished / MILLIS_IN_SECOND); 102*90c8c64dSAndroid Build Coastguard Worker } 103*90c8c64dSAndroid Build Coastguard Worker 104*90c8c64dSAndroid Build Coastguard Worker @Override 105*90c8c64dSAndroid Build Coastguard Worker public void onFinish() { 106*90c8c64dSAndroid Build Coastguard Worker mProgressBar.setProgress(0); 107*90c8c64dSAndroid Build Coastguard Worker mProgressBar.setVisibility(View.INVISIBLE); 108*90c8c64dSAndroid Build Coastguard Worker mSoundRecorder.stopRecording(); 109*90c8c64dSAndroid Build Coastguard Worker mUIAnimation.transitionToHome(); 110*90c8c64dSAndroid Build Coastguard Worker mUiState = UIAnimation.UIState.HOME; 111*90c8c64dSAndroid Build Coastguard Worker mState = AppState.READY; 112*90c8c64dSAndroid Build Coastguard Worker mCountDownTimer = null; 113*90c8c64dSAndroid Build Coastguard Worker } 114*90c8c64dSAndroid Build Coastguard Worker }; 115*90c8c64dSAndroid Build Coastguard Worker mCountDownTimer.start(); 116*90c8c64dSAndroid Build Coastguard Worker break; 117*90c8c64dSAndroid Build Coastguard Worker case SOUND_UP: 118*90c8c64dSAndroid Build Coastguard Worker mState = AppState.PLAYING_VOICE; 119*90c8c64dSAndroid Build Coastguard Worker mUiState = state; 120*90c8c64dSAndroid Build Coastguard Worker mSoundRecorder.startPlay(); 121*90c8c64dSAndroid Build Coastguard Worker break; 122*90c8c64dSAndroid Build Coastguard Worker case HOME: 123*90c8c64dSAndroid Build Coastguard Worker switch (mState) { 124*90c8c64dSAndroid Build Coastguard Worker case PLAYING_MUSIC: 125*90c8c64dSAndroid Build Coastguard Worker mState = AppState.READY; 126*90c8c64dSAndroid Build Coastguard Worker mUiState = state; 127*90c8c64dSAndroid Build Coastguard Worker stopMusic(); 128*90c8c64dSAndroid Build Coastguard Worker break; 129*90c8c64dSAndroid Build Coastguard Worker case PLAYING_VOICE: 130*90c8c64dSAndroid Build Coastguard Worker mState = AppState.READY; 131*90c8c64dSAndroid Build Coastguard Worker mUiState = state; 132*90c8c64dSAndroid Build Coastguard Worker mSoundRecorder.stopPlaying(); 133*90c8c64dSAndroid Build Coastguard Worker break; 134*90c8c64dSAndroid Build Coastguard Worker case RECORDING: 135*90c8c64dSAndroid Build Coastguard Worker mState = AppState.READY; 136*90c8c64dSAndroid Build Coastguard Worker mUiState = state; 137*90c8c64dSAndroid Build Coastguard Worker mSoundRecorder.stopRecording(); 138*90c8c64dSAndroid Build Coastguard Worker if (mCountDownTimer != null) { 139*90c8c64dSAndroid Build Coastguard Worker mCountDownTimer.cancel(); 140*90c8c64dSAndroid Build Coastguard Worker mCountDownTimer = null; 141*90c8c64dSAndroid Build Coastguard Worker } 142*90c8c64dSAndroid Build Coastguard Worker mProgressBar.setVisibility(View.INVISIBLE); 143*90c8c64dSAndroid Build Coastguard Worker setProgressBar(COUNT_DOWN_MS); 144*90c8c64dSAndroid Build Coastguard Worker break; 145*90c8c64dSAndroid Build Coastguard Worker } 146*90c8c64dSAndroid Build Coastguard Worker break; 147*90c8c64dSAndroid Build Coastguard Worker } 148*90c8c64dSAndroid Build Coastguard Worker } 149*90c8c64dSAndroid Build Coastguard Worker 150*90c8c64dSAndroid Build Coastguard Worker /** 151*90c8c64dSAndroid Build Coastguard Worker * Plays back the MP3 file embedded in the application 152*90c8c64dSAndroid Build Coastguard Worker */ playMusic()153*90c8c64dSAndroid Build Coastguard Worker private void playMusic() { 154*90c8c64dSAndroid Build Coastguard Worker if (mMediaPlayer == null) { 155*90c8c64dSAndroid Build Coastguard Worker mMediaPlayer = MediaPlayer.create(this, R.raw.sound); 156*90c8c64dSAndroid Build Coastguard Worker mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 157*90c8c64dSAndroid Build Coastguard Worker @Override 158*90c8c64dSAndroid Build Coastguard Worker public void onCompletion(MediaPlayer mp) { 159*90c8c64dSAndroid Build Coastguard Worker // we need to transition to the READY/Home state 160*90c8c64dSAndroid Build Coastguard Worker Log.d(TAG, "Music Finished"); 161*90c8c64dSAndroid Build Coastguard Worker mUIAnimation.transitionToHome(); 162*90c8c64dSAndroid Build Coastguard Worker } 163*90c8c64dSAndroid Build Coastguard Worker }); 164*90c8c64dSAndroid Build Coastguard Worker } 165*90c8c64dSAndroid Build Coastguard Worker mMediaPlayer.start(); 166*90c8c64dSAndroid Build Coastguard Worker } 167*90c8c64dSAndroid Build Coastguard Worker 168*90c8c64dSAndroid Build Coastguard Worker /** 169*90c8c64dSAndroid Build Coastguard Worker * Stops the playback of the MP3 file. 170*90c8c64dSAndroid Build Coastguard Worker */ stopMusic()171*90c8c64dSAndroid Build Coastguard Worker private void stopMusic() { 172*90c8c64dSAndroid Build Coastguard Worker if (mMediaPlayer != null) { 173*90c8c64dSAndroid Build Coastguard Worker mMediaPlayer.stop(); 174*90c8c64dSAndroid Build Coastguard Worker mMediaPlayer.release(); 175*90c8c64dSAndroid Build Coastguard Worker mMediaPlayer = null; 176*90c8c64dSAndroid Build Coastguard Worker } 177*90c8c64dSAndroid Build Coastguard Worker } 178*90c8c64dSAndroid Build Coastguard Worker 179*90c8c64dSAndroid Build Coastguard Worker /** 180*90c8c64dSAndroid Build Coastguard Worker * Checks the permission that this app needs and if it has not been granted, it will 181*90c8c64dSAndroid Build Coastguard Worker * prompt the user to grant it, otherwise it shuts down the app. 182*90c8c64dSAndroid Build Coastguard Worker */ checkPermissions()183*90c8c64dSAndroid Build Coastguard Worker private void checkPermissions() { 184*90c8c64dSAndroid Build Coastguard Worker boolean recordAudioPermissionGranted = 185*90c8c64dSAndroid Build Coastguard Worker ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) 186*90c8c64dSAndroid Build Coastguard Worker == PackageManager.PERMISSION_GRANTED; 187*90c8c64dSAndroid Build Coastguard Worker 188*90c8c64dSAndroid Build Coastguard Worker if (recordAudioPermissionGranted) { 189*90c8c64dSAndroid Build Coastguard Worker start(); 190*90c8c64dSAndroid Build Coastguard Worker } else { 191*90c8c64dSAndroid Build Coastguard Worker ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.RECORD_AUDIO}, 192*90c8c64dSAndroid Build Coastguard Worker PERMISSIONS_REQUEST_CODE); 193*90c8c64dSAndroid Build Coastguard Worker } 194*90c8c64dSAndroid Build Coastguard Worker 195*90c8c64dSAndroid Build Coastguard Worker } 196*90c8c64dSAndroid Build Coastguard Worker 197*90c8c64dSAndroid Build Coastguard Worker @Override onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)198*90c8c64dSAndroid Build Coastguard Worker public void onRequestPermissionsResult(int requestCode, 199*90c8c64dSAndroid Build Coastguard Worker String permissions[], int[] grantResults) { 200*90c8c64dSAndroid Build Coastguard Worker if (requestCode == PERMISSIONS_REQUEST_CODE) { 201*90c8c64dSAndroid Build Coastguard Worker if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 202*90c8c64dSAndroid Build Coastguard Worker start(); 203*90c8c64dSAndroid Build Coastguard Worker } else { 204*90c8c64dSAndroid Build Coastguard Worker // Permission has been denied before. At this point we should show a dialog to 205*90c8c64dSAndroid Build Coastguard Worker // user and explain why this permission is needed and direct them to go to the 206*90c8c64dSAndroid Build Coastguard Worker // Permissions settings for the app in the System settings. For this sample, we 207*90c8c64dSAndroid Build Coastguard Worker // simply exit to get to the important part. 208*90c8c64dSAndroid Build Coastguard Worker Toast.makeText(this, R.string.exiting_for_permissions, Toast.LENGTH_LONG).show(); 209*90c8c64dSAndroid Build Coastguard Worker finish(); 210*90c8c64dSAndroid Build Coastguard Worker } 211*90c8c64dSAndroid Build Coastguard Worker } 212*90c8c64dSAndroid Build Coastguard Worker } 213*90c8c64dSAndroid Build Coastguard Worker 214*90c8c64dSAndroid Build Coastguard Worker /** 215*90c8c64dSAndroid Build Coastguard Worker * Starts the main flow of the application. 216*90c8c64dSAndroid Build Coastguard Worker */ start()217*90c8c64dSAndroid Build Coastguard Worker private void start() { 218*90c8c64dSAndroid Build Coastguard Worker mSoundRecorder = new SoundRecorder(this, VOICE_FILE_NAME, this); 219*90c8c64dSAndroid Build Coastguard Worker int[] thumbResources = new int[] {R.id.mic, R.id.play, R.id.music}; 220*90c8c64dSAndroid Build Coastguard Worker ImageView[] thumbs = new ImageView[3]; 221*90c8c64dSAndroid Build Coastguard Worker for(int i=0; i < 3; i++) { 222*90c8c64dSAndroid Build Coastguard Worker thumbs[i] = (ImageView) findViewById(thumbResources[i]); 223*90c8c64dSAndroid Build Coastguard Worker } 224*90c8c64dSAndroid Build Coastguard Worker View containerView = findViewById(R.id.container); 225*90c8c64dSAndroid Build Coastguard Worker ImageView expandedView = (ImageView) findViewById(R.id.expanded); 226*90c8c64dSAndroid Build Coastguard Worker int animationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime); 227*90c8c64dSAndroid Build Coastguard Worker mUIAnimation = new UIAnimation(containerView, thumbs, expandedView, animationDuration, 228*90c8c64dSAndroid Build Coastguard Worker this); 229*90c8c64dSAndroid Build Coastguard Worker } 230*90c8c64dSAndroid Build Coastguard Worker 231*90c8c64dSAndroid Build Coastguard Worker @Override onStart()232*90c8c64dSAndroid Build Coastguard Worker protected void onStart() { 233*90c8c64dSAndroid Build Coastguard Worker super.onStart(); 234*90c8c64dSAndroid Build Coastguard Worker if (speakerIsSupported()) { 235*90c8c64dSAndroid Build Coastguard Worker checkPermissions(); 236*90c8c64dSAndroid Build Coastguard Worker } else { 237*90c8c64dSAndroid Build Coastguard Worker findViewById(R.id.container2).setOnClickListener(new View.OnClickListener() { 238*90c8c64dSAndroid Build Coastguard Worker @Override 239*90c8c64dSAndroid Build Coastguard Worker public void onClick(View v) { 240*90c8c64dSAndroid Build Coastguard Worker Toast.makeText(MainActivity.this, R.string.no_speaker_supported, 241*90c8c64dSAndroid Build Coastguard Worker Toast.LENGTH_SHORT).show(); 242*90c8c64dSAndroid Build Coastguard Worker } 243*90c8c64dSAndroid Build Coastguard Worker }); 244*90c8c64dSAndroid Build Coastguard Worker } 245*90c8c64dSAndroid Build Coastguard Worker } 246*90c8c64dSAndroid Build Coastguard Worker 247*90c8c64dSAndroid Build Coastguard Worker @Override onStop()248*90c8c64dSAndroid Build Coastguard Worker protected void onStop() { 249*90c8c64dSAndroid Build Coastguard Worker if (mSoundRecorder != null) { 250*90c8c64dSAndroid Build Coastguard Worker mSoundRecorder.cleanup(); 251*90c8c64dSAndroid Build Coastguard Worker mSoundRecorder = null; 252*90c8c64dSAndroid Build Coastguard Worker } 253*90c8c64dSAndroid Build Coastguard Worker if (mCountDownTimer != null) { 254*90c8c64dSAndroid Build Coastguard Worker mCountDownTimer.cancel(); 255*90c8c64dSAndroid Build Coastguard Worker } 256*90c8c64dSAndroid Build Coastguard Worker 257*90c8c64dSAndroid Build Coastguard Worker if (mMediaPlayer != null) { 258*90c8c64dSAndroid Build Coastguard Worker mMediaPlayer.release(); 259*90c8c64dSAndroid Build Coastguard Worker mMediaPlayer = null; 260*90c8c64dSAndroid Build Coastguard Worker } 261*90c8c64dSAndroid Build Coastguard Worker super.onStop(); 262*90c8c64dSAndroid Build Coastguard Worker } 263*90c8c64dSAndroid Build Coastguard Worker 264*90c8c64dSAndroid Build Coastguard Worker @Override onPlaybackStopped()265*90c8c64dSAndroid Build Coastguard Worker public void onPlaybackStopped() { 266*90c8c64dSAndroid Build Coastguard Worker mUIAnimation.transitionToHome(); 267*90c8c64dSAndroid Build Coastguard Worker mUiState = UIAnimation.UIState.HOME; 268*90c8c64dSAndroid Build Coastguard Worker mState = AppState.READY; 269*90c8c64dSAndroid Build Coastguard Worker } 270*90c8c64dSAndroid Build Coastguard Worker 271*90c8c64dSAndroid Build Coastguard Worker /** 272*90c8c64dSAndroid Build Coastguard Worker * Determines if the wear device has a built-in speaker and if it is supported. Speaker, even if 273*90c8c64dSAndroid Build Coastguard Worker * physically present, is only supported in Android M+ on a wear device.. 274*90c8c64dSAndroid Build Coastguard Worker */ speakerIsSupported()275*90c8c64dSAndroid Build Coastguard Worker public final boolean speakerIsSupported() { 276*90c8c64dSAndroid Build Coastguard Worker if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 277*90c8c64dSAndroid Build Coastguard Worker PackageManager packageManager = getPackageManager(); 278*90c8c64dSAndroid Build Coastguard Worker // The results from AudioManager.getDevices can't be trusted unless the device 279*90c8c64dSAndroid Build Coastguard Worker // advertises FEATURE_AUDIO_OUTPUT. 280*90c8c64dSAndroid Build Coastguard Worker if (!packageManager.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) { 281*90c8c64dSAndroid Build Coastguard Worker return false; 282*90c8c64dSAndroid Build Coastguard Worker } 283*90c8c64dSAndroid Build Coastguard Worker AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 284*90c8c64dSAndroid Build Coastguard Worker AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS); 285*90c8c64dSAndroid Build Coastguard Worker for (AudioDeviceInfo device : devices) { 286*90c8c64dSAndroid Build Coastguard Worker if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) { 287*90c8c64dSAndroid Build Coastguard Worker return true; 288*90c8c64dSAndroid Build Coastguard Worker } 289*90c8c64dSAndroid Build Coastguard Worker } 290*90c8c64dSAndroid Build Coastguard Worker } 291*90c8c64dSAndroid Build Coastguard Worker return false; 292*90c8c64dSAndroid Build Coastguard Worker } 293*90c8c64dSAndroid Build Coastguard Worker } 294