the below is my full code, when i switch to this activity, it crashed.
I have tried many solutions, yet it didn't work. Thanks!!
there is some mistake (deprecated) on
line 41 : requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
line 118 : setProgressBarIndeterminateVisibility(true);
line 175 : setProgressBarIndeterminateVisibility(false);
public class DeviceList extends Activity {
private static final String TAG = DeviceList.class.getSimpleName();
public static String EXTRA_DEVICE_ADDRESS = "device_address";
private BluetoothAdapter mBtAdapter;
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);
// Set result CANCELED in case the user backs out
setResult(Activity.RESULT_CANCELED);
// Initialize the button to perform device discovery
Button scanButton = (Button) findViewById(R.id.button_scan);
scanButton.setOnClickListener(new View.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
ArrayAdapter<String> pairedDevicesArrayAdapter =
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(pairedDevicesArrayAdapter);
pairedListView.setOnItemClickListener(mDeviceClickListener);
// Find and set up the ListView for newly discovered devices
ListView newDevicesListView = (ListView) findViewById(R.id.new_device);
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) {
pairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
} else {
String noDevices = "none paired";
pairedDevicesArrayAdapter.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() {
Log.d(TAG, "doDiscovery()");
// Indicate scanning in the title
setProgressBarIndeterminateVisibility(true);
setTitle("Scanning");
// Turn on sub-title for new devices
findViewById(R.id.new_device_title).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 AdapterView.OnItemClickListener mDeviceClickListener
= new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
// 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);
// Create the result Intent and include the MAC address
Intent intent = new Intent();
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
// Set result and finish this Activity
setResult(Activity.RESULT_OK, intent);
finish();
}
};
/**
* 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("Select Device");
if (mNewDevicesArrayAdapter.getCount() == 0) {
String noDevices = "Not Found";
mNewDevicesArrayAdapter.add(noDevices);
}
}
}
};
}
Related
I have combed the forums in order to try and figure out why my bluetooth BroadcastReceiver isn't working and all I can find is people saying to ensure that coarse/fine location permissions are requested. I'm already doing that here (method is called before the discovery method):
Request Permissions
private void requestPermissions()
{
final int CODE = 5; // app defined constant used for onRequestPermissionsResult
boolean allPermissionsGranted = true;
String[] permissionsToRequest =
{
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
};
for(String permission : permissionsToRequest)
{
allPermissionsGranted = allPermissionsGranted &&
(ContextCompat.checkSelfPermission(this, permission)
== PackageManager.PERMISSION_GRANTED);
}
if(!allPermissionsGranted)
{
ActivityCompat.requestPermissions(this, permissionsToRequest, CODE);
}
}
The problem is that my BroadcastReceiver never finds other discoverable devices, if a device is already paired, it puts it in a ListView as expected, but once the device is unpaired, it cannot identify it again. See screenshots below.
Output with no paired devices
Output with paired devices
I'm at a loss at this point, it feels like I've tried everything, if anyone has any ideas you'd save my life and I'd be eternally grateful.
Thanks,
Broadcast Receiver
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action))
{
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if(btDevice.getBondState() != BluetoothDevice.BOND_BONDED)
{
newDevicesArrayAdapter.add(btDevice.getName() + "\n" + btDevice.getAddress());
}
}
else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
{
setTitle(R.string.select_device);
if(newDevicesArrayAdapter.getCount() == 0)
{
newDevicesArrayAdapter.clear();
String noDevices = getResources().getText(R.string.none_found).toString();
newDevicesArrayAdapter.add(noDevices);
}
}
}
};
onCreate - Setup ListView elements and IntentFilters
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_choose_machine);
setResult(Activity.RESULT_CANCELED);
pairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
newDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
pairedListView.setAdapter(pairedDevicesArrayAdapter);
pairedListView.setOnItemClickListener(deviceClickListener);
newDevicesListView.setAdapter(pairedDevicesArrayAdapter);
newDevicesListView.setOnItemClickListener(deviceClickListener);
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(broadcastReceiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(broadcastReceiver, filter);
}
doDiscovery() - Called by onStart method, I've verified that it gets called
private void doDiscovery()
{
Log.d(TAG, "doDiscovery()");
requestPermissions();
setTitle(R.string.scanning);
findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
if(btAdapter.isDiscovering()) { btAdapter.cancelDiscovery(); }
newDevicesArrayAdapter.clear();
btAdapter.startDiscovery();
}
Turns out I was just being stupid and had values updating to both ListViews, so I never saw the list of other devices.
newDevicesListView.setAdapter(pairedDevicesArrayAdapter);
Should have been:
newDevicesListView.setAdapter(newDevicesArrayAdapter);
The discovery and pairing process described in the Android Bluetooth Documentation is quite complex. Even a separate permission is needed for that: BLUETOOTH_ADMIN.
I wonder if there is a system action, that I just would call, that will handle the UI, return, and the I will just choose an already paired device. Or do I have to implement all that UI myself?
if you want to get the list of paired bluetooth devices you can use this code
public class DeviceList extends ActionBarActivity
{
//widgets
Button btnPaired;
ListView devicelist;
//Bluetooth
private BluetoothAdapter myBluetooth = null;
private Set<BluetoothDevice> pairedDevices;
public static String EXTRA_ADDRESS = "device_address";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_list);
//Calling widgets
btnPaired = (Button)findViewById(R.id.button);
devicelist = (ListView)findViewById(R.id.listView);
//if the device has bluetooth
myBluetooth = BluetoothAdapter.getDefaultAdapter();
if(myBluetooth == null)
{
//Show a mensag. that the device has no bluetooth adapter
Toast.makeText(getApplicationContext(), "Bluetooth Device Not Available", Toast.LENGTH_LONG).show();
//finish apk
finish();
}
else if(!myBluetooth.isEnabled())
{
//Ask to the user turn the bluetooth on
Intent turnBTon = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnBTon,1);
}
btnPaired.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
pairedDevicesList();
}
});
}
private void pairedDevicesList()
{
pairedDevices = myBluetooth.getBondedDevices();
ArrayList list = new ArrayList();
if (pairedDevices.size()>0)
{
for(BluetoothDevice bt : pairedDevices)
{
list.add(bt.getName() + "\n" + bt.getAddress()); //Get the device's name and the address
}
}
else
{
Toast.makeText(getApplicationContext(), "No Paired Bluetooth Devices Found.", Toast.LENGTH_LONG).show();
}
final ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, list);
devicelist.setAdapter(adapter);
devicelist.setOnItemClickListener(myListClickListener); //Method called when the device from the list is clicked
}
private AdapterView.OnItemClickListener myListClickListener = new AdapterView.OnItemClickListener()
{
public void onItemClick (AdapterView<?> av, View v, int arg2, long arg3)
{
// Get the device MAC address, the last 17 chars in the View
String info = ((TextView) v).getText().toString();
String address = info.substring(info.length() - 17);
// Make an intent to start next activity.
Intent i = new Intent(DeviceList.this, NextActivity.class);
//Change the activity.
i.putExtra(EXTRA_ADDRESS, address); //this will be received at NextActivity
startActivity(i);
}
};
}
I have made an application that allows many-to-one communication using Bluetooth and it is working perfectly fine. Now, i wanted to use the service of the application in another application (e.g. Discovering Devices, Connecting to Device). So, I marked my project as library and added it as library in my new project. However, when i call the Discovering Device Activity (Available in library) from the application, the activity starts, but it doesn't discovers the devices ? Can someone help on this ?
I have included all the library project activity and permissions in my app's manifest.
Here is the sample code for the same -
In Library -
This is how the DeviceListActivity Looks like -
`
public class DeviceListActivity extends Activity{
String insecure="8ce255c0-200a-11e0-ac64-0800200c9a66";
private int flag=0;
int flag_toast=0;
ArrayList<Pair<String,String>> x=new ArrayList<Pair<String,String>>();
private static final String TAG = "DeviceListActivity";
ArrayList<String> temp=new ArrayList<String>();
Map<String, String> services = new HashMap<String, String>();
/**
* Return Intent extra
*/
public static String EXTRA_DEVICE_ADDRESS = "device_address";
/**
* Member fields
*/
private BluetoothAdapter mBtAdapter;
/**
* Newly discovered devices
*/
ImageView animation;
private ArrayList<BluetoothDevice> btDeviceList = new ArrayList<BluetoothDevice>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup the window
// requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_device_list);
// Set result CANCELED in case the user backs out
setResult(Activity.RESULT_CANCELED);
// Initialize the button to perform device discovery
animation=(ImageView)findViewById(R.id.imageAnimation);
/*scanButton.setOnClickListener(new View.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
//ArrayAdapter<String> pairedDevicesArrayAdapter =new ArrayAdapter<String>(this, R.layout.device_name);
//mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
//Register for broadcasts when a device is discovered
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_UUID);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter);
/* 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();
animation.setBackgroundResource(R.drawable.animation);
doDiscovery();
}
#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
*/
public void doDiscovery() {
Log.d(TAG, "doDiscovery()");
// If we're already discovering, stop it
if (mBtAdapter.isDiscovering()) {
mBtAdapter.cancelDiscovery();
}
// Request discover from BluetoothAdapter
mBtAdapter.startDiscovery();
}
private void connect_automatic(String name){
flag++;
Log.d(name,"Called " + Integer.toString(flag)+" times");
Log.d("Flag is = ",Integer.toString(flag));
int i,j;
for(i=0;i<x.size();i++){
for (j=i+1;j<x.size();j++)
if (x.get(i).getFirst().equals(x.get(j).getFirst())==true && x.get(i).getSecond().equals(x.get(j).getSecond())==true)
x.remove(j);
}
for(i=0;i<x.size();i++){
Log.d("Found "+x.get(i).getFirst(),x.get(i).getSecond());
}
Log.d("Size =",Integer.toString(x.size()));
if (x.size()>=1){
Log.d("Size is =",Integer.toString(x.size()));
String address = x.get(0).getFirst();
if (flag_toast==0)
Toast.makeText(DeviceListActivity.this, "Merchant Found", Toast.LENGTH_SHORT).show();
flag_toast++;
Log.d("Connecting to ",x.get(0).getFirst());
// Create the result Intent and include the MAC address
Intent intent = new Intent();
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
// Set result and finish this Activity
setResult(Activity.RESULT_OK, intent);
finish();
}
}
/**
* 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
flag++;
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
//mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
btDeviceList.add(device);
// When discovery is finished, change the Activity title
}
else
{
Log.d("Action=",action.toString());
if(BluetoothDevice.ACTION_UUID.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
if(uuidExtra!=null)
for (int i=0; i<uuidExtra.length; i++) {
if(uuidExtra[i].toString().length()>0){
Log.d("\n Device: " + device.getName() + ", " + device, ", Service: " + uuidExtra[i].toString());
// services.put(device.getName(), uuidExtra[i].toString());
//flag=btDeviceList.size();
if (/*uuidExtra[i].toString().equals(secure)==true ||*/ uuidExtra[i].toString().equals(insecure)==true){
Pair<String,String> t=new Pair<String, String>(device.getAddress(), uuidExtra[i].toString());
x.add(t);
}
//connect_automatic();
}
}
Log.d("Device List =",Integer.toString(flag));
connect_automatic(device.getName());
//Log.d("Boolean",Boolean.toString(services.isEmpty()))
}
else
{
if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Log.d("Discovery","Started...");
}
else
{
if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Log.d("Discover","Finished");
//setProgressBarIndeterminateVisibility(false);
Iterator<BluetoothDevice> itr = btDeviceList.iterator();
while (itr.hasNext()) {
// Get Services for paired devices
BluetoothDevice device = itr.next();
temp.add(device.getName());
Log.d("ok","Getting Services for " + device.getName() + ", " + device);
if(!device.fetchUuidsWithSdp()) {
Log.d("!ok","SDP Failed for " + device.getName());
}
else{
Log.d("SDP Passed for ",device.getName());
}
}
//connect_automatic();
}
}
}
}
}
};}`
And here is how i call it in my new application -
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null)
{
ensureDiscoverable();
Intent intent = new Intent(this, DeviceListActivity.class);
startActivityForResult(intent, REQUEST_CONNECT_DEVICE_INSECURE);
}
}
First of all.... HappyNew Year!!!! I'm starting to learn about Android programming and actually I'm trying to develop some code. Main idea is to search for Paired Bluetooth devices and also list all BT devices near... later I'll try to connect both devices but time to time :P
My problem is supposed to be easy because I fill my ListView with the paired ones but using this code I can't fill the one's I discover... But I don't know what I'm doing wrong cause Toast.MakeText shows this BT devices but not in the ListView.... Anyone can help me??? Many Thanks
//SHOW ANDROID VERSION
Context context = getApplicationContext();
//Setting up for JELLY_BEAN_MR1 and above
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
BluetoothManager bluetoothManager = (BluetoothManager)context.getSystemService(Context.BLUETOOTH_SERVICE);
if (bluetoothManager != null)
{
mBluetoothAdapter = bluetoothManager .getAdapter();
}
} else {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
//Enable
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
}
//Discover my BT
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
//Paired Devices
pairedDevices = mBluetoothAdapter.getBondedDevices();
final ArrayList<String> listBT = new ArrayList<String>();
ListView lv =(ListView)findViewById(R.id.listDevicesFound);
for(BluetoothDevice bt : pairedDevices)
listBT.add(bt.getName());
//Starting Search
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
listBT.add(device.getName()); //Something happens but not adding to ListView
Toast.makeText(getApplicationContext(), device.getName(),
Toast.LENGTH_SHORT).show();
}
}
};
registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
mBluetoothAdapter.startDiscovery();
//Show ListView
lv.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1 , listBT));
Create a class variable for your adapter (above in your class):
private ArrayAdapter<String> mDeviceListAdapter;
Crete the adapter and set it to the list:
//Show ListView
mDeviceListAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1 , listBT);
lv.setAdapter(mDeviceListAdapter);
Update the adapter data when you have a new item:
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
listBT.add(device.getName());
if(mDeviceListAdapter!=null){
mDeviceListAdapter.add(device.getName());
mDeviceListAdapter.notifyDataSetChanged();
}
Toast.makeText(getApplicationContext(), device.getName(),
Toast.LENGTH_SHORT).show();
}
}
I am using DeviceListActivity for discovering Bluetooth devices. This is the activity that is used on Android Bluetooth Chat program sample.
I run the program on a virtual machine.
Problem: When I start scanning/discovering Bluetooth devices:
it lists duplicate devices name:
I have one device that is discoverable but the program lists it more than once.
How can I prevent to list duplicate devices name?
The activity code:
package com.example.android.BluetoothChat;
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.device_list);
// Set result CANCELED incase the user backs out
setResult(Activity.RESULT_CANCELED);
// 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 arg2, long arg3) {
// 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);
// Create the result Intent and include the MAC address
Intent intent = new Intent();
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
// Set result and finish this Activity
setResult(Activity.RESULT_OK, intent);
finish();
}
};
// 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);
}
}
}
};
}
Edit:
This problem is disappeared on my real device(smart phone). I don't know why an emulator has such problem!
Simple. To filter, use a Set.
Example
HashSet
Add bluetooth address on HashSet and verify with method contains().
if contains() returns false, then add the bluetooth data to the list
if contains() returns true, then DON'T add the bluetooth data to the list
Write this inside you ACTION_FOUND.
if (mNewDevicesArrayAdapter.size() < 1) {
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
mNewDevicesArrayAdapter.notifyDataSetChanged();
}
else {
boolean flag = true; // flag to indicate that particular device is already in the arlist or not
for(int i = 0; i<mNewDevicesArrayAdapter.size();i++)
{
if(device.getAddress().equals(mNewDevicesArrayAdapter.get(i).getAddress()))
{
flag = false;
}
}
if(flag == true)
{
mNewDevicesArrayAdapter.add(device.getName()+"\n"+device.getAddress());
mNewDevicesArrayAdapter.notifyDataSetChanged();
}
}
This one worked for me
public class MainActivity extends ActionBarActivity {
private ListView listView;
private ArrayList<String> mDeviceList = new ArrayList<String>();
private BluetoothAdapter mBluetoothAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.startDiscovery();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
}
#Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device.getName() + "\n" + device.getAddress());
Log.i("BT", device.getName() + "\n" + device.getAddress());
listView.setAdapter(new ArrayAdapter<String>(context,
android.R.layout.simple_list_item_1, mDeviceList));
}
}
};
In onReceive of BluetoothDevice.ACTION_FOUND, before adding a BlueTooth device to the Arraylist check if the Arraylist already contains that device using the method contains() of the ArrayList.
Add the device to the list only if contains() returns false.
Code is as below:
List<BluetoothDevice> availableDevices = new ArrayList<>();
class BluetoothReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action != null) {
switch (action) {
case BluetoothDevice.ACTION_FOUND: {
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice bluetoothDevice =
intent.getParcelableExtra(BluetoothDevice
.EXTRA_DEVICE);
//Add the device to the list only if contains() returns false.
if (!availableDevices.contains(bluetoothDevice)) {
availableDevices.add(bluetoothDevice);
}
displayAvailableDevices();
break;
}
It worked for me
#Override
public void onDeviceDiscovered(BluetoothDevice device) {
listener.endLoading(true);
devices.contains(device);
//======================To add only unique device not repeating same device in listView========================
if( devices.contains(device)){
}else {
devices.add(device);
}
//======================End of add only unique device not repeating same device in listView====================
notifyDataSetChanged();
}