1. 程式人生 > >安卓藍芽Bluetooth基本操作- (獲取附近裝置-1)

安卓藍芽Bluetooth基本操作- (獲取附近裝置-1)

1、效果圖

這裡寫圖片描述

2、AndroidManifest.xml新增如下程式碼

    //所有手機需要的許可權,藍芽功能才能正常使用
    <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" />

3、MainActivity主要類

public class MainActivity extends AppCompatActivity {

    private final static int SEARCH_CODE = 0x123;
    private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    private
static final String TAG = "MainActivity"; private List<BluetoothDevice> mBlueList = new ArrayList<>(); private ListView lisetView; private TextView textView1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lisetView = (ListView) findViewById(R.id.list_view); textView1 = (TextView) findViewById(R.id.textView1); Log.e(TAG, "onCreate: GPS是否可用:"
+ isGpsEnable(this)); init(); } //gps是否可用(有些裝置可能需要定位) public static final boolean isGpsEnable(final Context context) { LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (gps || network) { return true; } return false; } /** * 判斷藍芽是否開啟 */ private void init() { // 判斷手機是否支援藍芽 if (mBluetoothAdapter == null) { Toast.makeText(this, "裝置不支援藍芽", Toast.LENGTH_SHORT).show(); finish(); } // 判斷是否開啟藍芽 if (!mBluetoothAdapter.isEnabled()) { //彈出對話方塊提示使用者是後開啟 Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent,SEARCH_CODE); } else { // 不做提示,強行開啟 mBluetoothAdapter.enable(); } startDiscovery(); Log.e(TAG, "startDiscovery: 開啟藍芽"); } /** * 註冊非同步搜尋藍芽裝置的廣播 */ private void startDiscovery() { // 找到裝置的廣播 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); // 註冊廣播 registerReceiver(receiver, filter); // 搜尋完成的廣播 IntentFilter filter1 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); // 註冊廣播 registerReceiver(receiver, filter1); Log.e(TAG, "startDiscovery: 註冊廣播"); startScanBluth(); } /** * 廣播接收器 */ private final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // 收到的廣播型別 String action = intent.getAction(); // 發現裝置的廣播 if (BluetoothDevice.ACTION_FOUND.equals(action)) { // 從intent中獲取裝置 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // 沒否配對 if (device.getBondState() != BluetoothDevice.BOND_BONDED) { if (!mBlueList.contains(device)) { mBlueList.add(device); } textView1.setText("附近裝置:" + mBlueList.size() + "個\u3000\u3000本機藍芽地址:" + getBluetoothAddress()); MyAdapter adapter = new MyAdapter(MainActivity.this, mBlueList); lisetView.setAdapter(adapter); Log.e(TAG, "onReceive: " + mBlueList.size()); Log.e(TAG, "onReceive: " + (device.getName() + ":" + device.getAddress() + " :" + "m" + "\n")); } // 搜尋完成 } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { // 關閉進度條 progressDialog.dismiss(); Log.e(TAG, "onReceive: 搜尋完成"); } } }; private ProgressDialog progressDialog; /** * 搜尋藍芽的方法 */ private void startScanBluth() { // 判斷是否在搜尋,如果在搜尋,就取消搜尋 if (mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); } // 開始搜尋 mBluetoothAdapter.startDiscovery(); if (progressDialog == null) { progressDialog = new ProgressDialog(this); } progressDialog.setMessage("正在搜尋,請稍後!"); progressDialog.show(); } @Override protected void onDestroy() { super.onDestroy(); if (receiver != null) { //取消註冊,防止記憶體洩露(onDestroy被回撥代不代表Activity被回收?:具體回收看系統,由GC回收,同時廣播會註冊到系統 //管理的ams中,即使activity被回收,reciver也不會被回收,所以一定要取消註冊), unregisterReceiver(receiver); } } /** * 獲取本機藍芽地址 */ private String getBluetoothAddress() { try { BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); Field field = bluetoothAdapter.getClass().getDeclaredField("mService"); // 引數值為true,禁用訪問控制檢查 field.setAccessible(true); Object bluetoothManagerService = field.get(bluetoothAdapter); if (bluetoothManagerService == null) { return null; } Method method = bluetoothManagerService.getClass().getMethod("getAddress"); Object address = method.invoke(bluetoothManagerService); if (address != null && address instanceof String) { return (String) address; } else { return null; } //拋一個總異常省的一堆程式碼... } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode==SEARCH_CODE){ startDiscovery(); } Log.e(TAG, "onActivityResult: "+requestCode ); Log.e(TAG, "onActivityResult: "+resultCode ); Log.e(TAG, "onActivityResult: "+requestCode ); } }

注意:看有些文章開了定時器一直刷,不建議這樣做,只需啟動一次會搜尋附近的(測試的時候大概10秒載入完)如果沒搜尋到可以在右上角加個重新整理按鈕在呼叫對應方法即可,在搜尋的同時有新裝置開啟藍芽也是能掃描到的

3、activity_main 佈局

