Friday, May 27, 2011

Scan Bluetooth Devices

To start scan bluetooth device, simple call bluetoothAdapter.startDiscovery().

In order to receive the list of found bluetooth devices, we have to implement a BroadcastReceiver for BluetoothDevice.ACTION_FOUND.

Scan Bluetooth Devices

AndroidBluetooth.java
package com.exercise.AndroidBluetooth;

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.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

public class AndroidBluetooth extends Activity {
 
 private static final int REQUEST_ENABLE_BT = 1;
 
    ListView listDevicesFound;
 Button btnScanDevice;
 TextView stateBluetooth;
 BluetoothAdapter bluetoothAdapter;
 
 ArrayAdapter<String> btArrayAdapter;
 
 /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        btnScanDevice = (Button)findViewById(R.id.scandevice);
        
        stateBluetooth = (TextView)findViewById(R.id.bluetoothstate);
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        
        listDevicesFound = (ListView)findViewById(R.id.devicesfound);
        btArrayAdapter = new ArrayAdapter<String>(AndroidBluetooth.this, android.R.layout.simple_list_item_1);
        listDevicesFound.setAdapter(btArrayAdapter);
        
        CheckBlueToothState();
        
        btnScanDevice.setOnClickListener(btnScanDeviceOnClickListener);

        registerReceiver(ActionFoundReceiver, 
          new IntentFilter(BluetoothDevice.ACTION_FOUND));
    }
    
    @Override
 protected void onDestroy() {
  // TODO Auto-generated method stub
  super.onDestroy();
  unregisterReceiver(ActionFoundReceiver);
 }

 private void CheckBlueToothState(){
     if (bluetoothAdapter == null){
         stateBluetooth.setText("Bluetooth NOT support");
        }else{
         if (bluetoothAdapter.isEnabled()){
          if(bluetoothAdapter.isDiscovering()){
           stateBluetooth.setText("Bluetooth is currently in device discovery process.");
          }else{
           stateBluetooth.setText("Bluetooth is Enabled.");
           btnScanDevice.setEnabled(true);
          }
         }else{
          stateBluetooth.setText("Bluetooth is NOT Enabled!");
          Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
             startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
         }
        }
    }
    
    private Button.OnClickListener btnScanDeviceOnClickListener
    = new Button.OnClickListener(){

  @Override
  public void onClick(View arg0) {
   // TODO Auto-generated method stub
   btArrayAdapter.clear();
   bluetoothAdapter.startDiscovery();
  }};

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  // TODO Auto-generated method stub
  if(requestCode == REQUEST_ENABLE_BT){
   CheckBlueToothState();
  }
 }
    
 private final BroadcastReceiver ActionFoundReceiver = new BroadcastReceiver(){

  @Override
  public void onReceive(Context context, Intent intent) {
   // TODO Auto-generated method stub
   String action = intent.getAction();
   if(BluetoothDevice.ACTION_FOUND.equals(action)) {
             BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
             btArrayAdapter.add(device.getName() + "\n" + device.getAddress());
             btArrayAdapter.notifyDataSetChanged();
         }
  }};
    
}


main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
<TextView 
    android:id="@+id/bluetoothstate" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />
<TextView
    android:id="@+id/bluetoothstate" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />
<TextView
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Set Discoverable Duration" 
    />
<Button
    android:id="@+id/scandevice" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:text="Scan Bluetooth Devices" 
    android:enabled="false"
    /> 
<ListView
    android:id="@+id/devicesfound" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    /> 
</LinearLayout>


Modify AndroidManifest.xml to grant permission of "android.permission.BLUETOOTH", and "android.permission.BLUETOOTH_ADMIN".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.exercise.AndroidBluetooth"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />
    <uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".AndroidBluetooth"
                  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>


Download the files.


Related:
- Start Bluetooth Discoverable and register BroadcastReceiver for ACTION_SCAN_MODE_CHANGED


Updated@2016-03-07: 
Android 6.0 Changes - Access to Hardware Identifier

To provide users with greater data protection, starting in this release, Android removes programmatic access to the device’s local hardware identifier for apps using the Wi-Fi and Bluetooth APIs. The WifiInfo.getMacAddress() and the BluetoothAdapter.getAddress() methods now return a constant value of 02:00:00:00:00:00.

To access the hardware identifiers of nearby external devices via Bluetooth and Wi-Fi scans, your app must now have the ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permissions:

WifiManager.getScanResults()
BluetoothDevice.ACTION_FOUND
BluetoothLeScanner.startScan()

Note: When a device running Android 6.0 (API level 23) initiates a background Wi-Fi or Bluetooth scan, the operation is visible to external devices as originating from a randomized MAC address.

link: http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id

I have no Android 6.0 devices, So I can't figure it out if it is related!



21 comments:

Güliz Seray Tuncay said...

Do you have any code to pair two bluetooth devices?

Anbu said...

Hi,

i am anbu., when i run this code my android emulator showing that"Unfortunately bluetooth has stopped "

please help me to find the problem..

i aM a tEKy said...
This comment has been removed by the author.
Unknown said...

Anbu,
The emulator cannot initiate a bluetooth apps. Instead, u need to have real physical mobile device to run on it.

Deepak Sharma said...

Hi Anbu..
Actually the emulator doesnt support the bluetooth..so you have to run the same code on the device..It will surely work.

Unknown said...

Its nice Snap.. It works for me to find bluetooth devices.. Thanks a lot..

Anonymous said...

thank a lot :) actually now the app fetches only the device name & mac id... can u post code for fetching the time when the device came into our bluetooth range & when it goes out of over range .... thanx :)

Anonymous said...

hi..when i run my code on mobile its giving me an error of blutoothapp has stopped..its not running..

Shanmugasundharam Selvadurai said...

hi Güliz Seray Tuncay i`m doing the project using multiparing the bluetooth connection..... first of all i`m the beginer of android programmer... do you have any idea about paring 2 or more bluetooth connection ...thank you..

Shanmugasundharam Selvadurai said...

even i tried my phone its not working...

Anonymous said...

when I click on the scan button , nothing happens, and no list of connected devices plz any help

Anonymous said...

How to run this as a service? I mean running it into background and not showing anything on UI

patelsandip2601 said...

If by chance my android phone OS bluetooth software not found than how can i install buletooth ?????

Shanmugasundharam Selvadurai said...

restore your phone and than it will Work.

Unknown said...

How can i get date and time for the device which is connected. can you please provide a code.

aniruddhark said...

Hi
Can anybody plz guide me for How I can get this app into the cellphone ? I might be skipping a step. Please help.
thanks,

Anonymous said...

Version 6 needs one extra line in Manifestoo



Unknown said...

hi... this code is not responding for android marshmallow, it is responding only for lower versions...... why....

Erik said...


Hello Reddi prasad chinnabala,
Please check Updated@2016-03-07 of Android 6.0 Changes - Access to Hardware Identifier.

Hossein O+G said...

Hello Andr.oid Eric,
Thank you for your helpful Blog,

for android 6 (Marshmallow) and 6+ you should add these two lines above "bluetoothAdapter.startDiscovery()" line:

int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1;
ActivityCompat.requestPermissions(MainActivity.this,
new String[]Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);

and also add the following permission to Android Manifest:


and it should work, like it does for me!
Have Fun, and Thank You Again

NatnaelET said...

@Hossein, you last comment to add permission statements above startdiscovery() worked for me.