2010-07-19 18 views
30

Salve, potrebbe sembrare una domanda stupida. Ma non sono riuscito a trovare alcuna risposta per questo, pubblicando qui.Come cercare periodicamente i dispositivi bluetooth su Android

Sto costruendo un'applicazione interna che scansiona continuamente i dongle bluetooth situati in luoghi diversi in un posto come un centro commerciale o una biblioteca.Come mi muovo nel centro commerciale con il telefono Android nella mia mano dovrei essere in grado di ottenere il dongle più vicino a cui posso collegarmi (Stupid Idea ma voglio fare qualcos'altro con questo). Per questo dovrei essere in grado di scansionare continuamente i dispositivi bluetooth.

Per favore qualcuno può dirmi come faccio a fare Android scansione dei dispositivi Bluetooth disponibili periodicamente.

+0

E 'un'idea impressionante e domanda fantastico, io sono Tu upvoting, Felice Coding :-) –

risposta

18

Immagino che fosse così semplice ma non mi ha colpito prima. Ecco la risposta,

private BluetoothAdapter mBtAdapter; 
mBtAdapter.startDiscovery(); 

private final BroadcastReceiver mReceiver = new BroadcastReceiver() 
{ 
     @Override 
     public void onReceive(Context context, Intent intent) 
     { 
      String action = intent.getAction(); 

      // When discovery finds a device 
      if (BluetoothDevice.ACTION_FOUND.equals(action)) 
      { 
      //do something 
      } 

      else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) 
      { 
       Log.v(TAG,"Entered the Finished "); 
       mBtAdapter.startDiscovery(); 
      } 

Così dovremmo ricomincia scoperta su ACTION_DISCOVERY_FINISHED che continuamente ricerca dei dispositivi ogni 12 secondi.

+1

Awesom risposta Caro, ma si don' t consumare troppo il prodotto? –

+0

Non funziona con me :-( –

+8

Assicurarsi di registrare il ricevitore 'IntentFilter intentFilter = new IntentFilter (BluetoothAdapter.ACTION_DISCOVERY_FINISHED); registerReceiver (myReceiver, intentFilter);' – Raytheon

2

Lo snippet di codice dovrebbe funzionare - Solo che sarà costoso in termini di assorbimento di corrente e sicuramente ucciderà il dispositivo/telefono in poche ore. StartDiscovery() esegue un processo in 2 passaggi, individuando il dispositivo richiedendolo e seguito da un rilevamento nome, ovvero cercapersone e connessione al dispositivo,

Sfortunatamente Android non fornisce alcuna API per controllare questo e fare solo richiesta Inoltre, esiste una funzione di inchiesta periodica definita e supportata dalla maggior parte dei chipset Bluetooth, Android al momento non ha alcuna API per fare inchieste periodiche che avrebbero potuto essere più ideali per il tuo caso d'uso.

9

ecco il codice per ottenere l'elenco di tutti gli dispositivi Bluetooth attivi [associato o non associato]

import java.util.Set; 

import android.app.Activity; 
import android.bluetooth.BluetoothAdapter; 
import android.bluetooth.BluetoothDevice; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.view.Window; 
import android.view.View.OnClickListener; 
import android.widget.AdapterView; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.ListView; 
import android.widget.TextView; 
import android.widget.AdapterView.OnItemClickListener; 

/** 
* This Activity appears as a dialog. It lists any paired devices and 
* devices detected in the area after discovery. When a device is chosen 
* by the user, the MAC address of the device is sent back to the parent 
* Activity in the result Intent. 
*/ 
public class DeviceListActivity extends Activity { 
    // Debugging 
    private static final String TAG = "DeviceListActivity"; 
    private static final boolean D = true; 

    // Return Intent extra 
    public static String EXTRA_DEVICE_ADDRESS = "device_address"; 

    // Member fields 
    private BluetoothAdapter mBtAdapter; 
    private ArrayAdapter<String> mPairedDevicesArrayAdapter; 
    private ArrayAdapter<String> mNewDevicesArrayAdapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // Setup the window 
     requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 
     setContentView(R.layout.activity_device_list); 


     // Initialize the button to perform device discovery 
     Button scanButton = (Button) findViewById(R.id.button_scan); 
     scanButton.setOnClickListener(new OnClickListener() { 
      public void onClick(View v) { 
       doDiscovery(); 
       v.setVisibility(View.GONE); 
      } 
     }); 

     // Initialize array adapters. One for already paired devices and 
     // one for newly discovered devices 
     mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); 
     mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); 

     // Find and set up the ListView for paired devices 
     ListView pairedListView = (ListView) findViewById(R.id.paired_devices); 
     pairedListView.setAdapter(mPairedDevicesArrayAdapter); 
     pairedListView.setOnItemClickListener(mDeviceClickListener); 

     // Find and set up the ListView for newly discovered devices 
     ListView newDevicesListView = (ListView) findViewById(R.id.new_devices); 
     newDevicesListView.setAdapter(mNewDevicesArrayAdapter); 
     newDevicesListView.setOnItemClickListener(mDeviceClickListener); 

     // Register for broadcasts when a device is discovered 
     IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 
     this.registerReceiver(mReceiver, filter); 

     // Register for broadcasts when discovery has finished 
     filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 
     this.registerReceiver(mReceiver, filter); 

     // Get the local Bluetooth adapter 
     mBtAdapter = BluetoothAdapter.getDefaultAdapter(); 

     // Get a set of currently paired devices 
     Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices(); 

     // If there are paired devices, add each one to the ArrayAdapter 
     if (pairedDevices.size() > 0) { 
      findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE); 
      for (BluetoothDevice device : pairedDevices) { 
       mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); 
      } 
     } else { 
      String noDevices = getResources().getText(R.string.none_paired).toString(); 
      mPairedDevicesArrayAdapter.add(noDevices); 
     } 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 

     // Make sure we're not doing discovery anymore 
     if (mBtAdapter != null) { 
      mBtAdapter.cancelDiscovery(); 
     } 
     // Unregister broadcast listeners 
     this.unregisterReceiver(mReceiver); 
    } 

    /** 
    * Start device discover with the BluetoothAdapter 
    */ 
    private void doDiscovery() { 
     if (D) Log.d(TAG, "doDiscovery()"); 

     // Indicate scanning in the title 
     setProgressBarIndeterminateVisibility(true); 
     setTitle(R.string.scanning); 

     // Turn on sub-title for new devices 
     findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE); 

     // If we're already discovering, stop it 
     if (mBtAdapter.isDiscovering()) { 
      mBtAdapter.cancelDiscovery(); 
     } 
     // Request discover from BluetoothAdapter 
     mBtAdapter.startDiscovery(); 
    } 

    // The on-click listener for all devices in the ListViews 
    private OnItemClickListener mDeviceClickListener = new OnItemClickListener() { 
     public void onItemClick(AdapterView<?> av, View v, int i, long l) { 
      // Cancel discovery because it's costly and we're about to connect 
      mBtAdapter.cancelDiscovery(); 

      // Get the device MAC address, which is the last 17 chars in the View 
      String info = ((TextView) v).getText().toString(); 
      String address = info.substring(info.length() - 17); 


     } 
    }; 

    // The BroadcastReceiver that listens for discovered devices and 
    // changes the title when discovery is finished 
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      String action = intent.getAction(); 

      // When discovery finds a device 
      if (BluetoothDevice.ACTION_FOUND.equals(action)) { 
       // Get the BluetoothDevice object from the Intent 
       BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
       // If it's already paired, skip it, because it's been listed already 
       if (device.getBondState() != BluetoothDevice.BOND_BONDED) { 
        mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); 
       } 
      // When discovery is finished, change the Activity title 
      } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { 
       setProgressBarIndeterminateVisibility(false); 
       setTitle(R.string.select_device); 
       if (mNewDevicesArrayAdapter.getCount() == 0) { 
        String noDevices = getResources().getText(R.string.none_found).toString(); 
        mNewDevicesArrayAdapter.add(noDevices); 
       } 
      } 
     } 
    }; 

} 

