Andriod studio 學習 之 藍牙

藍牙

是一種無線技術標準,可實現固定設備、移動設備和樓宇個人域網之間的短距離數據交換

關於藍牙的權限主要涉及到下面四個:

BLUETOOTH:允許配對的設備進行連接

BLUETOOTH_ADMIN:允許搜索和配對設備

ACCESS_COARSE_LOCATION:廣播接收器接收BluetoothDevice.ACTION_FOUND廣播需要改權限
ACCESS_FINE_LOCATION

<uses-permission android:name="android.permission.BLUETOOTH" />

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

<uses-permission android:name="android.permission.ACCESS_FINE_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=".client.BlueClient">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/open"
            android:text="打開藍牙"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/close"
            android:text="關閉藍牙"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/search"
            android:text="掃描藍牙"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/pair"
            android:text="已配對的藍牙"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/server"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="服務器收到消息"
            />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ListView
            android:id="@+id/nearblue"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent"></ListView>
        <ListView
            android:id="@+id/alerady"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent"></ListView>
    </LinearLayout>
</LinearLayout>

適配器xml佈局

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/blueid"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        />
</LinearLayout>

適配器中的代碼

      package com.example.bluetooth.client;

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.example.bluetooth.R;

import java.util.ArrayList;

public class Mybondedadpater extends BaseAdapter {
    private Context context;
    private ArrayList<BluetoothDevice> list;

    public Mybondedadpater(Context context, ArrayList<BluetoothDevice> list) {
        this.context = context;
        this.list = list;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Viewholder viewholder;
        if (convertView==null){
            convertView = LayoutInflater.from(context).inflate(R.layout.bonded_item, null);
            viewholder = new Viewholder();
            viewholder.blue = convertView.findViewById(R.id.blueid);
            convertView.setTag(viewholder);
        }else {
            viewholder = (Viewholder) convertView.getTag();
        }
        viewholder.blue.setText(list.get(position).getName());
        return convertView;
    }
    class Viewholder{
        TextView blue;
    }
}

activity代碼

    package com.example.bluetooth.client;

import android.Manifest;
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.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.example.bluetooth.R;
import com.example.bluetooth.Server.BlueSever;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;

public class BlueClient extends AppCompatActivity {
    private Button open;
    private Button close;
    private Button search;
    private Button pair;
    private ListView nearblue;
    private ListView alerady;
    private BluetoothAdapter adapter;
    private ArrayList<BluetoothDevice> list = new ArrayList<>();
    private Mybondedadpater mybondedadpater;

    private Mybondedadpater mysearchadpater;
    private BluetoothDevice bluetoothDevice;
    private ArrayList<BluetoothDevice> devices = new ArrayList<>();
    private Mybroad mybroad;
    private Button server;
    private Handler handler =new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what==101){
                Toast.makeText(BlueClient.this, msg.obj.toString()+"連接成功", Toast.LENGTH_SHORT).show();
                Log.i("連接成功", "handleMessage: "+msg.obj.toString());
            }else if (msg.what==102){
                Toast.makeText(BlueClient.this, "接收到數據"+msg.obj.toString(), Toast.LENGTH_SHORT).show();
                Log.i("接收到數據", "handleMessage: "+msg.obj.toString());
            }
        }
    };
    private UUID uuid = UUID.fromString("00001106-0000-1000-8000-00805F9B34FB");
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_blue_client);

        open = (Button) findViewById(R.id.open);
        close = (Button) findViewById(R.id.close);
        search = (Button) findViewById(R.id.search);
        pair = (Button) findViewById(R.id.pair);
        nearblue = (ListView) findViewById(R.id.nearblue);
        alerady = (ListView) findViewById(R.id.alerady);
        server = (Button) findViewById(R.id.server);


        String[] s={Manifest.permission.BLUETOOTH,Manifest.permission.BLUETOOTH_ADMIN,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION};
        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            requestPermissions(s,101);
        }
        BluetoothManager manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
        adapter = manager.getAdapter();

        //已經配對的藍牙的適配器
        mybondedadpater = new Mybondedadpater(this, list);
        alerady.setAdapter(mybondedadpater);

        //搜索的藍牙
        mysearchadpater = new Mybondedadpater(this,devices);
        nearblue.setAdapter(mysearchadpater);

        //註冊廣播
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        mybroad = new Mybroad();
        registerReceiver(mybroad,intentFilter);

        //打開藍牙
        open.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);
                startActivity(intent);
            }
        });
        //關閉藍牙
        close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                adapter.disable();
            }
        });

        //搜索藍牙
        search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                devices.clear();
                adapter.startDiscovery();
            }
        });

        //接收他人消息
        server.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);
                startActivity(intent);

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            BluetoothServerSocket serverSocket = adapter.listenUsingInsecureRfcommWithServiceRecord(adapter.getName(), uuid);
                            while (true){
                                BluetoothSocket socket = serverSocket.accept();
                                Message message = new Message();
                                message.what=101;
                                message.obj=socket.getRemoteDevice().getName();
                                handler.sendMessage(message);
                                new MyServerThread(socket,handler).start();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        });

        //已經配對的藍牙
        pair.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                list.clear();
                Set<BluetoothDevice> bondedDevices = adapter.getBondedDevices();
                list.addAll(bondedDevices);
                mybondedadpater.notifyDataSetChanged();
            }
        });

        //進行配對
        nearblue.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                devices.get(position).createBond();
            }
        });

        //已經配對的開啓線程發送數據
        alerady.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                BluetoothDevice device = list.get(position);
                try {
                    BluetoothSocket socket = device.createInsecureRfcommSocketToServiceRecord(uuid);
                    new MyClientThread(socket,"hello!").start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    class Mybroad extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)){
                if (device!=null){
                    devices.add(device);
                    mysearchadpater.notifyDataSetChanged();
                }
            }
        }
    }
    class MyClientThread extends Thread{
        private BluetoothSocket socket;
        private String message;

        public MyClientThread(BluetoothSocket socket, String message) {
            this.socket = socket;
            this.message = message;
        }

        @Override
        public void run() {
            super.run();
            try {
                socket.connect();
                if (socket.isConnected()){
                    socket.getOutputStream().write(message.getBytes());
                }else {
                    Log.i("xxx", "run: 連接失敗");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    class MyServerThread extends Thread{
        BluetoothSocket socket;
        Handler handler;

        public MyServerThread(BluetoothSocket socket, Handler handler) {
            this.socket = socket;
            this.handler = handler;
        }

        @Override
        public void run() {
            super.run();
            try {
                InputStream inputStream = socket.getInputStream();
                byte[] b = new byte[1024];
                int read = inputStream.read(b);
                String s = new String(b, 0, read);
                Message message = new Message();
                message.what=102;
                message.obj=s;
                handler.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章