第6天Android蓝牙4.0
动态权限的使用
6.2. 开关蓝牙
6.3. 蓝牙配对
6.4. 蓝牙传输
一.蓝牙介绍:
是一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换,我们主要掌握这几项技能:
添加权限:
<!-- 用于进行网络定位 -->
<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();
MainActivity代码
public class MainActivity extends AppCompatActivity {
private UUID uuid = UUID.fromString("00001106-0000-1000-8000-00805F9B34FB");
BluetoothManager manager;
Button button1;
Button button2;
Button button3;
Button button4;
ListView listView;
ListView listView2;
MyRecevier myRecevier;
BluetoothAdapter adapter;
String[] strings = new String[]{Manifest.permission.BLUETOOTH,Manifest.permission.BLUETOOTH_ADMIN,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION};
List<BluetoothDevice> list = new ArrayList<>();
List<BluetoothDevice> list2 = new ArrayList<>();
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//动态获取权限
if (Build.VERSION.SDK_INT>=23){//安卓6.0以后的手机
//判断是否授予过
if (ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
requestPermissions(strings,101);//动态获取权限
}
}
initBluetooth();
button1 = findViewById(R.id.bt1);
button2 = findViewById(R.id.bt2);
button3 = findViewById(R.id.bt3);
button4 = findViewById(R.id.bt4);
listView = findViewById(R.id.list1);
listView2 = findViewById(R.id.list2);
//注册广播
myRecevier = new MyRecevier();
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
registerReceiver(myRecevier,intentFilter);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
open();
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
close();
}
});
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
search();
}
});button4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
show();
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final BluetoothDevice device = list.get(position);
device.createBond();
}
});
listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final BluetoothDevice device = list2.get(position);
try {
final BluetoothSocket rfcommSocketToServiceRecord = device.createRfcommSocketToServiceRecord(uuid);
rfcommSocketToServiceRecord.connect();//建立连接
final OutputStream outputStream = rfcommSocketToServiceRecord.getOutputStream();
outputStream.write("徐绅迪".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public void open() {
//打开蓝牙并设置并允许被搜索
Intent intent1 = new Intent();
intent1.setAction(BluetoothAdapter.ACTION_REQUEST_ENABLE);//开启蓝牙
intent1.setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//设置被扫描
intent1.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,200);//设置被扫描的时长
startActivity(intent1);
new Thread(new Runnable() {
@Override
public void run() {
try {
final BluetoothServerSocket bluetoothServerSocket = adapter.listenUsingInsecureRfcommWithServiceRecord(adapter.getName(), uuid);
while (true){
final BluetoothSocket socket = bluetoothServerSocket.accept();
new SeverThread(socket,MainActivity.this).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
public void close() {
adapter.disable();
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void initBluetooth() {
manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
adapter = manager.getAdapter();
if (adapter == null){
Toast.makeText(this, "蓝牙设备故障", Toast.LENGTH_SHORT).show();
return;
}
}
private void search() {
adapter.startDiscovery();//开始扫描
}
class MyRecevier extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)){
//获得远程的蓝牙设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getName()!=null){
list.add(device);
final MyAdpter myAdpter = new MyAdpter(list, MainActivity.this);
myAdpter.notifyDataSetChanged();
listView.setAdapter(myAdpter);
}
}
}
}
private void show() {
list2.clear();
final Set<BluetoothDevice> bondedDevices = adapter.getBondedDevices();
list2.addAll(bondedDevices);
final MyAdpter myAdpter = new MyAdpter(list2, MainActivity.this);
myAdpter.notifyDataSetChanged();
listView2.setAdapter(myAdpter);
}
}
线程一直接收消息
public class SeverThread extends Thread{
private BluetoothSocket socket;
private Activity context;
public SeverThread(BluetoothSocket socket, Activity context) {
this.socket = socket;
this.context = context;
}
@Override
public void run() {
super.run();
context.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, "有人要给我发数据", Toast.LENGTH_SHORT).show();
}
});
InputStream inputStream = null;
try {
inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes))!=-1){
final String s = new String(bytes, 0, len);
context.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, ""+s, Toast.LENGTH_SHORT).show();
}
});
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}