蓝牙
是一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换
关于蓝牙的权限主要涉及到下面三个:
BLUETOOTH:允许配对的设备进行连接
BLUETOOTH_ADMIN:允许搜索和配对设备
ACCESS_COARSE_LOCATION:广播接收器接收BluetoothDevice.ACTION_FOUND广播需要改权限
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
一些介绍
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}’
真机测试效果
代码案例
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/block"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="打开蓝牙"
/>
<Button
android:id="@+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="关闭蓝牙"
/>
<Button
android:id="@+id/get"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获得已经配对的蓝牙设备"
/>
<Button
android:id="@+id/search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="搜索附近的蓝牙"
/>
<ListView
android:layout_weight="1"
android:id="@+id/listid"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
Activity中的代码
package com.example.day006;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.Parcelable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
private Button close;
private Button get;
private Button search;
private Button block;
private ListView listid;
private BluetoothAdapter adapter;
private MyRecevir myRecevir;
private Myadpater myadpater;
private BluetoothDevice device2;
private List<BluetoothDevice> devicecs = new ArrayList<>();//其他蓝牙列表
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
close = (Button) findViewById(R.id.close);
get = (Button) findViewById(R.id.get);
search = (Button) findViewById(R.id.search);
block = (Button) findViewById(R.id.block);
listid = (ListView) findViewById(R.id.listid);
myRecevir=new MyRecevir();
//注册广播接收者
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);//注册搜索蓝牙的广播
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//启动线程
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//显示到listview
registerReceiver(myRecevir,intentFilter);
//权限
String[] string=new String[]{Manifest.permission.BLUETOOTH,Manifest.permission.BLUETOOTH_ADMIN,Manifest.permission.ACCESS_FINE_LOCATION};
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION )!= PackageManager.PERMISSION_GRANTED){
requestPermissions(string,101);
}
}
BluetoothManager manager= (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
adapter = manager.getAdapter();
//开启蓝牙
block.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(BluetoothAdapter.ACTION_REQUEST_ENABLE);//自己可见可用
intent.setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//允许被扫描
// intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,200);//设置被扫描的时长
startActivity(intent);
}
});
//关闭蓝牙
close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
adapter.disable();
}
});
//获得
get.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
adapter.getBondedDevices();
}
});
//搜索蓝牙(扫描)
search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
adapter.startDiscovery();
}
});
listid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
BluetoothDevice device=devicecs.get(position);
device.createBond();//绑定蓝牙
}
});
}
class MyRecevir extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//收其他搜索的蓝牙
if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)){//是查找的功能
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i(TAG, "onReceive: "+device.getName());
devicecs.add(device);
}else if (intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)){
//将所有的蓝牙设备显示到界面上
myadpater = new Myadpater(MainActivity.this,devicecs);
listid.setAdapter(myadpater);
} else if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
device2= intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int state = device2.getBondState();
if (state==BluetoothDevice.BOND_BONDED){//已经绑定
new ClientThread().start();
}
}
}
}
//客户端代码
class ClientThread extends Thread{
@Override
public void run() {
super.run();
UUID uuid=UUID.fromString("00001106-0000-1000-8000-00805F9B34FB");
try {
BluetoothSocket socket = device2.createRfcommSocketToServiceRecord(uuid);
socket.connect();//建立socket连接
OutputStream outputStream=socket.getOutputStream();
FileInputStream inputStream=new FileInputStream(Environment.getExternalStorageDirectory().getAbsoluteFile()+"/baoke.txt");
int len=0;
byte[] b=new byte[1024];
while ((len=inputStream.read(b))!=-1){
outputStream.write(b,0,len);
// outputStream.write("你好呀".getBytes());
outputStream.flush();
}
outputStream.close();
// inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void receveFromserver(BluetoothSocket socket){
try {
InputStream inputStream = socket.getInputStream();
int len=0;
byte[] b=new byte[1024];
FileOutputStream outputStream = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsoluteFile()+"/http.txt");
while ((len=inputStream.read(b))!=-1){
outputStream.write(b,0,len);
}
inputStream.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}