2014-04-16 23 views
5

Bạn có thể cung cấp cho tôi mã đơn giản để quét các thiết bị BLE gần đó và liệt kê nó theo tên thiết bị và ID MAC. Tôi đã thử điều này bằng cách sử dụng mã mẫu được cung cấp trong http://developer.android.com/guide/topics/connectivity/bluetooth-le.html. Nhưng đã không làm việc, bất kỳ liên kết tham khảo hoặc ý tưởng kể từ khi tôi mới đến ứng dụng BLE.Android liệt kê các thiết bị BLE sau khi quét thiết bị

Trả lời

20

Ví dụ này dựa trên web của nhà phát triển bạn đã đăng và hoạt động tốt cho tôi. Đây là mã:

DeviceScanActivity.class

package com.example.android.bluetoothlegatt; 

import android.app.Activity; 
import android.app.ListActivity; 
import android.bluetooth.BluetoothAdapter; 
import android.bluetooth.BluetoothDevice; 
import android.bluetooth.BluetoothManager; 
import android.content.Context; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.os.Bundle; 
import android.os.Handler; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.ListView; 
import android.widget.TextView; 
import android.widget.Toast; 
import java.util.ArrayList; 

public class DeviceScanActivity extends ListActivity { 
private LeDeviceListAdapter mLeDeviceListAdapter; 
private BluetoothAdapter mBluetoothAdapter; 
private boolean mScanning; 
private Handler mHandler; 

private static final int REQUEST_ENABLE_BT = 1; 
// Stops scanning after 10 seconds. 
private static final long SCAN_PERIOD = 10000; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    getActionBar().setTitle(R.string.title_devices); 
    mHandler = new Handler(); 

    // Use this check to determine whether BLE is supported on the device. Then you can 
    // selectively disable BLE-related features. 
    if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { 
     Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); 
     finish(); 
    } 
    // Initializes a Bluetooth adapter. For API level 18 and above, get a reference to 
    // BluetoothAdapter through BluetoothManager. 
    final BluetoothManager bluetoothManager = 
      (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 
    mBluetoothAdapter = bluetoothManager.getAdapter(); 
    // Checks if Bluetooth is supported on the device. 
    if (mBluetoothAdapter == null) { 
     Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show(); 
     finish(); 
     return; 
    } 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.main, menu); 
    if (!mScanning) { 
     menu.findItem(R.id.menu_stop).setVisible(false); 
     menu.findItem(R.id.menu_scan).setVisible(true); 
     menu.findItem(R.id.menu_refresh).setActionView(null); 
    } else { 
     menu.findItem(R.id.menu_stop).setVisible(true); 
     menu.findItem(R.id.menu_scan).setVisible(false); 
     menu.findItem(R.id.menu_refresh).setActionView(
       R.layout.actionbar_indeterminate_progress); 
    } 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case R.id.menu_scan: 
      mLeDeviceListAdapter.clear(); 
      scanLeDevice(true); 
      break; 
     case R.id.menu_stop: 
      scanLeDevice(false); 
      break; 
    } 
    return true; 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    // Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled, 
    // fire an intent to display a dialog asking the user to grant permission to enable it. 
    if (!mBluetoothAdapter.isEnabled()) { 
     if (!mBluetoothAdapter.isEnabled()) { 
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
      startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 
     } 
    } 
    // Initializes list view adapter. 
    mLeDeviceListAdapter = new LeDeviceListAdapter(); 
    setListAdapter(mLeDeviceListAdapter); 
    scanLeDevice(true); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    // User chose not to enable Bluetooth. 
    if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) { 
     finish(); 
     return; 
    } 
    super.onActivityResult(requestCode, resultCode, data); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    scanLeDevice(false); 
    mLeDeviceListAdapter.clear(); 
} 

private void scanLeDevice(final boolean enable) { 
    if (enable) { 
     // Stops scanning after a pre-defined scan period. 
     mHandler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       mScanning = false; 
       mBluetoothAdapter.stopLeScan(mLeScanCallback); 
       invalidateOptionsMenu(); 
      } 
     }, SCAN_PERIOD); 
     mScanning = true; 
     mBluetoothAdapter.startLeScan(mLeScanCallback); 
    } else { 
     mScanning = false; 
     mBluetoothAdapter.stopLeScan(mLeScanCallback); 
    } 
    invalidateOptionsMenu(); 
} 

// Adapter for holding devices found through scanning. 
private class LeDeviceListAdapter extends BaseAdapter { 
    private ArrayList<BluetoothDevice> mLeDevices; 
    private LayoutInflater mInflator; 

    public LeDeviceListAdapter() { 
     super(); 
     mLeDevices = new ArrayList<BluetoothDevice>(); 
     mInflator = DeviceScanActivity.this.getLayoutInflater(); 
    } 

    public void addDevice(BluetoothDevice device) { 
     if(!mLeDevices.contains(device)) { 
      mLeDevices.add(device); 
     } 
    } 

    public BluetoothDevice getDevice(int position) { 
     return mLeDevices.get(position); 
    } 

    public void clear() { 
     mLeDevices.clear(); 
    } 

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

    @Override 
    public Object getItem(int i) { 
     return mLeDevices.get(i); 
    } 

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