<?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"
    android:orientation="vertical">

    <TextView
        android:layout_margin="10dp"
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="" />

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@color/colorAccent"
        android:dividerHeight="1dp" />
</LinearLayout>

4、MyAdapter 介面卡

public class MyAdapter extends BaseAdapter {

    private List<BluetoothDevice> mBluelist;
    private LayoutInflater layoutInflater;

    public MyAdapter(Context context, List<BluetoothDevice> list) {
        this.mBluelist = list;
        this.layoutInflater = LayoutInflater.from(context);
    }

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

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

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

    @Override
    public View getView(int position, View view, ViewGroup viewGroup) {

        ViewHolder viewHolder;
        if (view == null) {
            viewHolder = new ViewHolder();
            view = layoutInflater.inflate(R.layout.list_device_item, null);
            viewHolder.deviceName = view.findViewById(R.id.device_name);
            viewHolder.deviceAddress = view.findViewById(R.id.device_address);
            viewHolder.deviceType = view.findViewById(R.id.device_type);
            viewHolder.deviceState = view.findViewById(R.id.device_state);
            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }
        //詳細參考:http://blog.csdn.net/mirkowu/article/details/53862842
        BluetoothDevice blueDevice = mBluelist.get(position);
        //裝置名稱
        String deviceName = blueDevice.getName();
        viewHolder.deviceName.setText(TextUtils.isEmpty(deviceName) ? "未知裝置" : deviceName);
        //裝置的藍芽地(地址為17位,都為大寫字母-該項貌似不可能為空)
        String deviceAddress = blueDevice.getAddress();
        viewHolder.deviceAddress.setText(deviceAddress);
        //裝置的藍芽裝置型別(DEVICE_TYPE_CLASSIC 傳統藍芽 常量值:1, DEVICE_TYPE_LE  低功耗藍芽 常量值:2
        //DEVICE_TYPE_DUAL 雙模藍芽 常量值:3. DEVICE_TYPE_UNKNOWN:未知 常量值:0)
        int deviceType = blueDevice.getType();
        if (deviceType == 0) {
            viewHolder.deviceType.setText("未知型別");
        } else if (deviceType == 1) {
            viewHolder.deviceType.setText("傳統藍芽");
        } else if (deviceType == 2) {
            viewHolder.deviceType.setText("低功耗藍芽");
        } else if (deviceType == 3) {
            viewHolder.deviceType.setText("雙模藍芽");
        }
        //裝置的狀態(BOND_BONDED:已繫結 常量值:12, BOND_BONDING:繫結中 常量值:11, BOND_NONE:未匹配 常量值:10)
        int deviceState = blueDevice.getBondState();
        if (deviceState == 10) {
            viewHolder.deviceState.setText("未匹配");
        } else if (deviceState == 11) {
            viewHolder.deviceState.setText("繫結中");
        } else if (deviceState == 12) {
            viewHolder.deviceState.setText("已繫結");
        }
        //返回遠端裝置支援的UUID。此方法從遠端裝置檢索UUID不啟動服務。 而是返回服務UUID的本地快取。
        //如果需要重新整理UUID,使用fetchUuidsWithSdp()方法
        //ParcelUuid[] deviceUuid = blueDevice.getUuids();
        //blueDevice.fetchUuidsWithSdp(); boolean型別
        return view;
    }

    private class ViewHolder {
        TextView deviceName;
        TextView deviceAddress;
        TextView deviceType;
        TextView deviceState;
    }
}

5、list_device_item 介面卡佈局

<?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"
    android:paddingLeft="10dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/device_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/device_address"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/device_type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/device_state"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

相關推薦

Bluetooth基本操作- 獲取附近裝置-1

1、效果圖 2、AndroidManifest.xml新增如下程式碼 //所有手機需要的許可權,藍芽功能才能正常使用 <uses-permission android:name="android.permission.BLUET

4.0以上連線多臺裝置並接收裝置資料

前沿: 在我之前寫的程式碼中都沒有實現藍芽連線多個裝置,由於時間的原因沒有進行更改。 iOS端實現 藍芽多個連線確實比安卓的方便,本身利用官方的Demo就可以實現多臺連線,只不過自己利用view加以區分就可以。 到此藍芽4.0之前是通過scoket連線多臺

連線操作步驟。。。慢慢來不急

使用藍芽API,Android應用程式可以執行以下操作: 掃描其他藍芽裝置查詢配對藍芽裝置的本地藍芽介面卡建立RFCOMM通道通過服務發現連線到其他裝置向其他裝置傳輸資料管理多個連線---------------------------------------------

unity 2017.3 訂閱及資料解析

接上篇,我們寫到了連線藍芽,之後我們就需要訂閱藍芽的資訊了。訂閱藍芽訊息最後一個引數是一個回撥,它會傳回三個資訊分別是地址、UUID和資料,這個資料是串列埠通訊中常用的byte[],出於專案需要,我要進行一次資料轉換。    /// <summary> /

通訊之聊天小程式

