蓝牙通信
1.搜索设备,彼此确认身份,我说天王盖地虎,你回我,宝塔镇河妖,好,是那跟人,便可以通信了
2.添加权限:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
3.常见一些蓝牙的基本配置
package com.lmj.bluuetoothdemo;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
public class BluetoothController {
/* 本地蓝牙适配器*/
private BluetoothAdapter mAdapter;
public BluetoothController(){
mAdapter=BluetoothAdapter.getDefaultAdapter();
}
public boolean isSupportBlueTooth() {
if (mAdapter != null) {
//支持蓝牙,一般设备都支持蓝牙
return true;
} else {
return false;
}
}
public boolean getBlueToothStatus(){
//判断蓝牙状态,true为打开,false为关闭
//如果不支持,则会空指针,所以我们在mAdapter里加个断点函数
assert(mAdapter!=null);
return mAdapter.isEnabled();
}
/**
*打开蓝牙
* @param activity
* @param requestCode
*/
//系统主动调,一般不要设置成手动调用
public void turnOnBluetooth(Activity activity,int requestCode){
//通过intent获取蓝牙,action_request_enable请求可用
Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//知道它的返回结果
activity.startActivityForResult(intent,requestCode);
//设置成自动调用
mAdapter.enable();
}
public void turnOffBlueTooth() {
mAdapter.disable();
}
}
插播小技巧。输入:
/**
然后按两下回车,就能产生这样的绿色的注释效果
/**
*打开蓝牙
* @param activity
* @param requestCode
*/
MainActivity如下:
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE = 0;
private BluetoothController mController=new BluetoothController();
//这里是个延时创建
private Toast mToast;
private BroadcastReceiver receiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int state=intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,-1);
switch (state){
case BluetoothAdapter.STATE_OFF:
showToast("STATE_OFF");
break;
case BluetoothAdapter.STATE_ON:
showToast("STATE_ON");
break;
case BluetoothAdapter.STATE_TURNING_ON:
//正在打开,蓝牙打开是个一步操作
showToast("STATE_TURNING_ON");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
showToast("STATE_TURNING_OFF");
break;
default:
showToast("Unkonw STATE");
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在开始的时候需要注册一个处理蓝牙的广播
IntentFilter filter=new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
//注册广播
registerReceiver(receiver,filter);
}
public void isSupportBlueTooth(View view){
boolean ret=mController.isSupportBlueTooth();
showToast("支持蓝牙"+ret);
}
public void isBlueToothEable(View view){
boolean ret=mController.getBlueToothStatus();
showToast("蓝牙可用"+ret);
}
public void requestTurnOnBlueTooth(View view){
mController.turnOnBluetooth(this,REQUEST_CODE);
// showToast("蓝牙可用"+ret);
}
public void turnOffBlueTooth(View view){
mController.turnOffBlueTooth();
}
private void showToast(String text){
if(mToast==null){
mToast=Toast.makeText(this,text,Toast.LENGTH_SHORT);
}
else {
mToast.setText(text);
}
mToast.show();
}
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
super.onActivityResult(requestCode,resultCode,data);
if(requestCode == RESULT_OK){
showToast("打开成功");
}
else{
showToast("打开失败");
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/is_support_blue_tooth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="isSupportBlueTooth"
android:text="@string/support_bluetooth" />
<Button
android:id="@+id/is_blue_tooth_enable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="isBlueToothEable"
android:text="@string/is_turn_on" />
<Button
android:id="@+id/turn_on_blue_tooth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="requestTurnOnBlueTooth"
android:text="@string/turn_on" />
<Button
android:id="@+id/turn_off_blue_tooth"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="turnOffBlueTooth"
android:text="@string/turn_off" />
</LinearLayout>
第一阶段开发完毕
第二阶段:
打开可见,已邦设备,查找设备(查找过程,会有进度条)
Maniactivity:
public class MainActivity extends AppCompatActivity {
private List<BluetoothDevice> mDeviceList = new ArrayList<>();
private List<BluetoothDevice> mBondedDeviceList = new ArrayList<>();
private static final int REQUEST_CODE = 0;
private BluetoothController mController = new BluetoothController();
private DeviceAdapter mAdapter;
private ListView mListView;
//这里是个延时创建
private Toast mToast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initActionBar();
setContentView(R.layout.activity_main);
initUI();
IntentFilter filter = new IntentFilter();
//在开始的时候需要注册一个处理蓝牙的广播
// IntentFilter filter=new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
//开始查找
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
//结束查找
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
//设备扫描模式改变,被看见有广播,不被看见也有广播过来
filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
//绑定状态
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//注册广播
registerReceiver(mReceiver, filter);
mController.turnOnBluetooth(this, REQUEST_CODE);
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
//开始查找,查找上会有一个进度条,设别开始查找
setSupportProgressBarIndeterminateVisibility(true);
//初始数据列表
//设备清空
mDeviceList.clear();
//发送通知,关闭进度条等等
mAdapter.notifyDataSetChanged();
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
setSupportProgressBarIndeterminateVisibility(false);
}
//字符串的比较,有常量的放前面,可以防止为空报空指针异常的情况
//找到设备,就会有ACTION_FOUND这个广播,在广播的
else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//得device是我们查找的数据,找到一个,就添加一个
mDeviceList.add(device);
mAdapter.notifyDataSetChanged();
setSupportProgressBarIndeterminateVisibility(false);
} else if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) {
//scanMode为SCAN_MODE_CONNECTABLE_DISCOVERABLE,就让他可见
int scanMode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, 0);
if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
// 进度条转动,友好的人机交互,时间到了timeout就不可见。默认蓝牙扫描是12秒。
setProgressBarIndeterminateVisibility(true);
} else {
//进度条结束,设备不可见,通过ui给出提示,这比较友好,有互动,这就是广播的应用。
setProgressBarIndeterminateVisibility(false);
}
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (remoteDevice == null) {
showToast("没有设备");
return;
}
int status = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, 0);
if (status == BluetoothDevice.BOND_BONDED) {
}
}
}
};
public void isSupportBlueTooth(View view) {
boolean ret = mController.isSupportBlueTooth();
showToast("支持蓝牙" + ret);
}
public void isBlueToothEable(View view) {
boolean ret = mController.getBlueToothStatus();
showToast("蓝牙可用" + ret);
}
public void requestTurnOnBlueTooth(View view) {
mController.turnOnBluetooth(this, REQUEST_CODE);
// showToast("蓝牙可用"+ret);
}
public void turnOffBlueTooth(View view) {
mController.turnOffBlueTooth();
}
private void showToast(String text) {
if (mToast == null) {
mToast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
} else {
mToast.setText(text);
}
mToast.show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_OK) {
showToast("打开成功");
} else {
showToast("打开失败");
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.enable_visiblity) {
//打开蓝牙,使其可见,广播监听什么时候可见,什么时候不可见
mController.enableVisibly(this);
} else if (id == R.id.find_device) {
//查找设备
//每个设备点击后,都可进行绑定
mAdapter.refresh(mDeviceList);
mController.findDevice();
// 查找结果是通过广播传过来的
mListView.setOnItemClickListener(bindDeviceClick);
} else if (id == R.id.bonded_device) {
//查看已邦设备
//获取设备后,刷新
mBondedDeviceList = mController.getBondedDeviceList();
mAdapter.refresh(mBondedDeviceList);
//如果是完整流程,可以解绑定,将numl换成别的
mListView.setOnItemClickListener(null);
}
return super.onOptionsItemSelected(item);
}
private AdapterView.OnItemClickListener bindDeviceClick = new AdapterView.OnItemClickListener() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
BluetoothDevice device = mDeviceList.get(i);
//每个设备,点一下,就创建绑定
device.createBond();
}
};
//手机蓝牙被其他设备所发现
}
BluetoothController功能几乎不变。
package com.lmj.bluuetoothdemo;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import java.util.ArrayList;
import java.util.List;
//设置蓝牙被别的设备检查到
public class BluetoothController {
/* 本地蓝牙适配器*/
private BluetoothAdapter mAdapter;
public BluetoothController(){
mAdapter=BluetoothAdapter.getDefaultAdapter();
}
public boolean isSupportBlueTooth() {
if (mAdapter != null) {
//支持蓝牙,一般设备都支持蓝牙
return true;
} else {
return false;
}
}
public boolean getBlueToothStatus(){
//判断蓝牙状态,true为打开,false为关闭
//如果不支持,则会空指针,所以我们在mAdapter里加个断点函数
assert(mAdapter!=null);
return mAdapter.isEnabled();
}
/**
*打开蓝牙
* @param activity
* @param requestCode
*/
//系统主动调,一般不要设置成手动调用
public void turnOnBluetooth(Activity activity,int requestCode){
//通过intent获取蓝牙,action_request_enable请求可用
Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//知道它的返回结果
activity.startActivityForResult(intent,requestCode);
//设置成自动调用
mAdapter.enable();
}
public void enableVisibly(Context context){
Intent discoverableIntent=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
//可发生的时间做一个intent。
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);
//不需要forResult,因为设备不止一个,通过广播来作用
context.startActivity(discoverableIntent);
}
public void findDevice(){
assert(mAdapter!=null);
mAdapter.startDiscovery();
}
/**
* 获取绑定设备
* @return
*/
public List<BluetoothDevice>getBondedDeviceList(){
return new ArrayList<>(mAdapter.getBondedDevices());
}
public void turnOffBlueTooth() {
mAdapter.disable();
}
}
DeviceAdapter:
public class DeviceAdapter extends BaseAdapter {
private List<BluetoothDevice> mData;
private Context mContext;
public DeviceAdapter(List<BluetoothDevice>data,Context context){
mData=data;
//默认数据为空
mContext=context.getApplicationContext();
}
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
View itemView=view;
//复用veiw,优化性能
if(itemView==null){
//传下来的view为空,就创建一次,用android自带的简单simple_list_item_2来绘制view
itemView=LayoutInflater.from(mContext).inflate(android.R.layout.simple_list_item_2,viewGroup,false);
}
TextView line1=(TextView)itemView.findViewById(android.R.id.text1);
TextView line2=(TextView)itemView.findViewById(android.R.id.text2);
//获取对应的蓝牙设备
BluetoothDevice device=(BluetoothDevice)getItem(i);
//第一行显示名称
line1.setText(device.getName());
line2.setText(device.getAddress());
//第二行显示地址
return itemView;
}
public void refresh(List<BluetoothDevice>data){
mData=data;
//刷新一次数据,就发一次通知,注册的是观察者模式
notifyDataSetChanged();
}
}