参考:

Android实现主动连接蓝牙耳机

具体实现:

    private static final String TAG = "BluetoothA2DPTest";
private BroadcastReceiver mBroadcastReceiver;
private BluetoothA2dp mBluetoothA2dp;
private BluetoothAdapter mBluetoothAdapter;
private String DEVICE_NAME = "KUWO_K1";
private BluetoothDevice mBluetoothDevice;
private MediaPlayer mMediaPlayer; private void initParameters(){
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null){
Log.e(TAG,"have no bluetooth adapter.");
return;
} if(!mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.enable();
}else{
//开始搜索附近蓝牙
startDiscovery();
//绑定BluetoothA2DP,获得service
getBluetoothA2DP();
} //监听广播
mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
BluetoothDevice device;
switch (intent.getAction()) {
case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
//<editor-fold>
switch (intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1)) {
case BluetoothA2dp.STATE_CONNECTING:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i(TAG, "device: " + device.getName() +" connecting");
break;
case BluetoothA2dp.STATE_CONNECTED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i(TAG, "device: " + device.getName() +" connected");
//连接成功,开始播放
startPlay();
break;
case BluetoothA2dp.STATE_DISCONNECTING:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i(TAG, "device: " + device.getName() +" disconnecting");
break;
case BluetoothA2dp.STATE_DISCONNECTED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i(TAG, "device: " + device.getName() +" disconnected");
// setResultPASS();
break;
default:
break;
}
//</editor-fold>
break;
case BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED:
//<editor-fold>
int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1);
switch (state) {
case BluetoothA2dp.STATE_PLAYING:
Log.i(TAG, "state: playing.");
break;
case BluetoothA2dp.STATE_NOT_PLAYING:
Log.i(TAG, "state: not playing");
break;
default:
Log.i(TAG, "state: unkown");
break;
}
//</editor-fold>
break;
case BluetoothDevice.ACTION_FOUND:
//<editor-fold>
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int deviceClassType = device.getBluetoothClass().getDeviceClass();
//找到指定的蓝牙设备
if ((deviceClassType == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET
|| deviceClassType == BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES)
&& device.getName().equals(DEVICE_NAME)) {
Log.i(TAG, "Found device:" + device.getName());
mBluetoothDevice = device;
//start bond,开始配对
createBond();
}
//</editor-fold>
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
//<editor-fold>
int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,BluetoothDevice.BOND_NONE);
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (bondState){
case BluetoothDevice.BOND_BONDED: //配对成功
Log.i(TAG,"Device:"+device.getName()+" bonded.");
mBluetoothAdapter.cancelDiscovery(); //取消搜索
connect(); //连接蓝牙设备
break;
case BluetoothDevice.BOND_BONDING:
Log.i(TAG,"Device:"+device.getName()+" bonding.");
break;
case BluetoothDevice.BOND_NONE:
Log.i(TAG,"Device:"+device.getName()+" not bonded.");
//不知道是蓝牙耳机的关系还是什么原因,经常配对不成功
//配对不成功的话,重新尝试配对
createBond();
break;
default:
break; } //</editor-fold>
break;
case BluetoothAdapter.ACTION_STATE_CHANGED:
//<editor-fold>
state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
switch (state) {
case BluetoothAdapter.STATE_TURNING_ON:
Log.i(TAG, "BluetoothAdapter is turning on.");
break;
case BluetoothAdapter.STATE_ON:
Log.i(TAG, "BluetoothAdapter is on.");
//蓝牙已打开,开始搜索并连接service
startDiscovery();
getBluetoothA2DP();
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log.i(TAG, "BluetoothAdapter is turning off.");
break;
case BluetoothAdapter.STATE_OFF:
Log.i(TAG, "BluetoothAdapter is off.");
break;
}
//</editor-fold>
break;
default:
break;
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mBroadcastReceiver, filter);
} private void startDiscovery(){
Log.i(TAG,"mBluetoothAdapter startDiscovery.");
if(mBluetoothAdapter!=null && mBluetoothAdapter.isEnabled() && !mBluetoothAdapter.isDiscovering()){
mBluetoothAdapter.startDiscovery();
}
} private void getBluetoothA2DP(){
Log.i(TAG,"getBluetoothA2DP");
if(mBluetoothAdapter == null){
return;
} if(mBluetoothA2dp != null){
return;
} mBluetoothAdapter.getProfileProxy(this, new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if(profile == BluetoothProfile.A2DP){
//Service连接成功,获得BluetoothA2DP
mBluetoothA2dp = (BluetoothA2dp)proxy;
}
} @Override
public void onServiceDisconnected(int profile) { }
},BluetoothProfile.A2DP);
} private void createBond() {
Log.i(TAG, "createBond");
mBluetoothDevice.createBond();
} //connect和disconnect都是hide方法,普通应用只能通过反射机制来调用该方法
private void connect(){
Log.i(TAG,"connect");
if(mBluetoothA2dp == null){
return;
}
if(mBluetoothDevice == null){
return;
} try {
Method connect = mBluetoothA2dp.getClass().getDeclaredMethod("connect", BluetoothDevice.class);
connect.setAccessible(true);
connect.invoke(mBluetoothA2dp,mBluetoothDevice);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
Log.e(TAG,"connect exception:"+e);
e.printStackTrace();
}
} private void startPlay(){
Log.i(TAG, "startPlay");
AudioManager mAudioManager= (AudioManager)getSystemService(AUDIO_SERVICE);
if(mAudioManager!=null){
int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,maxVolume,0);
} Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+ R.raw.speaker_test);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.reset();
try {
mMediaPlayer.setDataSource(this,uri);
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//播放完成,可以考虑断开连接
disconnect();
}
});
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e(TAG, "Playback error.");
return false;
}
});
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch(IllegalStateException|IOException e) {
Log.e(TAG, "Exception: prepare or start mediaplayer");
setResultFAIL();
}
} //程序退出前,要release播放器
private void stopPlay(){
Log.i(TAG,"stopPlay");
if(mMediaPlayer!=null){
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
} private void disconnect(){
Log.i(TAG,"disconnect");
if(mBluetoothA2dp == null){
return;
}
if(mBluetoothDevice == null){
return;
} try {
Method disconnect = mBluetoothA2dp.getClass().getDeclaredMethod("disconnect", BluetoothDevice.class);
disconnect.setAccessible(true);
disconnect.invoke(mBluetoothA2dp,mBluetoothDevice);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
Log.e(TAG,"connect exception:"+e);
e.printStackTrace();
}
} //取消配对
private void unPairAllDevices(){
Log.i(TAG,"unPairAllDevices");
for(BluetoothDevice device:mBluetoothAdapter.getBondedDevices()){
try {
Method removeBond = device.getClass().getDeclaredMethod("removeBond");
removeBond.invoke(device);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
} //注意,在程序退出之前(OnDestroy),需要断开蓝牙相关的Service
//否则,程序会报异常:service leaks
private void disableAdapter(){
Log.i(TAG,"disableAdapter");
if(mBluetoothAdapter == null){
return;
} if(mBluetoothAdapter.isDiscovering()){
mBluetoothAdapter.cancelDiscovery();
} //关闭ProfileProxy,也就是断开service连接
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP,mBluetoothA2dp);
if(mBluetoothAdapter.isEnabled()){
boolean ret = mBluetoothAdapter.disable();
Log.i(TAG,"disable adapter:"+ret);
}
}

Android连接蓝牙耳机播放音乐的更多相关文章

  1. mac,macbook 连接蓝牙耳机播放音乐断断续续

    个人的情况是, mac本连的网线,用的无线鼠标, 屋里80多号人都在用笔记本,应该也有好多开着无线的东西 解决方法: mac 或macbook 连接蓝牙耳机播放音乐断断续续的原因, 在网上找了好多方法 ...

  2. Android实例-MediaPlayer播放音乐和视频(XE8+小米2)

    结果: 1.播放视频需要手动放入MediaPlayerControl1控件,设置MediaPlayerControl1.MediaPlayer := MediaPlayer1; 2.播放声音文件正常, ...

  3. Android应用开发--MP3音乐播放器代码实现(一)

    需求1:将内存卡中的MP3音乐读取出来并显示到列表当中 1.   从数据库中查询所有音乐数据,保存到List集合当中,List当中存放的是Mp3Info对象 2.   迭代List集合,把每一个Mp3 ...

  4. Android命令行播放MP3音乐

    /*************************************************************************** * Android命令行播放MP3音乐 * 说 ...

  5. Android跟蓝牙耳机建立连接有两种方式

    Android 跟蓝牙耳机建立连接有两种方式. 1. Android 主动跟蓝牙耳机连BluetoothSettings 中和蓝牙耳机配对上之后, BluetoothHeadsetService 会收 ...

  6. android 播放音乐-进度条

    今天学渣研究了一下使用MediaPlayer播放音乐时加入进度条,进度条如今用的是android自带的seekbar,后期会跟换UI的,在之前可以播放音乐的基础上,如今加入的主要功能有两个: 1实时显 ...

  7. Android基于发展Service音乐播放器

    这是一个基于Service组件的音乐播放器,程序的音乐将会由后台的Service组件负责播放,当后台的播放状态改变时,程序将会通过发送广播通知前台Activity更新界面:当用户单击前台Activit ...

  8. Android中播放音乐的几种方式

    前言 前几天一直在研究RxJava2,也写了记录了几篇博客,但因为工作任务原因,需要研究音频相关的知识,暂时放下Rxjava,本文的demo中,MediaPalyer 部分使用RxJava编写一点逻辑 ...

  9. Android播放器推荐:可以播放本地音乐、视频、在线播放音乐、视频、网络收音机等

    下载链接:http://www.eoeandroid.com/forum.php?mod=attachment&aid=MTAxNTczfGMyNjNkMzFlfDEzNzY1MzkwNTR8 ...

随机推荐

  1. C++ Pitfalls 之 reference to an object in a dynamically allocated containter

    (留坑待填)  Extraction from the C++ Programming Language 4th. ed., Bjarne Stroustrup 31.3.3 Size and Cap ...

  2. linux编程开发命令

    test命令命令功能test命令是shell环境中测试条件表达式的实用工具.命令语法test(选项)选项说明-b〈文件〉如果文件为一个块特殊文件,则为真;-c<文件〉,如果文件为一个字符特殊文件 ...

  3. ThinkPHP中field 方法与getField 方法的区别。

    做项目的时候遇到了一个问题,框架生成的sql与放到navicat中执行.和页面显示出来的结果不太一样. 排查了很久,也没有找到问题. 出现问题的sql如下. $fuck = M(null, null, ...

  4. Struct Member Default Value

    在C#中struct是值类型的数据类型,其默认值相当于调用了无参数默认构造函数之后的值.这也许就是struct不允许重载无参数默认构造函数的原因. https://msdn.microsoft.com ...

  5. __cdecl和__stdcall

    MSVC在编译C/C++程序的时候,默认采用__cdecl调用约定来编译.__stdcall是Win32 API函数的默认调用规约. Calling Convention Internal* MSVC ...

  6. 取出return array() 数组内容

    d.php文件 return array( "0" => 内容一, "1" => 内容二, "2" => 内容三, &qu ...

  7. apache外网不能访问分析与解决方法

    apache安装好以后,在本机可以用:http://localhost 或者 http://127.0.0.1进行访问,但是,在外网(相对本机来说的,局域网也算)不能访问. 这种情况可以分为两个问题, ...

  8. mysql中Can't connect to MySQL server on 'localhost' (10061)

    Can't connect to MySQL server on 'localhost' (10061) 第一问题有两个解决方案: 1)没有启动sql服务,以下是具体步骤: 右键-计算机-管理-服务和 ...

  9. Linux 挂载 NFS

    NFS(网络文件系统),这是在 Linux 系统上常用的文件共享方式.也可以做为作为一个远程存储使用,比如:我有个网站,用户可以上传文件,但文件慢慢会越来越多,这个时候我们只能把存放上传文件的目录挂在 ...

  10. Saltstack pillar组件

     pillar组件 pillar也是Saltstack最重要的组件之一,其作用是定义与被控主机相关的任何数据,定义好的数据可以被其他组件使用,如模板.state.API等.在pillar中定义的数据与 ...