安卓 藍芽聊天小程式 一、簡述   記--簡單的藍芽聊天小程式。使用的是傳統藍芽開發。(某些手機由於Android版本原因需要新增新的許可權)        兩臺裝置開啟藍芽,一臺裝置設定藍芽可見性,另一臺裝置進行連線,然後互相收發資訊。

個人進階之路——模組

今天學習一下專案中的藍芽的基礎知識 Android系統包含了對藍芽網路協議棧的支援,使得安卓裝置能無線連線其他藍芽裝置交換資料。 應用程式框架提供訪問藍芽功能的APIs,使得應用程式能夠通過無線連線其他藍芽裝置,實現點對點,或者點對多點的無線互動 通過使用

——listView搜尋以及點選事件

一;點選事件。 1;開啟關閉藍芽; 2;掃描附近藍芽的點選事件。 二;關於藍芽裝置listView展示 1;listView介面卡 2;通過layout找到例項化ListView物件 3;ListView物件載入介面卡 4;即可進行點選事件

的屬性動畫基本用法

    休假歸來,十幾天的婚假過得真快,時間不管對誰都是不夠用的,我們能做的只能是珍惜時間。     上篇文章講解了補間動畫,這次我們來看看屬性動畫,先給大家看看兩張效果圖,大家看看其中的不同:     第一張(補間動畫):        第二張(屬性動畫):     

BLE裝置開發

 前段時間做了一個有關於安卓藍芽BLE裝置的開發專案,主要的功能包括了搜尋藍芽ble裝置和ble裝置的資料讀寫等等,本篇部落格用於記錄安卓藍芽ble裝置的通訊的細節。  其實關於BLE裝置的通訊在API中已經講地比較清楚了,這裡只是做一個總結,如果要進行BLE

框架彙總

1.  從藍芽資料和控制信令流程層次圖看藍芽底層協議棧 2. Android Version1 藍芽框架 3.  從庫的角度看安卓藍芽架構 4.   Android N  藍芽框架 5. +---------------------------------

串列埠例子修改

BluetoothChatService.java的第49行             private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");  

技術之中央BluetoothGatt和周邊BluetoothGattServer的實現

BluetoothAdapter.LeScanCallback  Class Overview:回撥介面被用於傳輸LE掃描後的結果; 詳情請查看: onLescan(BluetoothDevice , int , byte[]) 是通過startLeScan(Blu

rabbitmq安裝及基本操作含集群配置

home 操作 14. 關系 裝包 del protocol otp examples 一、rabbitmq的安裝 因為rabbitmq是基於 erlang語言開發,所有要先安裝erlang 1、安裝erlang 這裏我下載的是19.2的版本,地址為https://w

使用 sql 語句完成資料庫和表的建立等基本操作基於 sql server 2014

寫在前面 程式碼中使用的資料庫名字 review 和 review_2,表名是 first 和 second 資料庫的建立 資料庫建立常用的幾個引數設定 name:邏輯檔名稱 filename:物理檔名稱(存放在磁碟的哪個地方) size:初始化的大

python對字典的基本操作遍歷、排序總結

Python字典容器 python中的字典同其他語言中的字典作用一樣,都是用來儲存資料的容器。只不過不同於其他序列型資料用下標來訪問其中的物件,而是以關鍵字key來訪問其中的物件value。另外,字典也被稱為關聯陣列或者雜湊表。 字典的應用場景有很多,下面通過一個投票的例

系統自帶提示框 帶取消 確定按鈕

private void showCoverDialog(){ AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("提示"); builder.setMess

Django 學習筆記資料庫基本操作增查改刪

1.建立一個專案 2.建立一個應用 3.更改settings.py 4.更改models.py 5.同步資料 二、安裝IPython方便debug sudo apt-get install ipython3 安裝成功後用python manage.py shell 會自動進入Ipython互動直譯器中,沒

socket通訊連線建立演示socket通訊第一彈

歡迎轉載,請註明轉載自微信訂閱號(安卓程式設計入門進階)。 百度雲原清晰度地址:http://pan.baidu.com/s/1mhS0H8O 安卓的網路連線方式有socket和http兩類連線,本節課程介紹socket連線的網路建立過程。課程例項將編寫客戶端和伺服器兩個安

效能優化之懶載入View的懶載入

1、背景:為什麼需要View的懶載入。           我們在做安卓專案的時候,經常會有一個使用場景:需要在執行時根據資料動態決定顯示或隱藏某個View和佈局。       上述場景,我們通常的解決方案就是:就是把可能用到的View先寫在佈局裡,再初始化其可見性都設為

第4章第1節練習題2 二叉樹的基本操作非遞迴實現

二叉樹的非遞迴遍歷 上一節二叉樹的遞迴遍歷中簡單介紹了二叉樹的遞迴遍歷的實現方式,本節主要介紹二叉樹的非遞迴遍歷實現,繼續引用上節的例子來說明下。 一.先序遍歷 二叉樹先序遍歷的訪問順序為:根結點->左孩子->右孩子。簡單的說,對於任意