    @Override 
    public View getView(int i, View view, ViewGroup viewGroup) { 
     ViewHolder viewHolder; 
     // General ListView optimization code. 
     if (view == null) { 
      view = mInflator.inflate(R.layout.listitem_device, null); 
      viewHolder = new ViewHolder(); 
      viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address); 
      viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name); 
      view.setTag(viewHolder); 
     } else { 
      viewHolder = (ViewHolder) view.getTag(); 
     } 

     BluetoothDevice device = mLeDevices.get(i); 
     final String deviceName = device.getName(); 
     if (deviceName != null && deviceName.length() > 0) 
      viewHolder.deviceName.setText(deviceName); 
     else 
      viewHolder.deviceName.setText(R.string.unknown_device); 
     viewHolder.deviceAddress.setText(device.getAddress()); 

     return view; 
    } 
} 

// Device scan callback. 
private BluetoothAdapter.LeScanCallback mLeScanCallback = 
     new BluetoothAdapter.LeScanCallback() { 

    @Override 
    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       mLeDeviceListAdapter.addDevice(device); 
       mLeDeviceListAdapter.notifyDataSetChanged(); 
      } 
     }); 
    } 
}; 

static class ViewHolder { 
    TextView deviceName; 
    TextView deviceAddress; 
} 

}

Cách bố trí tùy chỉnh cho listview listitem_device.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:orientation="vertical" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content"> 
    <TextView android:id="@+id/device_name" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:textSize="24dp"/> 
    <TextView android:id="@+id/device_address" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:textSize="12dp"/> 
</LinearLayout> 

Thanh tiến trình trên quét actionbar_indeterminate_progress.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_height="wrap_content" 
     android:layout_width="56dp" 
     android:minWidth="56dp"> 
<ProgressBar android:layout_width="32dp" 
      android:layout_height="32dp" 
      android:layout_gravity="center"/> 
</FrameLayout> 

Việc bố trí trình đơn main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android"> 
<item android:id="@+id/menu_refresh" 
     android:checkable="false" 
     android:orderInCategory="1" 
     android:showAsAction="ifRoom"/> 
<item android:id="@+id/menu_scan" 
     android:title="@string/menu_scan" 
     android:orderInCategory="100" 
     android:showAsAction="ifRoom|withText"/> 
<item android:id="@+id/menu_stop" 
     android:title="@string/menu_stop" 
     android:orderInCategory="101" 
     android:showAsAction="ifRoom|withText"/> 
</menu> 

Các chuỗi bố trí strings.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string name="ble_not_supported">BLE is not supported</string> 
    <string name="error_bluetooth_not_supported">Bluetooth not supported.</string> 
    <string name="unknown_device">Unknown device</string> 

    <!-- Menu items --> 
    <string name="menu_connect">Connect</string> 
    <string name="menu_disconnect">Disconnect</string> 
    <string name="menu_scan">Scan</string> 
    <string name="menu_stop">Stop</string> 
</resources> 

Và manifest AndroidManifest.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.example.android.bluetoothlegatt" 
android:versionCode="1" 
android:versionName="1.0"> 

<uses-sdk android:minSdkVersion="18" 
    android:targetSdkVersion="19"/> 
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/> 

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

<application android:label="@string/app_name" 
    android:icon="@drawable/ic_launcher" 
    android:theme="@android:style/Theme.Holo.Light"> 
    <activity android:name=".DeviceScanActivity" 
     android:label="@string/app_name"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN"/> 
      <category android:name="android.intent.category.LAUNCHER"/> 
     </intent-filter> 
    </activity> 
</application> 

</manifest> 

Tôi nghĩ đây là tất cả. Nếu tôi bỏ lỡ bất cứ điều gì cho tôi bây giờ và tôi sửa chữa nó. Hy vọng nó giúp!!

(Bluetooth LE khá sucks trong Android chưa: D ... nhu cầu và cập nhật nhanh)

UPDATE:

Tải ở đây một ví dụ đầy đủ quét BLE và kết nối: https://dl.dropboxusercontent.com/u/18548987/DeviceScanActivity.rar

+1

Cảm ơn thời gian quý báu của bạn.Tôi sẽ kiểm tra và cho bạn biết sớm :) – info

+0

Xin chào, tôi nhận được lỗi sự cố D/AbsListView (17995): unregisterIRListener() được gọi. trong khi chạy trong samsung galaxy s4. Xin giúp đỡ – info

+1

Tôi thực sự không biết lỗi đó là gì. Dù sao, tải xuống và thử toàn bộ dự án cũng sẽ cho phép bạn kết nối với các thiết bị ble và xem các đặc điểm dịch vụ của chúng: https://www.dropbox.com/s/66y8j9auptllbhf/DeviceScanActivity.rar – margabro

4

đây là câu hỏi khá cũ, nhưng đối với người đọc trong tương lai, tôi chỉ muốn đề xuất xem mã nguồn chính thức do Bluetooth SIG cung cấp:

Application Accelerator

Có các ứng dụng nhỏ, dễ hiểu và được ghi lại cho hầu hết các nền tảng di động (Android, iOS, Windows Phone và hơn thế nữa) + một số tài liệu/hướng dẫn. Nếu bạn muốn bắt đầu chơi với BLE thì đây là điểm khởi đầu tốt nhất theo ý kiến ​​của tôi.

Mọi thứ đều miễn phí nhưng bạn cần phải đăng ký trên trang web. Theo tôi nhớ có thể 1-3 email theo năm, tất cả kết nối với các công cụ mới để phát triển Bluetooth.

Darek

+1

Có một phiên bản mới của nó với hỗ trợ Android 6.0: https://www.bluetooth.com/develop-with-bluetooth/developer-resources-tools/app-acc-2 –

+0

Cảm ơn bạn, trong số nhiều ví dụ về máy quét BLE không hoạt động, cái này (liên kết cuối cùng từ Evin1_) hoạt động tốt. – Ujeenator

Các vấn đề liên quan