I'm trying to create an app that scans for wifi. When the player does something in the game, it "consumes" the strongest wifi signal. That signal should no longer be detected on the next scan.
Anyone who's played Metal Gear Solid Portable ops would know what I mean.
I tried to do this by creating a List of Wireless Signals that have already been used by the player and can no longer be detected again. The problem is that after scanning the best network, I scan again and it still displays the same network instead of ignoring it.
public void onClick(View arg0) {
if (arg0.getId() == R.id.bStart) {
ActivityLoader.loadMain(this);
}
if (arg0.getId() == R.id.bScan) {
Toast.makeText(this, "Searching....", Toast.LENGTH_LONG).show();
for (ScanResult selectedSpot : networkList) {
{
if (firstSignal == null || checkIfNotUsed(firstSignal)) {
firstSignal = selectedSpot;
usedNetworks.add(firstSignal.SSID);
break;
}
}
}
}
if (firstSignal != null) {
Toast.makeText(
this,
"Found Food and Ammo at the " + firstSignal.SSID
+ " store.", Toast.LENGTH_LONG).show();
// textStatus.setText(usedNetworks.toString());
textStatus.setText(networkList.toString());
} else {
Toast.makeText(this, "Found nothing!!!", Toast.LENGTH_LONG).show();
}
}
private boolean checkIfNotUsed(ScanResult selectedSpot) {
// TODO Auto-generated method stub
boolean flag = true;
if (usedNetworks.isEmpty()) {
flag = true;
} else {
for (String used : usedNetworks) {
if (selectedSpot.SSID.equals(used)) {
flag = false;
break;
}
}
}
return flag;
}
Related
Inside the BluetoothGattCallback method onConnectionStateChange I am checking for the successful connection with the BLE device and calling the discoverServices method afterwards. The BLE device needs a pin entry (prompt by Android) for an successful pairing. I want to discover all available services immediately after connecting to the device because when switching to the main activity of the application there should be data from the available characteristics already displayed.
I tried to analyze the functionality of the onConnectionStateChange method and the behavior of the BLE device with pin. Unfortunately the method is called once you initialize the connection and again after successfully entering the pin. There isn't a difference within the receiving state codes. Status and newState are exactly the same when initializing and after successful pin entry and connection. Therefore i added this workaround with the Thread.sleep method to wait for the user entry of the pin and call afterwards the discoverServices method. But this workaround is not very practical because the user need to enter the pin within these 10 seconds. If not the connection is successful but the services won't be discovered.
How can i check or differ between these two states? Initializing the connection and successful enter of the pin?
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.d("KOPPLUNG", "In onConnectionStateChange with status: " + status + " and newState: " + newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
broadcastUpdate(ACTION_GATT_CONNECTED, mCallbackBleAddress);
Log.i(TAG, "Connected to GATT server." + mCallbackBleAddress);
// Attempts to discover services after successful connection.
try {
Thread.sleep(10000);
} catch (Exception e) {
}
for(int i = 0; i<5; i++){
if(mBoltDeviceHandler.getBoltDevice(mCallbackBleAddress).getBluetoothGatt().discoverServices()){
Log.i(TAG, "Attempting to start service discovery:" + true);
break;
}
}
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
switch (status){
case 0: Log.i(TAG, "Sucessfully Disconnected from GATT server.");
break;
case 133: // Handle internal Android Bug
Log.i(TAG, "Connection aborted, Android Error 133");
broadcastUpdate(ACTION_GATT_CONNECTION_NOT_SUCCESSFUL, mCallbackBleAddress);
break;
default: Log.i(TAG, "Unexpected Disconnection from GATT server. Errorcode: "+status);
broadcastUpdate(ACTION_GATT_DISCONNECTED, mCallbackBleAddress);
autoconnect(gatt.getDevice());
}
Addition
The code for building up the connection is divided up in three different classes. The application starts with an scan activity where available devices are being searched and listed. By clicking on one list item (device) the connection process will be started.
onListItemClick
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
if (device == null) return;
Context mContext = getApplicationContext();
BoltDevice boltDevice = new BoltDevice(device,mContext);
int i = mBoltDeviceHandler.addBoltDevice(boltDevice);
Intent resultIntent = new Intent();
resultIntent.putExtra("IN_CONNECTION", boltDevice.getBleAddress());
resultIntent.putExtra("POSITION",i);
if(i != -1){
setResult(Activity.RESULT_OK, resultIntent);
}
else {
setResult(Activity.RESULT_CANCELED, resultIntent);
}
finish();
}
By running the above code an object from type BoltDevice is being created and added to the BoltDeviceHandler.
Relevant code from BoltDevice class
public BoltDevice(BluetoothDevice device, Context context) {
mContext = context;
this.mBluetoothDevice = device;
this.mBleAddress = device.getAddress();
this.mDeviceName = device.getName();
mBatteryLevel = 0;
mSpecialBolt = false;
//Workarround for 133 error taken from: https://github.com/googlesamples/android-BluetoothLeGatt/issues/44
mStartGattHandler.postDelayed(mStartGattRunnable, START_GATT_DELAY);
}
public void closeGatt() {
if (mBluetoothGatt != null) {
mBluetoothGatt.disconnect();
mBluetoothGatt.close();
mBluetoothGatt = null;
}
}
public boolean connect() {
// Previously connected device. Try to reconnect.
if (mBluetoothGatt != null) {
Log.d(TAG, "Trying to connect with existing bluetoothGATT to: " + mBleAddress);
if (mBluetoothGatt.connect()) {
return true;
} else {
Log.d(TAG, "Could not connect to existing bluetoothGATT: " + mBleAddress);
return false;
}
}
// We want to directly connect to the device, so we are setting the autoConnect
// parameter to false.
mBluetoothLeService.connect(mBluetoothDevice);
Log.d(TAG, "Trying to create a new connection to: " + mBluetoothDevice.getAddress());
return true;
}
public boolean disconnect() {
if (mBluetoothGatt != null) {
mBluetoothGatt.disconnect();
return true;
} else {
return false;
}
}
public void bindService(){
Intent gattServiceIntent = new Intent(mContext, BluetoothLeService.class);
}
Relevant code from the MainActivity (active after the ScanActivity is finished)
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case (5) : {
if (resultCode == Activity.RESULT_OK) {
int i = data.getIntExtra("POSITION",-1);
mReconnect[i] = false;
runOnUiThread(new Runnable() {
#Override
public void run() {
if(!isFinishing()) {
updateText(i,true);
ToastCompat.makeText(MainActivity.this, "In Connection!", ToastCompat.LENGTH_SHORT).show();
}
}
});
}
if (resultCode == Activity.RESULT_CANCELED) {
if(data!=null) {
int i = mBoltDeviceHandler.getBoltDevicePositionInList(data.getStringExtra("IN_CONNECTION"));
mReconnect[i] = true;
runOnUiThread(new Runnable() {
#Override
public void run() {
if(!isFinishing()) {
ToastCompat.makeText(MainActivity.this, "In Connection!", ToastCompat.LENGTH_SHORT).show();
}
}
});
}
else{
ToastCompat.makeText(this,"No device selected!", ToastCompat.LENGTH_SHORT).show();
}
}
break;
}
}
}
(...)
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
final String address = intent.getStringExtra(BluetoothLeService.EXTRA_ADDRESS);
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
ToastCompat.makeText(MainActivity.this, mBoltDeviceHandler.getBoltDevice(address).getDeviceName() + " " + getResources().getString(R.string.BLE_Connected), ToastCompat.LENGTH_SHORT).show();
updateText(mBoltDeviceHandler.getBoltDevicePositionInList(address), false);
ToastCompat.makeText(MainActivity.this, mBoltDeviceHandler.getBoltDevice(address).getDeviceName()+ ": "+ getResources().getString(R.string.BLE_ServicesDiscovered), ToastCompat.LENGTH_SHORT).show();
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
(...)
First of all, I would recommend using the Nordic library. That saved me a lot of headhacke when working with BLE on android and allow to keep a clean architecture.
You should have something of the state machine like :
connect to device
request GATT services / characteristic
request for the user code on Android
send user code
retrieve data over BLE
Also, after receiving a onConnection status change notifcation, you should xwait a few ms before starting discovering GATT
The onConnectionStateChange event is triggered just after the Android connects to a device.Moreover, when the device has Service Changed indication enabled, and the list of services has changed (e.g. using the DFU), the indication is received few hundred milliseconds later, depending on the connection interval. When received, Android will start performing a service discovery operation on its own, internally, and will NOT notify the app that services has changed.
public final void onConnectionStateChange(#NonNull final BluetoothGatt gatt,
final int status, final int newState) {
if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
// Sometimes, when a notification/indication is received after the device got
// disconnected, the Android calls onConnectionStateChanged again, with state
// STATE_CONNECTED.
// See: https://github.com/NordicSemiconductor/Android-BLE-Library/issues/43
if (bluetoothDevice == null) {
Log.e(TAG, "Device received notification after disconnection.");
log(Log.DEBUG, "gatt.close()");
try {
gatt.close();
} catch (final Throwable t) {
// ignore
}
return;
}
// Notify the parent activity/service
Log("Connected to " + gatt.Device.Address);
isConnected = true;
connectionState = State.Connected;
OnDeviceConnected(gatt.Device);
/*
* TODO: Please calculate the proper delay that will work in your solution.
* If your device does not use Service Change indication (for example does not have DFU) the delay may be 0.
*/
var delay = 1600; // around 1600 ms is required when connection interval is ~45ms.
postDelayed(() -> gatt.DiscoverServices(), delay);
} else {
if (newState == ProfileState.Disconnected)
{
var wasConnected = IsConnected;
if (gatt != null)
{
NotifyDeviceDisconnected(gatt.Device); // This sets the mConnected flag to false
if (_initialConnection) ConnectDevice(gatt.Device);
if (wasConnected || status == GattStatus.Success)
return;
}
}
/*
* Connection attempt did fail! Retry possible ?
*/
onError(gatt.Device, Error.LinkLost, status);
}
}
This post will be long because I'm trying to explain the full scenario of my problem. Please read it patiently.
Now, I'm trying to control the app features using some physical buttons connected to Arduino. To connect the Arduino to a mobile device I'm using an OTG cable.
I have three activities. One is a splash activity, which is launcher one. The other two are Activity1 and Activity2, in which I use this Arduino thing.
So now I've made a broadcast receiver for system actions i.e., USB Permission, USB Attached and USB Detached. I wrote the broadcast receiver in the activities itself separately. And I register the receiver when the activity is created i.e., in onCreate(). That goes for both the activities. And I unregister the receiver when the activity is destroyed.
In the broadcast receiver's onReceive() method, I write the code like this:
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
//Broadcast Receiver to automatically start and stop the Serial connection.
#Override
#AddTrace(name = "broadcast receiver", enabled = true/*Optional*/)
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
boolean granted = intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
Toast.makeText(NewCameraActivity.this, String.valueOf(granted), Toast.LENGTH_SHORT).show();
device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (granted) {
connection = usbManager.openDevice(device);
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
if (serialPort != null) {
if (serialPort.open()) {
//Set Serial Connection Parameters.
serialPort.setBaudRate(9600);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(mCallback);
Toast.makeText(NewCameraActivity.this, "Port Opening", Toast.LENGTH_SHORT).show();
} else {
Log.d("SERIAL", "PORT NOT OPEN");
Toast.makeText(NewCameraActivity.this, "PORT NOT OPEN", Toast.LENGTH_SHORT).show();
} else {
Log.d("SERIAL", "PORT IS NULL");
Toast.makeText(NewCameraActivity.this, "PORT IS NULLg", Toast.LENGTH_SHORT).show();
}
} else {
Log.d("SERIAL", "PERM NOT GRANTED");
Toast.makeText(NewCameraActivity.this, "PERM NOT GRANTED", Toast.LENGTH_SHORT).show();
}
} else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
onClickStart();
} else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
onClickStop();
finish();
}
};
};
UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
#Override
public void onReceivedData(byte[] arg0) {
String data;
try {
data = new String(arg0, "UTF-8");
final String finalData = data;
runOnUiThread(new Runnable() {
#Override
public void run() {
switch (finalData) {
case "portopen":
break;
case "portinc":
System.exit(0);
break;
case "scan":
onClickStop();
requestPicture();
break;
case "lang":
counter++;
counter = counter % 3;
if (counter == 0) {
ImageNameSingleton.getInstance().setLanguage("eng");
textToSpeech.speak("English selected", TextToSpeech.QUEUE_FLUSH, myHash1);
} else if (counter == 1) {
ImageNameSingleton.getInstance().setLanguage("hin");
textToSpeech.speak("Hindi Selected", TextToSpeech.QUEUE_FLUSH, myHash1);
} else if (counter == 2) {
ImageNameSingleton.getInstance().setLanguage("mar");
textToSpeech.speak("Marathi Selected", TextToSpeech.QUEUE_FLUSH, myHash1);
}
break;
default:
break;
}
}
});
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} //Defining a Callback which triggers whenever data is read.
};
#AddTrace(name = "onClickstart", enabled = true/*Optional*/)
public void onClickStart() {
Toast.makeText(NewCameraActivity.this, "onClickStart", Toast.LENGTH_SHORT).show();
HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
if (!usbDevices.isEmpty()) {
boolean keep = true;
for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
device = entry.getValue();
int deviceVID = device.getVendorId();
Toast.makeText(NewCameraActivity.this, String.valueOf(deviceVID), Toast.LENGTH_SHORT).show();
if (deviceVID == 0x1A86) {
//Arduino Vendor ID
Toast.makeText(NewCameraActivity.this, "Device Found", Toast.LENGTH_SHORT).show();
Toast.makeText(NewCameraActivity.this, String.valueOf(deviceVID) + String.valueOf(device.getProductId()), Toast.LENGTH_SHORT).show();
PendingIntent pendingintent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
Toast.makeText(this, String.valueOf(usbManager.hasPermission(device)), Toast.LENGTH_SHORT).show();
usbManager.requestPermission(device, pendingintent);
keep = false;
connectionEstablished = true;
} else {
Toast.makeText(NewCameraActivity.this, "Device Not Found", Toast.LENGTH_SHORT).show();
connection = null;
device = null;
}
if (!keep) break;
}
}
}
private void onClickStop() {
if(serialPort!=null) serialPort.close();
else Toast.makeText(this, "No serial port", Toast.LENGTH_SHORT).show();
}
Here, when the device is connected to USB, the USB attached action is started and it will start to look for the devices and will search for a particular device with that vendorID. When it gets the device, it will start the USB Permission action to check the permission is given or not. If yes, the code in the USB permission action will be executed. If not, it will ask the user for permission.
Everything is the same for both activities.
Now in Activity1, after the serial port is opened, I will send a string by clicking a button and I receive it in the activity. Based on the string, a particular job will be done (as you can see it in the callback part). After the job (like clicking an image), the data will be sent to Activity2 and the Activity1 will be destroyed along with the receiver.
In Activity2, I will register the receiver again and I'm opening the port again and I'm getting the strings to do jobs.
This is the workflow. Now the problem is, I want the app to open (in the foreground), whether the app is in background or killed, when a button is clicked in Arduino. Also, the app should close when any other button is clicked.
How to do it? Is there any way? Or is my approach not correct? Anyone help me out...
Any help would be appreciated.
i want to build an application using wifi direct to transfer files and i'm using NFC to reduce pairing time. I've already follow the instruction in http://developer.android.com/guide/topics/connectivity/wifip2p.html and http://developer.android.com/training/connect-devices-wirelessly/wifi-direct.html but my apps won't connect. and i took the code from wifi direct demo from android example.
when i trace the problem is when wifi direct broadcast receiver WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION the network info won't to connect with other device so, in my main class that implements ConnectionInfoListener that have a method onConnectionInfoAvailable it's never triggered.
can anyone help me? thx before
the code is like this
Wifi Direct BroadCast Receiver
`
public void onReceive(Context arg0, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
// UI update to indicate wifi p2p status.
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
// Wifi Direct mode is enabled
activity.setIsWifiP2pEnabled(true);
} else {
activity.setIsWifiP2pEnabled(false);
//activity.resetData();
}
//Log.d(WiFiDirectActivity.TAG, "P2P state changed - " + state);
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
// request available peers from the wifi p2p manager. This is an
// asynchronous call and the calling activity is notified with a
// callback on PeerListListener.onPeersAvailable()
if (manager != null) {
}
//Log.d(WiFiDirectActivity.TAG, "P2P peers changed");
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
if (manager == null) {
return;
}
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {
// we are connected with the other device, request connection
// info to find group owner IP
manager.requestConnectionInfo(channel, activity);
} else {
// It's a disconnect
}
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
WifiP2pDevice device = (WifiP2pDevice) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
activity.myname = device.deviceName + " " + device.deviceAddress + " " + device.primaryDeviceType + " " + device.secondaryDeviceType + " " + device.status;
}
}`
my main class
`
// how to connect
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = names[1];
config.wps.setup = WpsInfo.PBC;
config.groupOwnerIntent = 15;
connect(config);
public void connect(WifiP2pConfig config) {
manager.connect(channel, config, new ActionListener() {
#Override
public void onSuccess() {
// WiFiDirectBroadcastReceiver will notify us. Ignore for now.
}
#Override
public void onFailure(int reason) {
Toast.makeText(getApplicationContext(), "Connect failed. Retry.", Toast.LENGTH_SHORT).show();
}
});
}
public void disconnect() {
manager.removeGroup(channel, new ActionListener() {
#Override
public void onFailure(int reasonCode) {
//Log.d(TAG, "Disconnect failed. Reason :" + reasonCode);
Toast.makeText(getApplicationContext(), "Disconnect failed. Reason :" + reasonCode, Toast.LENGTH_SHORT).show();
}
#Override
public void onSuccess() {
Toast.makeText(getApplicationContext(), "Disconnected", Toast.LENGTH_SHORT).show();
}
});
}
public void onChannelDisconnected() {
// we will try once more
if (manager != null && !retryChannel) {
Toast.makeText(this, "Channel lost. Trying again", Toast.LENGTH_LONG).show();
//resetData();
retryChannel = true;
manager.initialize(this, getMainLooper(), this);
} else {
Toast.makeText(this,
"Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P.",
Toast.LENGTH_LONG).show();
}
}
public void onConnectionInfoAvailable(WifiP2pInfo info) {
// TODO Auto-generated method stub
this.info = info;
// After the group negotiation, we can determine the group owner.
if (info.groupFormed && info.isGroupOwner) {
// Do whatever tasks are specific to the group owner.
// One common case is creating a server thread and accepting
// incoming connections.
Toast.makeText(getApplicationContext(), "Owner", Toast.LENGTH_SHORT).show();
} else if (info.groupFormed) {
// The other device acts as the client. In this case,
// you'll want to create a client thread that connects to the group
// owner.
Toast.makeText(getApplicationContext(), "Client", Toast.LENGTH_SHORT).show();
}
}
`
onConnectionInfoAvailable will never be executed because the networkInfo.isConnected() is never true.
Please help me.. Thx..
I want to pair the device and connect it ,but I have a problem ,I just can pair device but I am not able to connect them. I want to know how to solve this problem. I'm afraid, I have not explained my problem very well, I can not connect means, connect your phone to a Bluetooth headset and I can only pair, here is the code
if (btAdapt.isEnabled()) {
tbtnSwitch.setChecked(false);
} else {
tbtnSwitch.setChecked(true);
}
// ============================================================
IntentFilter intent = new IntentFilter();
intent.addAction(BluetoothDevice.ACTION_FOUND);
intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(searchDevices, intent);
}
private BroadcastReceiver searchDevices = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Bundle b = intent.getExtras();
Object[] lstName = b.keySet().toArray();
for (int i = 0; i < lstName.length; i++) {
String keyName = lstName[i].toString();
Log.e(keyName, String.valueOf(b.get(keyName)));
}
BluetoothDevice device = null;
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
String str = "no pair|" + device.getName() + "|"
+ device.getAddress();
if (lstDevices.indexOf(str) == -1)
lstDevices.add(str);
adtDevices.notifyDataSetChanged();
}
}else if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (device.getBondState()) {
case BluetoothDevice.BOND_BONDING:
Log.d("BlueToothTestActivity", "it is pairing");
break;
case BluetoothDevice.BOND_BONDED:
Log.d("BlueToothTestActivity", "finish");
connect(device);
break;
case BluetoothDevice.BOND_NONE:
Log.d("BlueToothTestActivity", "cancel");
default:
break;
}
}
}
};
#Override
protected void onDestroy() {
this.unregisterReceiver(searchDevices);
super.onDestroy();
android.os.Process.killProcess(android.os.Process.myPid());
}
class ItemClickEvent implements AdapterView.OnItemClickListener {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
if(btAdapt.isDiscovering())btAdapt.cancelDiscovery();
String str = lstDevices.get(arg2);
String[] values = str.split("\\|");
String address = values[2];
Log.e("address", values[2]);
BluetoothDevice btDev = btAdapt.getRemoteDevice(address);
try {
Boolean returnValue = false;
if (btDev.getBondState() == BluetoothDevice.BOND_NONE) {
BluetoothDevice.createBond(BluetoothDevice remoteDevice);
Method createBondMethod = BluetoothDevice.class
.getMethod("createBond");
Log.d("BlueToothTestActivity", "start");
returnValue = (Boolean) createBondMethod.invoke(btDev);
}else if(btDev.getBondState() == BluetoothDevice.BOND_BONDED){
connect(btDev);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void connect(BluetoothDevice btDev) {
UUID uuid = UUID.fromString(SPP_UUID);
try {
btSocket = btDev.createInsecureRfcommSocketToServiceRecord(uuid);
Log.d("BlueToothTestActivity", "connecting...");
btSocket.connect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class ClickEvent implements View.OnClickListener {
public void onClick(View v) {
if (v == btnSearch)
{
if (btAdapt.getState() == BluetoothAdapter.STATE_OFF) {
Toast.makeText(BlueToothTestActivity.this, "please open", 1000)
.show();
return;
}
if (btAdapt.isDiscovering())
btAdapt.cancelDiscovery();
lstDevices.clear();
Object[] lstDevice = btAdapt.getBondedDevices().toArray();
for (int i = 0; i < lstDevice.length; i++) {
BluetoothDevice device = (BluetoothDevice) lstDevice[i];
String str = "pair|" + device.getName() + "|"
+ device.getAddress();
lstDevices.add(str);
adtDevices.notifyDataSetChanged();
}
setTitle("address:" + btAdapt.getAddress());
btAdapt.startDiscovery();
} else if (v == tbtnSwitch) {
if (tbtnSwitch.isChecked() == false)
btAdapt.enable();
else if (tbtnSwitch.isChecked() == true)
btAdapt.disable();
} else if (v == btnDis)
{
Intent discoverableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(
BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
} else if (v == btnExit) {
try {
if (btSocket != null)
btSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
BlueToothTestActivity.this.finish();
}
}
}
}
You have not specified, but I assume your problem is in the socket creation part rather than the actual connect() call. This is where things usually go wrong.
How to fix?
Your code assumes the headset supports insecure BT communications. In many cases this is true, but not in all. Try calling createRfcommSocketToServiceRecord() instead
Your code uses the default SPP UUID for the RFCOMM channel lookup. For API versions >= 15 this is the wrong thing to do. Instead try calling device.getUuids() and use the first returned UUID as the creation parameter.
From my own experience, even for pre-15 API versions you can still call getUuids() and get good results, but you will need to do it by reflection. Only if the above fails should you attempt socket creation with the default SPP UUID
If the above fails, you may try, as a last resort, to activate the "createRfcommSocket" hidden API . That had worked for me several occasions, and on multiple Android versions. Use java reflection to activate this call and, since inherently not safe, protect it with try catch.
Remember to place your logic in an AsyncTask or something. You do not want the UI thread to block on such tasks!
Finally feel free to use https://github.com/giladHaimov/BTWiz for a much simpler handling of the Bluetooth connect and for simple async IO interface.
Quoting your code:
btSocket = btDev.createInsecureRfcommSocketToServiceRecord(uuid);
Log.d("BlueToothTestActivity", "connecting...");
btSocket.connect();
You can find the code on the official Android documentation on connecting as a client, here.
I can see 4 things that might cause problems:
You should connect in a separate thread! .connect() is a blocking call - see link above
Not all devices accept insecure connections
For Android devices below 2.3.3 this method does not work. You have to call a private method via reflection - see this. Also I think you will find it on SO.
Surround .create.... with a try/catch and post errors on Logcat.
Can you post your Logcat logs?
The android application is bulit in such a way that when data is being sent(on clicking the button) to the usb device ,LED toggles and the data is being displayed. I want data to be sent continuously without any manual intervention. Kindly help
if (mInputStream != null)
{
int Data = 0;
try {
Data = mInputStream.read();
} catch (IOException e) {
}
if (Data == LED_ON)
{
ledStatus.setText("LED is ON");
}
else if (Data == LED_OFF)
{
ledStatus.setText("LED is OFF");
}
else
{
ledStatus.setText("Request failed");
}
}
else
{
ledStatus.setText("mInputStream == null");
}
this time I have tested it myself...
it should definitely work
paste it in your onCreate() good luck :)
Timer t = new Timer();
t.schedule(new TimerTask(){
public void run(){
// write the method name here. which you want to call continuously
Log.d("timer", "timer");
}
},10, 1000);