1,工具类
package com.win16.bluetoothclass5;
import java.util.List;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Build;
import android.os.CountDownTimer;
/** * @Description: * @author eandroidhu * @date 2014年10月17日 上午10:56:47 */
public abstract class BluetoothHeadsetUtils {
private Context mContext;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothHeadset mBluetoothHeadset;
private BluetoothDevice mConnectedHeadset;
private AudioManager mAudioManager;
private boolean mIsOnHeadsetSco;
private boolean mIsStarted;
/** * Constructor * * @param context */
public BluetoothHeadsetUtils(Context context) {
mContext = context;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
}
/** * Call this to start BluetoothHeadsetUtils functionalities. * * @return The return value of startBluetooth() or startBluetooth11() */
public boolean start() {
if (mBluetoothAdapter.isEnabled() == false){
mIsStarted = false;
return mIsStarted;
}
if (!mIsStarted) {
mIsStarted = true;
mIsStarted = startBluetooth();
}
return mIsStarted;
}
/** * Should call this on onResume or onDestroy. Unregister broadcast receivers * and stop Sco audio connection and cancel count down. */
public void stop() {
if (mIsStarted) {
mIsStarted = false;
stopBluetooth();
}
}
/** * * @return true if audio is connected through headset. */
public boolean isOnHeadsetSco() {
return mIsOnHeadsetSco;
}
public abstract void onHeadsetDisconnected();
public abstract void onHeadsetConnected();
public abstract void onScoAudioDisconnected();
public abstract void onScoAudioConnected();
/** * Register a headset profile listener * * @return false if device does not support bluetooth or current platform * does not supports use of SCO for off call or error in getting * profile proxy. */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private boolean startBluetooth() {
// Device support bluetooth
if (mBluetoothAdapter != null) {
if (mAudioManager.isBluetoothScoAvailableOffCall()) {
// All the detection and audio connection are done in
// mHeadsetProfileListener
if (mBluetoothAdapter.getProfileProxy(mContext, mHeadsetProfileListener, BluetoothProfile.HEADSET)) {
return true;
}
}
}
return false;
}
/** * API >= 11 Unregister broadcast receivers and stop Sco audio connection * and cancel count down. */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
protected void stopBluetooth() {
if (mBluetoothHeadset != null) {
// Need to call stopVoiceRecognition here when the app
// change orientation or close with headset still turns on.
mBluetoothHeadset.stopVoiceRecognition(mConnectedHeadset);
mContext.unregisterReceiver(mHeadsetBroadcastReceiver);
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
mBluetoothHeadset = null;
}
}
/** * API >= 11 Check for already connected headset and if so start audio * connection. Register for broadcast of headset and Sco audio connection * states. */
private BluetoothProfile.ServiceListener mHeadsetProfileListener = new BluetoothProfile.ServiceListener() {
/** * This method is never called, even when we closeProfileProxy on * onPause. When or will it ever be called??? */
@Override
public void onServiceDisconnected(int profile) {
stopBluetooth();
}
@SuppressWarnings("synthetic-access")
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
// mBluetoothHeadset is just a headset profile,
// it does not represent a headset device.
mBluetoothHeadset = (BluetoothHeadset) proxy;
// If a headset is connected before this application starts,
// ACTION_CONNECTION_STATE_CHANGED will not be broadcast.
// So we need to check for already connected headset.
List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
if (devices.size() > 0) {
// Only one headset can be connected at a time,
// so the connected headset is at index 0.
mConnectedHeadset = devices.get(0);
onHeadsetConnected();
}
// During the active life time of the app, a user may turn on and
// off the headset.
// So register for broadcast of connection states.
mContext.registerReceiver(mHeadsetBroadcastReceiver, new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED));
// Calling startVoiceRecognition does not result in immediate audio
// connection.
// So register for broadcast of audio connection states. This
// broadcast will
// only be sent if startVoiceRecognition returns true.
mContext.registerReceiver(mHeadsetBroadcastReceiver, new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED));
}
};
/** * API >= 11 Handle headset and Sco audio connection states. */
private BroadcastReceiver mHeadsetBroadcastReceiver = new BroadcastReceiver() {
@SuppressWarnings("synthetic-access")
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
int state;
if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_DISCONNECTED);
if (state == BluetoothHeadset.STATE_CONNECTED) {
mConnectedHeadset = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Calling startVoiceRecognition always returns false here,
// that why a count down timer is implemented to call
// startVoiceRecognition in the onTick.
// override this if you want to do other thing when the
// device is connected.
onHeadsetConnected();
} else if (state == BluetoothHeadset.STATE_DISCONNECTED) {
mConnectedHeadset = null;
// override this if you want to do other thing when the
// device is disconnected.
onHeadsetDisconnected();
}
} else // audio
{
state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
// override this if you want to do other thing when headset
// audio is connected.
onScoAudioConnected();
} else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
mIsOnHeadsetSco = false;
// override this if you want to do other thing when headset
// audio is disconnected.
onScoAudioDisconnected();
}
}
}
};
}
2,帮助类
package com.win16.bluetoothclass5;
import android.content.Context;
import android.media.AudioManager;
/** * @Description: * @author eandroidhu * @date 2014年10月17日 上午11:00:02 */
public class BluetoothHelper extends BluetoothHeadsetUtils {
private final static String TAG = BluetoothHelper.class.getSimpleName();
Context mContext;
int mCallvol;
// int mMediaVol;
AudioManager mAudioManager;
public BluetoothHelper(Context context) {
super(context);
mContext = context;
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mCallvol = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
// mMediaVol = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
}
@Override
public void onHeadsetDisconnected() {
mAudioManager.setBluetoothScoOn(false);
}
@Override
public void onHeadsetConnected() {
mAudioManager.setBluetoothScoOn(true); // 打开SCO
// mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
}
@Override
public void onScoAudioDisconnected() {
mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, mCallvol, 0);
// mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mMediaVol, 0);
}
@Override
public void onScoAudioConnected() {
mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), 0);
// mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
}
}
3,源码下载
http://download.csdn.net/detail/eandroidhu/9433853