ho reso l'idea da API demo, spero che questo potrebbe essere utile per tutti gli sviluppatori .

5

Come indicato nello strumento documentation, l'individuazione dei dispositivi è un processo elevato che degraderà direttamente le prestazioni di qualsiasi legame che si ha con altri dispositivi.

Attenzione: Esecuzione di rilevamento dei dispositivi è una procedura pesante per l'adattatore Bluetooth e consumerà un sacco delle sue risorse. Dopo aver trovato un dispositivo per la connessione, verificare che si interrompa sempre il rilevamento con cancelDiscovery() prima di tentare una connessione. Inoltre, se si è già in possesso di una connessione con un dispositivo, quindi l'esecuzione della ricerca può ridurre in modo significativo la larghezza di banda disponibile per la connessione , quindi non eseguire il rilevamento durante la connessione.

Con questo in mente (la gestione degli errori omesso):

private final BroadcastReceiver deviceBroadcastReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      String action = intent.getAction(); 

      if (BluetoothDevice.ACTION_FOUND.equals(action)) { 
       deviceFound = true; 

       adapter.cancelDiscovery(); 

       //process new device. 

       deviceFound = false; 

       adapter.startDiscovery(); 
      } 
} 

private final BroadcastReceiver adapterBroadcastReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      String action = intent.getAction(); 

      if (BluetoothAdaptor.ACTION_DISCOVERY_FINISHED.equals(action)) { 
       if (deviceFound == false) { 
         adapter.startDiscovery(); 
       } 
      } 
} 
Problemi correlati