2014-04-16 96 views

回答

20

這個例子是基於你發佈的開發者網站,對我很好。這是代碼:

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; 
} 

}

爲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> 

上掃描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> 

菜單佈局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> 

琴絃佈局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> 

而且清單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> 

我想這就是全部。如果我錯過了任何事情,現在就讓我修復它。希望能幫助到你!!

(藍牙LE相當Android中還吸!d ...的需求和更新快)

UPDATE:

此處下載BLE掃描和連接的一個完整的例子: https://dl.dropboxusercontent.com/u/18548987/DeviceScanActivity.rar

+1

感謝您的寶貴時間。我會檢查並讓你知道很快:) – info

+0

嗨,我得到了崩潰錯誤 D/AbsListView(17995):unregisterIRListener()被調用。而在三星Galaxy S4運行。 Plz幫助 – info

+1

我真的不知道那是什麼錯誤。無論如何,下載並嘗試完整的項目,這也將允許您連接到設備,並看到他們的服務特點:https://www.dropbox.com/s/66y8j9auptllbhf/DeviceScanActivity.rar – margabro

4

這是一個相當古老的問題,但對於未來的讀者,我只是想提出檢查一下由Bluetooth SIG提供的官方源代碼:

Application Accelerator

有小,易於理解和記錄應用程序對於大多數移動平臺(Android,iOS設備的Windows Phone和更多)+一些材料/教程。如果你想開始玩BLE,這是我認爲最好的起點。

一切都是免費的,但你需要在網站上註冊。據我記得,每年可能會有1-3封電子郵件,所有這些都與用於藍牙開發的新工具相關。

Darek

+1

有一個支持Android 6.0的新版本:https://www.bluetooth.com/develop-with-bluetooth/developer-resources-tools/app-acc-2 –

+0

謝謝,在多個不工作的BLE掃描儀示例中,這一個(來自Evin1_的最後一個鏈接)工作正常。 – Ujeenator

相關問題