蓝牙设备
是一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换,我们主要掌握这几项技能:
添加权限:
<!-- 用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH"/>
打开蓝牙并设置允许被搜索:
//调用系统开关蓝牙弹窗->用户手动允许
Intent intent = new Intent();
intent.setAction(BluetoothAdapter.ACTION_REQUEST_ENABLE);//开启蓝
intent.setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//允许蓝牙被搜索
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,200);//设置允许被搜索时间200s内可以被搜索到
startActivityForResult(intent,100);
关闭蓝牙:
bluetoothAdapter.disable();//强制关闭蓝牙
搜索附近的蓝牙:
bluetoothAdapter.startDiscovery();//搜索
配对蓝牙:
bluetoothDevice.createBond();//发起配对
获得已经配对的蓝牙设备:
adapter.getBondedDevices();
使用蓝牙传输数据:socket和ServerSocket传输数据:
//1.获得客户端Socket
BluetoothSocket socket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
socket.connect();
//2.获得服务端Socket
BluetoothServerSocket serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(bluetoothAdapter.getName(),uuid);
serverSocket.accpet();
蓝牙工作原理以及涉及到的类:
BluetoothManager 蓝牙管理类,管理BluetoothAdapter。主要负责管理蓝牙的本地连接。
BluetoothAdapter 蓝牙适配器类:代表本蓝牙设备
BluetoothDevice 蓝牙设备,配对后的远程蓝牙设备.
BluetoothServiceSocket 服务端连接类
BluetoothSocket:客户端连接类
UUID(universal unique identifier , 全局唯一标识符)
格式如下:UUID格式一般是”xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,可到http://www.uuidgenerator.com 申请。UUID分为5段,是一个8-4-4-4-12的字符串,这个字符串要求永不重复。蓝牙建立连接时双方必须使用固定的UUID
例如:文件传输服务
OBEXFileTransferServiceClass_UUID = ‘{00001106-0000-1000-8000-00805F9B34FB}’
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private UUID uuid = UUID.fromString("00001106-0000-1000-8000-00805F9B34FB");
private Button open;
private Button close;
private Button search;
private Button show;
private RecyclerView rv_show;
private RecyclerView rv_search;
MyReceiver myReceiver;
ArrayList<BluetoothDevice> list=new ArrayList<>();
ArrayList<BluetoothDevice> arrayList=new ArrayList<>();
String[] strings=new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH
};
BluetoothManager bluetoothManager;//蓝牙管理者
BluetoothAdapter bluetoothAdapter;//本机蓝牙设备
BaseRvAdapter adapter;
BaseRvAdapter adapters;
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==101){
Toast.makeText(MainActivity.this, ""+msg.obj, Toast.LENGTH_SHORT).show();
}
}
};
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT>=23){
for (int i = 0; i < strings.length; i++) {
int permission = ActivityCompat.checkSelfPermission(this, strings[i]);
if (permission== PackageManager.PERMISSION_DENIED){
requestPermissions(strings,101);
break;
}
}
}
initView();
myReceiver =new MyReceiver();
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
registerReceiver(myReceiver,intentFilter);
bluetoothManager= (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
bluetoothAdapter=bluetoothManager.getAdapter();
adapter=new BaseRvAdapter(list,this,R.layout.item_layout) {
@Override
public void bind(BaseRvViewHolder baseRvViewHolder, int i) {
baseRvViewHolder.setTextViewText(R.id.tv_id,list.get(i).getName());
baseRvViewHolder.setTextViewText(R.id.tv_text,list.get(i).getAddress());
}
};
rv_show.setLayoutManager(new LinearLayoutManager(this));
adapter.notifyDataSetChanged();
rv_show.setAdapter(adapter);
adapters=new BaseRvAdapter(arrayList,this,R.layout.item_layout) {
@Override
public void bind(BaseRvViewHolder baseRvViewHolder, int i) {
baseRvViewHolder.setTextViewText(R.id.tv_id,arrayList.get(i).getName());
baseRvViewHolder.setTextViewText(R.id.tv_text,arrayList.get(i).getAddress());
}
};
rv_search.setLayoutManager(new LinearLayoutManager(this));
adapters.notifyDataSetChanged();
rv_search.setAdapter(adapters);
adapter.setMyOnItemClickListener(new MyOnItemClickListener() {
@Override
public void myOnItemClickListener(int position) {
BluetoothDevice bluetoothDevice = list.get(position);
try {
BluetoothSocket socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);
socket.connect();
socket.getOutputStream().write("听说你不想努力了".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
});
adapters.setMyOnItemClickListener(new MyOnItemClickListener() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void myOnItemClickListener(int position) {
bluetoothAdapter.cancelDiscovery();
arrayList.get(position).createBond();
}
});
}
private void initView() {
open = (Button) findViewById(R.id.open);
close = (Button) findViewById(R.id.close);
search = (Button) findViewById(R.id.search);
show = (Button) findViewById(R.id.show);
rv_show = (RecyclerView) findViewById(R.id.rv_show);
rv_search = (RecyclerView) findViewById(R.id.rv_search);
open.setOnClickListener(this);
close.setOnClickListener(this);
search.setOnClickListener(this);
show.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.open://打开蓝牙:使用隐士意图
open();
break;
case R.id.close:
bluetoothAdapter.disable();//关闭蓝牙
break;
case R.id.search:
arrayList.clear();
bluetoothAdapter.startDiscovery();//扫描附件的蓝牙设备
break;
case R.id.show:
show();
break;
}
}
public void open(){
Intent intent=new Intent();
intent.setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
intent.setAction(BluetoothAdapter.ACTION_REQUEST_ENABLE);
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,200);
startActivityForResult(intent,100);
new Thread(new Runnable() {
@Override
public void run() {
try {
BluetoothServerSocket serverSocket = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(bluetoothAdapter.getName(), uuid);
while (true){
BluetoothSocket socket = serverSocket.accept();
new MyThread(socket,handler).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
public void show(){
list.clear();
Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
for (BluetoothDevice bondedDevice : bondedDevices) {
Log.e("###",bondedDevice.getName());
Log.e("###",bondedDevice.getAddress());
list.add(bondedDevice);
}
adapter.notifyDataSetChanged();
}
class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)){
BluetoothDevice parcelableExtra = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
arrayList.add(parcelableExtra);
adapters.notifyDataSetChanged();
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver);
}
}
public class MyThread extends Thread {
BluetoothSocket socket;
Handler handler;
public MyThread(BluetoothSocket socket, Handler handler) {
this.socket = socket;
this.handler = handler;
}
@Override
public void run() {
super.run();
try {
StringBuffer sb=new StringBuffer();
InputStream inputStream = socket.getInputStream();
int len =0;
byte[] bytes=new byte[1024];
while ((len=inputStream.read(bytes))!=-1){
sb.append(new String(bytes,0,len));
Message message = Message.obtain();
message.what=101;
message.obj=sb.toString();
handler.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:text="打开蓝牙"
android:id="@+id/open"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
<Button
android:text="关闭蓝牙"
android:id="@+id/close"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
<Button
android:text="搜索蓝牙"
android:id="@+id/search"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
<Button
android:text="显示已经配对"
android:id="@+id/show"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
<TextView
android:background="#D5D6D6"
android:text="已经配对设备"
android:layout_weight="0.2"
android:layout_width="match_parent"
android:layout_height="0dp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_show"
android:layout_weight="3"
android:layout_width="match_parent"
android:layout_height="0dp"></android.support.v7.widget.RecyclerView>
<TextView
android:background="#D5D6D6"
android:text="附近的设备"
android:layout_weight="0.2"
android:layout_width="match_parent"
android:layout_height="0dp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_search"
android:layout_weight="3"
android:layout_width="match_parent"
android:layout_height="0dp"></android.support.v7.widget.RecyclerView>
</LinearLayout>