国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

詳解Android――藍牙技術 帶你實現終端間數據傳輸

2019-12-12 04:20:28
字體:
來源:轉載
供稿:網友

藍牙技術在智能硬件方面有很多用武之地,今天我就為大家分享一下藍牙在Android系統下的使用方法技巧,并實現一下兩個終端間數據的傳輸。

藍牙(Bluetooth)是一種短距離的無線通信技術標準,藍牙協議分為4層,即核心協議層、電纜替代協議層、電話控制協議層和采納的其它協議層。

這4種協議中最重要的是核心協議。藍牙的核心協議包括基帶、鏈路管理、邏輯鏈路控制和適應協議四部分。其中鏈路管理(LMP)負責藍牙組件間連接的建立。邏輯鏈路控制與適應協議(L2CAP)位于基帶協議層上,屬于數據鏈路層,是一個為高層傳輸和應用層協議屏蔽基帶協議的適配協議。

1.打開和關閉藍牙

第一種方法相對簡單,直接調用系統對話框啟動藍牙:

在AndroidManifest文件中添加需要的權限,高版本也不需要動態授權:

<uses-permission android:name="android.permission.BLUETOOTH" />
startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), 1);

第一種方法

如果不想讓用戶看到這個對話框,那么我們還可以選擇第二種方法,進行靜默開啟藍牙。

第二種方法,靜默開啟,不會有方法一的對話框:

在AndroidManifest文件中添加需要的權限:

<!-- 已適配Android6.0 --><uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-feature  android:name="android.hardware.bluetooth_le"  android:required="true" />

由于藍牙所需要的權限包含Dangerous Permissions,所以我們需要在Java代碼中進行動態授權處理:

