藍牙
是一種無線技術標準,可實現固定設備、移動設備和樓宇個人域網之間的短距離數據交換
關於藍牙的權限主要涉及到下面三個:
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();
}
}
}
}