private static final int REQUEST_BLUETOOTH_PERMISSION=10;private void requestBluetoothPermission(){  //判斷系統版本  if (Build.VERSION.SDK_INT >= 23) {    //檢測當前app是否擁有某個權限    int checkCallPhonePermission = ContextCompat.checkSelfPermission(this,         Manifest.permission.ACCESS_COARSE_LOCATION);    //判斷這個權限是否已經授權過    if(checkCallPhonePermission != PackageManager.PERMISSION_GRANTED){      //判斷是否需要 向用戶解釋,為什么要申請該權限      if(ActivityCompat.shouldShowRequestPermissionRationale(this,           Manifest.permission.ACCESS_COARSE_LOCATION))        Toast.makeText(this,"Need bluetooth permission.",             Toast.LENGTH_SHORT).show();      ActivityCompat.requestPermissions(this ,new String[]          {Manifest.permission.ACCESS_COARSE_LOCATION},REQUEST_BLUETOOTH_PERMISSION);      return;    }else{    }  } else {  }}

接下來我們就可以靜默開啟藍牙了:

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();mBluetoothAdapter.enable(); //開啟//mBluetoothAdapter.disable(); //關閉

下面我們來看一下如何通過代碼搜索藍牙設備。

2.通過代碼搜索藍牙設備

搜索分為主動搜索和被動搜索。

我們開始進行主動搜索:

(1)創建BluetoothAdapter對象

TextView tvDevices = (TextView)findViewById(R.id.tv_devices);BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

(2)我們先獲取并顯示一下已經配對的藍牙設備列表

//獲取已經配對的藍牙設備Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();if (pairedDevices.size() > 0) {  for (BluetoothDevice device : pairedDevices) {    tvDevices.append(device.getName() + ":" + device.getAddress());  }}

(3)下面我們定義廣播接收器

// 設置廣播信息過濾IntentFilter filter = new IntentFilter();filter.addAction(BluetoothDevice.ACTION_FOUND);//每搜索到一個設備就會發送一個該廣播filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//當全部搜索完后發送該廣播filter.setPriority(Integer.MAX_VALUE);//設置優先級// 注冊藍牙搜索廣播接收者,接收并處理搜索結果this.registerReceiver(receiver, filter);

藍牙設備的廣播接收器如下:

/** * 定義廣播接收器 */private final BroadcastReceiver receiver = new BroadcastReceiver() {  @Override  public void onReceive(Context context, Intent intent) {    String action = intent.getAction();    if (BluetoothDevice.ACTION_FOUND.equals(action)) {      BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);      if (device.getBondState() != BluetoothDevice.BOND_BONDED) {        tvDevices.append(device.getName() + ":"+ device.getAddress());      }    } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {      //已搜素完成    }  }};

(4)我們創建一個Button按鈕,當點擊Button時進行搜索,Button點擊事件如下:

//如果當前在搜索,就先取消搜索if (mBluetoothAdapter.isDiscovering()) {  mBluetoothAdapter.cancelDiscovery();}//開啟搜索mBluetoothAdapter.startDiscovery();

搜索藍牙設備

3.藍牙的UUID

兩個藍牙設備進行連接時需要使用同一個UUID。但很多讀者可能發現,有很多型號的手機(可能是非Android系統的手機)之間使用了不同的程序也可以使用藍牙進行通訊。從表面上看,它們之間幾乎不可能使用同一個UUID。

UUID的格式如下:

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

UUID的格式被分成5段,其中中間3段的字符數相同,都是4,第1段是8個字符,最后一段是12個字符。所以UUID實際上是一個8-4-4-4-12的字符串。

實際上,UUID和TCP的端口一樣,也有一些默認的值。例如,將藍牙模擬成串口的服務就使用了一個標準的UUID:

00001101-0000-1000-8000-00805F9B34FB

除此之外,還有很多標準的UUID,如下面就是兩個標準的UUID:

信息同步服務:00001104-0000-1000-8000-00805F9B34FB

文件傳輸服務:00001106-0000-1000-8000-00805F9B34FB

4.藍牙終端間數據傳輸

通過藍牙傳輸數據與Socket類似。在網絡中使用Socket和ServerSocket控制客戶端和服務端的數據讀寫。而藍牙通訊也由客戶端和服務端Socket來完成。藍牙客戶端Socket是BluetoothSocket,藍牙服務端Socket是BluetoothServerSocket。這兩個類都在android.bluetooth包中。

無論是BluetoothSocket,還是BluetoothServerSocket,都需要一個UUID(全局唯一標識符,Universally Unique Identifier),UUID相當于Socket的端口,而藍牙地址相當于Socket的IP。

我們開始進行模擬一個藍牙數據的傳輸:

首先來看客戶端:

(1)定義全局常量變量

private ListView lvDevices;private BluetoothAdapter mBluetoothAdapter;private List<String> bluetoothDevices = new ArrayList<String>();private ArrayAdapter<String> arrayAdapter;private final UUID MY_UUID = UUID    .fromString("abcd1234-ab12-ab12-ab12-abcdef123456");//隨便定義一個private BluetoothSocket clientSocket;private BluetoothDevice device; private OutputStream os;//輸出流

(2)在onCreate方法中做初始化操作

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();lvDevices = (ListView) findViewById(R.id.lv_devices);//獲取已經配對的藍牙設備Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();if (pairedDevices.size() > 0) {  for (BluetoothDevice device : pairedDevices) {    bluetoothDevices.add(device.getName() + ":"+ device.getAddress());  }}arrayAdapter = new ArrayAdapter<String>(this,    android.R.layout.simple_list_item_1, android.R.id.text1,bluetoothDevices);lvDevices.setAdapter(arrayAdapter);lvDevices.setOnItemClickListener(this);//Activity實現OnItemClickListener接口//每搜索到一個設備就會發送一個該廣播IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);this.registerReceiver(receiver, filter);//當全部搜索完后發送該廣播filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);this.registerReceiver(receiver, filter);

藍牙設備的廣播接收器如下:

/** * 定義廣播接收器 */private final BroadcastReceiver receiver = new BroadcastReceiver() {  @Override  public void onReceive(Context context, Intent intent) {    String action = intent.getAction();    if (BluetoothDevice.ACTION_FOUND.equals(action)) {      BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);      if (device.getBondState() != BluetoothDevice.BOND_BONDED) {        bluetoothDevices.add(device.getName() + ":" + device.getAddress());        arrayAdapter.notifyDataSetChanged();//更新適配器      }    } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {      //已搜素完成    }  }};

(4)我們創建一個Button按鈕,當點擊Button時進行搜索,Button點擊事件如下:

//如果當前在搜索,就先取消搜索if (mBluetoothAdapter.isDiscovering()) {  mBluetoothAdapter.cancelDiscovery();}//開啟搜索mBluetoothAdapter.startDiscovery();

(5)接下來我們設置列表的點擊事件:

@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {  String s = arrayAdapter.getItem(position);  String address = s.substring(s.indexOf(":") + 1).trim();//把地址解析出來  //主動連接藍牙服務端  try {    //判斷當前是否正在搜索    if (mBluetoothAdapter.isDiscovering()) {      mBluetoothAdapter.cancelDiscovery();    }    try {      if (device == null) {        //獲得遠程設備        device = mBluetoothAdapter.getRemoteDevice(address);      }      if (clientSocket == null) {        //創建客戶端藍牙Socket        clientSocket = device.createRfcommSocketToServiceRecord(MY_UUID);        //開始連接藍牙,如果沒有配對則彈出對話框提示我們進行配對        clientSocket.connect();        //獲得輸出流(客戶端指向服務端輸出文本)        os = clientSocket.getOutputStream();      }    } catch (Exception e) {    }    if (os != null) {      //往服務端寫信息      os.write("藍牙信息來了".getBytes("utf-8"));    }  } catch (Exception e) {  }}

接下來看服務端:

服務端使用的是另一部手機,接受上面手機通過藍牙發送過來的信息并顯示。

(1)定義全局常量變量:

private BluetoothAdapter mBluetoothAdapter;private AcceptThread acceptThread;private final UUID MY_UUID = UUID    .fromString("abcd1234-ab12-ab12-ab12-abcdef123456");//和客戶端相同的UUIDprivate final String NAME = "Bluetooth_Socket";private BluetoothServerSocket serverSocket;private BluetoothSocket socket;private InputStream is;//輸入流

(2)定義服務端線程類:

private Handler handler = new Handler() {  public void handleMessage(Message msg) {    Toast.makeText(getApplicationContext(), String.valueOf(msg.obj),        Toast.LENGTH_LONG).show();    super.handleMessage(msg);  }};//服務端監聽客戶端的線程類private class AcceptThread extends Thread {  public AcceptThread() {    try {      serverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);    } catch (Exception e) {    }  }  public void run() {    try {      socket = serverSocket.accept();      is = socket.getInputStream();      while(true) {        byte[] buffer =new byte[1024];        int count = is.read(buffer);        Message msg = new Message();        msg.obj = new String(buffer, 0, count, "utf-8");        handler.sendMessage(msg);      }    }    catch (Exception e) {    }  }}

(3)在onCreate方法中初始化線程類并開啟

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();acceptThread = new AcceptThread();acceptThread.start();

我們運行程序看一下效果圖:

client

點擊“搜索藍牙設備”按鈕,就會搜索到另一臺手機的藍牙信息,我們點擊條目,另一臺手機會出現如下變化:

server

彈出Toast,此時證明我們的藍牙數據已經傳輸過來了。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 南充市| 深州市| 堆龙德庆县| 紫阳县| 成武县| 长乐市| 同心县| 新乡市| 拉萨市| 呼伦贝尔市| 从江县| 灵武市| 偏关县| 阿拉善右旗| 大竹县| 都兰县| 宜兰市| 翁源县| 绍兴市| 涿州市| 武功县| 新建县| 咸阳市| 伊金霍洛旗| 武穴市| 镇原县| 临泉县| 冕宁县| 新乐市| 博客| 疏附县| 中宁县| 茶陵县| 汤阴县| 福建省| 元阳县| 葫芦岛市| 托克逊县| 溆浦县| 云阳县| 托里县|