So i'm making a OBDII Bluetooth app were the user can send commands such as voltage (in this case) and get data from the OBDII. So far i've managed to make a Bluetooth connection with my mobile device to my OBDII adapter work and now I need to send some basic commands and displaying them in Logcat (for the moment).
The problem i'm having is that it doesn't recognize my onClick method?
Could not find method onClick(View) in a parent or ancestor Context
for android:onClick attribute defined on view class
android.support.v7.widget.AppCompatButton with id 'getValue'
I'm sure that i've missed something in my code, but I dont know what.
MainActivity.java
public class MainActivity extends AppCompatActivity {
Button b1;
BluetoothAdapter mAdapter;
FragmentHostCallback mHost;
BTHandler btHandler;
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BTHandler.STATE_CONNECTED:
//setContentView(R.layout.activity_connected);
Intent intent = new Intent(MainActivity.this, Connected.class);
startActivity(intent);
Toast.makeText(getApplicationContext(), R.string.title_connected_to, Toast.LENGTH_SHORT).show();
Log.v("Log", "Connected");
break;
case BTHandler.STATE_NONE:
Toast.makeText(getApplicationContext(), R.string.title_not_connected, Toast.LENGTH_SHORT).show();
break;
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btHandler = new BTHandler(MainActivity.this, mHandler);
b1 = (Button) findViewById(R.id.connect);
mAdapter = BluetoothAdapter.getDefaultAdapter();
//init();
if (mAdapter == null) {
Toast.makeText(getApplicationContext(), R.string.device_not_supported, Toast.LENGTH_LONG).show();
finish();
} else {
if (!mAdapter.isEnabled()) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
}
//BTHandler btHandler = new BTHandler(MainActivity.this, mHandler);
//btHandler.connect("");
}
public void onClick(View v) {
int id = v.getId();
String sendMessage = ("AT RV");
switch (id) {
case R.id.connect:
onConnect(); //Operation
Log.v("Log", "Pressed onClick");
break;
case R.id.getValue:
btHandler.write(sendMessage);
Log.v("Log", "getValue" + sendMessage);
break;
}
}
BTHandler.java
public class BTHandler {
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
final ArrayList<String> devices = new ArrayList();
private final Handler mHandler;
private BluetoothAdapter mAdapter;
private BluetoothDevice device;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private BluetoothSocket socket;
private String status;
private int mState;
private boolean connectionStatus = false;
public BTHandler(Context context, Handler handler) { // Konstruktor
mAdapter = BluetoothAdapter.getDefaultAdapter();
mHandler = handler;
}
public void write(String s) {
mConnectedThread.sendRawCommand(s);
}
/*
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
*/
public void connect(String deviceAddress) {
mConnectThread = new ConnectThread(deviceAddress);
mConnectThread.start();
}
private void guiHandler(int what, int arg1, String obj) {
Message msg = mHandler.obtainMessage();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.sendToTarget();
}
private class ConnectThread extends Thread {
BluetoothSocket tmp = null;
private BluetoothSocket mmSocket;
public ConnectThread(String deviceAddress) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
device = mAdapter.getRemoteDevice(deviceAddress);
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
tmp = device.createRfcommSocketToServiceRecord(uuid);
//socket.connect();
//Log.v("connect", "connect");
} catch (IOException e) {
//e.printStackTrace();
//Log.v("exception", "e");
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mAdapter.cancelDiscovery();
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes;
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.v("connect", "connect");
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
Log.v("close", "close");
} catch (IOException closeException) {
}
guiHandler(Constants.TOAST, Constants.SHORT, "Connection Failed");
return;
}
guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private ObdMultiCommand multiCommand;
public ConnectedThread(BluetoothSocket socket) {
connectionStatus = true;
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
try {
RPMCommand engineRpmCommand = new RPMCommand();
SpeedCommand speedCommand = new SpeedCommand();
ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
while (!Thread.currentThread().isInterrupted()) {
engineRpmCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
speedCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
voltageCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
// TODO handle commands result
Log.d("Log", "RPM: " + engineRpmCommand.getFormattedResult());
Log.d("Log", "Speed: " + speedCommand.getFormattedResult());
Log.v("Log", "Voltage: " + speedCommand.getFormattedResult());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
OBDcmds();
// Keep listening to the InputStream until an exception occurs
while (connectionStatus) {
sendMultiCommand();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// CALL this to MainActivity
public void sendRawCommand(String s) {
try {
//new ObdRawCommand();
} catch (Exception e) {
}
}
private void OBDcmds() { // execute commands
try {
new EchoOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new LineFeedOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new TimeoutCommand(125).run(socket.getInputStream(), socket.getOutputStream());
new SelectProtocolCommand(ObdProtocols.AUTO).run(socket.getInputStream(), socket.getOutputStream()); //ISO_15765_4_CAN
} catch (Exception e) {
Log.v("Log", "e");
// handle errors
}
}
/*
// Call this from the main activity to send data to the remote device
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
*/
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
public void sendMultiCommand() {
try {
// RUN some code here
} catch (Exception e) {
}
}
}
}
EDIT:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {...}
#Override
protected void onCreate(Bundle savedInstanceState) {
b1 = (Button) findViewById(R.id.connect);
b1.setOnClickListener(this);
}
Logcat:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.asabanov.powersupplytool, PID: 26570
java.lang.IllegalStateException: Could not find method onClick(View) in a parent or ancestor Context for android:onClick
attribute defined on view class
android.support.v7.widget.AppCompatButton with id 'getValue'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:307)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:266)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21266)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5845)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
W/System.err: com.github.pires.obd.exceptions.UnableToConnectException: Error
running 01 42, response: 0142...UNABLETOCONNECT
W/System.err: at java.lang.Class.newInstance(Native Method)
W/System.err: at com.github.pires.obd.commands.ObdCommand.checkForErrors(ObdCommand.java:203)
W/System.err: at com.github.pires.obd.commands.ObdCommand.readResult(ObdCommand.java:123)
W/System.err: at com.github.pires.obd.commands.ObdCommand.run(ObdCommand.java:77)
W/System.err: at com.example.asabanov.powersupplytool.BTHandler$ConnectedThread.(BTHandler.java:151)
W/System.err: at com.example.asabanov.powersupplytool.BTHandler$ConnectThread.run(BTHandler.java:117)
V/Log: e
EDIT:
private void onConnect() {
ArrayList deviceStrs = new ArrayList();
final ArrayList<String> devices = new ArrayList();
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
Set pairedDevices = mAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (Object device : pairedDevices) {
BluetoothDevice bdevice = (BluetoothDevice) device;
deviceStrs.add(bdevice.getName() + "\n" + bdevice.getAddress());
devices.add(bdevice.getAddress());
}
}
// show list
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.select_dialog_singlechoice,
deviceStrs.toArray(new String[deviceStrs.size()]));
alertDialog.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
String deviceAddress = devices.get(position);
btHandler.connect(deviceAddress);
//btHandler.write();
}
});
alertDialog.setTitle("Paired devices");
alertDialog.show();
}
You should set an onClickListener for your button.
For that, you need to implement OnClickListener interface as:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
When you create the button, set its OnClickListener as follows:
b1 = (Button) findViewById(R.id.connect);
b1.setOnClickListener(this);
This should get you to your onClick method, when the button is clicked.
Edit: i see you have two buttons. Just do the same for the other button. Don't forget to declare a member for b2, just like b1.
Button b2;
b2 = (Button)findViewById(R.id.getValue);
b2.setOnClickListener(this);
Related
I am trying to send data over bluetooth to stm32f411 board. I am using HC-05 v2 bluetooth module which communicates over UART interface. When I'm sending data from computer it works perfectly- data is sent and STM's response is received over UART in RealTerm. However switching to bluetooth module and sending and receiving data from android app doesn't work as expected. For now I want to send ASCII data (for now just 0 and 1, but the goal is to send integers from 0 to 100). Perhaps it has something to do with message length or app's baud rate.
I also tried to send data as byte not byte array but it didn't work- when I sent 0 it worked fine but when I sent 1 I got 120 decimal on STM, 2 I got 128, 3 I got 248. When I tried sending the same data back to app every message started with [B# followed by usually 7 characters.
My android studio code:
public class MainActivity extends AppCompatActivity {
Button someButton;
ListView pairedDevListView;
Switch bluetoothSwitch;
BluetoothAdapter myBluetoothAdapter;
Intent bluetoothEnablingIntent;
TextView connectionStatusText;
SeekBar rightEnSeekBar, leftEnSeekBar;
SendReceive sendReceive;
BluetoothDevice[] bluetoothPairedDevArray;
int REQUEST_ENABLE_BLUETOOTH = 1;
int requestCodeForEnable;
static final int STATE_LISTENING = 1;
static final int STATE_CONNECTING = 2;
static final int STATE_CONNECTED = 3;
static final int STATE_CONNECTION_FAILED = 4;
static final int STATE_MESSAGE_RECEIVED = 5;
private static final String APP_NAME = "STM32";
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(#NonNull Message message) {
switch (message.what){
case STATE_LISTENING:
connectionStatusText.setText("Listening");
break;
case STATE_CONNECTING:
connectionStatusText.setText("Connecting");
break;
case STATE_CONNECTED:
connectionStatusText.setText("Connected");
break;
case STATE_CONNECTION_FAILED:
connectionStatusText.setText("Connection failed");
break;
case STATE_MESSAGE_RECEIVED:
byte[] readBuff = (byte[]) message.obj;
//String tempMsg = new String(readBuff, 0 , message.arg1);
String tempMsg = null;
try {
tempMsg = new String(readBuff, "ASCII");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), String.valueOf(readBuff), Toast.LENGTH_SHORT).show();
connectionStatusText.setText(tempMsg);
break;
}
return true;
}
});
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothEnablingIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
requestCodeForEnable = 1;
if(!myBluetoothAdapter.isEnabled()){
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BLUETOOTH);
}
findViewByIds();
implementListeners();
}
private void findViewByIds() {
pairedDevListView = findViewById(R.id.pairedDevicesListView);
bluetoothSwitch = findViewById(R.id.btSwitch);
connectionStatusText = findViewById(R.id.statusTextView);
rightEnSeekBar = findViewById(R.id.rightSeekBar);
leftEnSeekBar = findViewById(R.id.leftSeekBar);
someButton = findViewById(R.id.button2);
}
private void implementListeners() {
//BLUETOOTH ENABLING SWITCH
bluetoothSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b){
if(myBluetoothAdapter == null){
Toast.makeText(getApplicationContext(),"Bluetooth is not supported on this device", Toast.LENGTH_LONG).show();
}
else{
if(!myBluetoothAdapter.isEnabled()){
startActivityForResult(bluetoothEnablingIntent, requestCodeForEnable);
}
}
}
else{
if(myBluetoothAdapter.isEnabled()){
myBluetoothAdapter.disable();
Toast.makeText(getApplicationContext(), "Bluetooth is disabled", Toast.LENGTH_LONG).show();
}
}
}
});
//CLICKING ON DEVICE FROM PAIRED DEVICE LIST
pairedDevListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
ClientClass clientClass = new ClientClass(bluetoothPairedDevArray[i]);
clientClass.start();
connectionStatusText.setText("Connecting");
}
});
someButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String string = "1";
try {
sendReceive.write(string.getBytes("ASCII"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
}
//SHOWING PAIRED DEVICES WHEN SWITCH IS CHECKED
private void showPairedDevices() {
Set<BluetoothDevice> btDevices = myBluetoothAdapter.getBondedDevices();
bluetoothPairedDevArray = new BluetoothDevice[btDevices.size()];
String[] deviceNames = new String[btDevices.size()];
int index = 0;
if(btDevices.size() > 0){
for(BluetoothDevice device: btDevices){
deviceNames[index] = device.getName();
bluetoothPairedDevArray[index] = device;
index++;
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, deviceNames);
pairedDevListView.setAdapter(arrayAdapter);
}
}
//SHOWING POP UP MESSAGE
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
if(requestCode == requestCodeForEnable){
if(resultCode == RESULT_OK){
Toast.makeText(getApplicationContext(), "Bluetooth is enabled", Toast.LENGTH_LONG).show();
showPairedDevices();
}
else if(resultCode == RESULT_CANCELED){
Toast.makeText(getApplicationContext(), "Bluetooth enabling cancelled", Toast.LENGTH_LONG).show();
}
}
}
private class ClientClass extends Thread{
private BluetoothSocket socket;
private BluetoothDevice device;
public ClientClass(BluetoothDevice device1){
this.device = device1;
try {
socket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
myBluetoothAdapter.cancelDiscovery();
try {
socket.connect();
Message message = Message.obtain();
message.what = STATE_CONNECTED;
handler.sendMessage(message);
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
e.printStackTrace();
Message message = Message.obtain();
message.what = STATE_CONNECTION_FAILED;
handler.sendMessage(message);
}
}
}
private class SendReceive extends Thread {
private final BluetoothSocket bluetoothSocket;
private final InputStream inputStream;
private final OutputStream outputStream;
public SendReceive(BluetoothSocket socket) {
bluetoothSocket = socket;
InputStream tempIn = null;
OutputStream tempOut = null;
try {
tempIn = bluetoothSocket.getInputStream();
tempOut = bluetoothSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
inputStream = tempIn;
outputStream = tempOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (true) {
try {
bytes = inputStream.read(buffer);
handler.obtainMessage(STATE_MESSAGE_RECEIVED, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write(byte[] bytes) {
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
My STM code:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
switch (atoi(&Received)) {
case 0:
size = sprintf(Data, "STOP\n\r");
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_RESET);
break;
case 1:
size = sprintf(Data, "START\n\r");
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET);
break;
default:
size = sprintf(Data, "Odebrano nieznany znak: %c\n\r", Received);
break;
}
HAL_UART_Transmit_IT(&huart1, Data, size);
HAL_UART_Receive_IT(&huart1, &Received, 1);
HAL_GPIO_TogglePin(RED_LED_GPIO_Port, RED_LED_Pin);
}
I am attempting to use the MyBluetoothService class straight from the Android tutorials and call the write method from the main activity as suggested by the text. I would just like some guidance on how to pass a string from the main activity to the write method and send it to a connected Bluetooth device.
public class MyBluetoothService {
private static final String TAG = "MY_APP_DEBUG_TAG";
private Handler mHandler; // handler that gets info from Bluetooth service
// Defines several constants used when transmitting messages between the
// service and the UI.
private interface MessageConstants {
public static final int MESSAGE_READ = 0;
public static final int MESSAGE_WRITE = 1;
public static final int MESSAGE_TOAST = 2;
// ... (Add other message types here as needed.)
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private byte[] mmBuffer; // mmBuffer store for the stream
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams; using temp objects because
// member streams are final.
try {
tmpIn = socket.getInputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating input stream", e);
}
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating output stream", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
mmBuffer = new byte[1024];
int numBytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs.
while (true) {
try {
// Read from the InputStream.
numBytes = mmInStream.read(mmBuffer);
// Send the obtained bytes to the UI activity.
Message readMsg = mHandler.obtainMessage(
MessageConstants.MESSAGE_READ, numBytes, -1,
mmBuffer);
readMsg.sendToTarget();
} catch (IOException e) {
Log.d(TAG, "Input stream was disconnected", e);
break;
}
}
}
// Call this from the main activity to send data to the remote device.
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
// Share the sent message with the UI activity.
Message writtenMsg = mHandler.obtainMessage(
MessageConstants.MESSAGE_WRITE, -1, -1, mmBuffer);
writtenMsg.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Error occurred when sending data", e);
// Send a failure message back to the activity.
Message writeErrorMsg =
mHandler.obtainMessage(MessageConstants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString("toast",
"Couldn't send data to the other device");
writeErrorMsg.setData(bundle);
mHandler.sendMessage(writeErrorMsg);
}
}
// Call this method from the main activity to shut down the connection.
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the connect socket", e);
}
}
}
}
this code will help you to find all the devices in the surrounding
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class DeviceList extends AppCompatActivity {
ListView blist;
Button b;
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);
b=(Button)findViewById(R.id.button);
blist=(ListView)findViewById(R.id.listView);
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);
}
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pairedDevices();
}
});
}
private void pairedDevices()
{
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);
blist.setAdapter(adapter);
blist.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, ledControl.class);
//Change the activity.
i.putExtra(EXTRA_ADDRESS, address); //this will be received at ledControl (class) Activity
startActivity(i);
}
};
}
this code helps to send the message to the device connected
public class ledControl extends AppCompatActivity {
Button btnOn, btnOff, btnDis;
TextView lumn;
String address = null;
private ProgressDialog progress;
BluetoothAdapter myBluetooth = null;
BluetoothSocket btSocket = null;
private boolean isBtConnected = false;
//SPP UUID. Look for it
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent newint = getIntent();
address = newint.getStringExtra(DeviceList.EXTRA_ADDRESS); //receive the address of the bluetooth device
//view of the ledControl
setContentView(R.layout.activity_led_control);
//call the widgtes
btnOn = (Button) findViewById(R.id.button2);
btnOff = (Button) findViewById(R.id.button3);
btnDis = (Button) findViewById(R.id.button4);
lumn = (TextView) findViewById(R.id.lumn);
new ConnectBT().execute(); //Call the class to connect
//commands to be sent to bluetooth
btnOn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
turnOnLed();
//method to turn on
}
});
btnOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
turnOffLed(); //method to turn off
}
});
btnDis.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Disconnect(); //close connection
}
});
}
private void Disconnect()
{
if (btSocket!=null) //If the btSocket is busy
{
try
{
btSocket.close(); //close connection
}
catch (IOException e)
{ msg("Error");}
}
finish(); //return to the first layout
}
private void turnOffLed()
{
if (btSocket!=null)
{
try
{
btSocket.getOutputStream().write("F".toString().getBytes());
//Log.e("message",)
}
catch (IOException e)
{
msg("Error");
}
}
}
private void turnOnLed()
{
if (btSocket!=null)
{
try
{
//Toast.makeText(ledControl.this,"oning",Toast.LENGTH_SHORT).show();
btSocket.getOutputStream().write("O".toString().getBytes());
Log.e("message",btSocket.toString());
}
catch (IOException e)
{
msg("Error");
}
}
}
// fast way to call Toast
private void msg(String s)
{
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
}
private class ConnectBT extends AsyncTask<Void, Void, Void> // UI thread
{
private boolean ConnectSuccess = true; //if it's here, it's almost connected
#Override
protected void onPreExecute()
{
progress = ProgressDialog.show(ledControl.this, "Connecting...", "Please wait!!!"); //show a progress dialog
}
#Override
protected Void doInBackground(Void... devices) //while the progress dialog is shown, the connection is done in background
{
try
{
if (btSocket == null || !isBtConnected)
{
myBluetooth = BluetoothAdapter.getDefaultAdapter();//get the mobile bluetooth device
BluetoothDevice dispositivo = myBluetooth.getRemoteDevice(address);//connects to the device's address and checks if it's available
btSocket = dispositivo.createInsecureRfcommSocketToServiceRecord(myUUID);//create a RFCOMM (SPP) connection
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
btSocket.connect();//start connection
}
}
catch (IOException e)
{
ConnectSuccess = false;//if the try failed, you can check the exception here
}
return null;
}
#Override
protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
{
super.onPostExecute(result);
if (!ConnectSuccess)
{
msg("Connection Failed. Is it a SPP Bluetooth? Try again.");
finish();
}
else
{
msg("Connected.");
isBtConnected = true;
}
progress.dismiss();
}
}
}
I'm learning how work handler in Android. I did Android server and socket class. I want send some message (i.e. "New Connect") from socket to mainactivity, when somebody connect to server. I can't figure out how to pass from socket to mainactivity. (More in comments)
HttpServerActivity.java
public class HttpServerActivity extends Activity implements OnClickListener{
private SocketServer s;
private static final int READ_EXTERNAL_STORAGE = 1;
Button btn1, btn2;
// There I'm trying to send message to button, when somebody connected
Handler h = new Handler(){
#Override
public void handleMessage(Message msg){
super.handleMessage(msg);
String text = (String)msg.obj;
btn1.setText(text);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_http_server);
Button btn1 = (Button)findViewById(R.id.button1);
Button btn2 = (Button)findViewById(R.id.button2);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.http_server, menu);
return true;
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.button1) {
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE);
} else {
// I dont know figure out in this place
s = new SocketServer(h);
s.start();
}
}
if (v.getId() == R.id.button2) {
s.close();
try {
s.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case READ_EXTERNAL_STORAGE:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// I dont know figure out in this place
s = new SocketServer(h);
s.start();
}
break;
default:
break;
}
}
}
SocketServer.java
public class SocketServer extends Thread {
private final Handler mHandler;
public SocketServer(Handler handler)
{
mHandler = handler;
}
ServerSocket serverSocket;
public final int port = 12345;
boolean bRunning;
public void close() {
try {
serverSocket.close();
} catch (IOException e) {
Log.d("SERVER", "Error, probably interrupted in accept(), see log");
e.printStackTrace();
}
bRunning = false;
}
public Handler mHandler;
public void run() {
try {
Log.d("SERVER", "Creating Socket");
serverSocket = new ServerSocket(port);
bRunning = true;
while (bRunning) {
Log.d("SERVER", "Socket Waiting for connection");
Socket s = serverSocket.accept();
Log.d("SERVER", "Socket Accepted");
// trying to send some message
String[] messageString = new String[1];
Message message = Message.obtain();
messageString[0]="OK";
message.obj = messageString;
mHandler.sendMessage(message);
OutputStream o = s.getOutputStream();
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(o));
out.write("HTTP/1.0 200 OK\n" +
"Date: Fri, 31 Dec 1999 23:59:59 GMT\n" +
"Content-Type: text/html\n" +
"Content-Length: 1354\n" +
"\n" +
"<html>\n" +
"<body>\n" +
"<h1> Connected </h1>\n" +
"</body>\n" +
"</html>");
out.flush();
while (!((tmp = in.readLine()).isEmpty()))
{
Log.d("Header", tmp);
if (tmp.startsWith("GET"))
{
getRequest = tmp;
}
}
s.close();
Log.d("SERVER", "Socket Closed");
}
}
catch (IOException e) {
if (serverSocket != null && serverSocket.isClosed())
Log.d("SERVER", "Normal exit");
else {
Log.d("SERVER", "Error");
e.printStackTrace();
}
}
finally {
serverSocket = null;
bRunning = false;
}
}
}
This is a sample of a bigger project I was involved a few years ago. You will not be able to run as it is, but I think you can see how the communication between a Service and an Activity works. Feel free to ask if anything is not clear
Service
public class BluetoothService {
private final Handler mHandler;
public BluetoothService(Context context, Handler handler) {
mHandler = handler;
}
public synchronized void Connecting(...) {
...
Message MenssageToActivity = mHandler.obtainMessage(Cliente_Bluetooth.MESSAGE_HELLO);
Bundle bundle = new Bundle();
bundle.putString(BluetoothClient.DEVICE_NAME, " Gorkatan");
MensajeParaActivity.setData(bundle);
mHandler.sendMessage(MensajeParaActivity);
...
}
}
Activity
public class BluetoothClient{
public static final int MESSAGE_HELLO = 1;
public static final int MESSAGE_BYE = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
mBluetoothService = new BluetoothService(this, mHandler);
}
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_HELLO:
String mName = null;
mName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(), "Hello "+ mName, Toast.LENGTH_SHORT).show();
break;
case MESSAGE_BYE:
System.out.println("Bye!")
break;
}
Here it is the whole project (which has got comments and variable names in Spanish):
https://github.com/ignacio-alorre/PDF-Dispenser/tree/master/Client/Cliente_Bluetooth/src/com/cliente_bluetooth
If you plan on sending data from a thread to your handler then use obtainMessage to create a message object.
You must also use the same instance of the handler to handleMessage and sendMessage.
Here you will find a great resource explaining how to use Handler:
https://www.youtube.com/watch?v=LJ_pUlWzGsc
I'm in need to move a Bluetooth activity (BTHandler) that handles all my Bluetooth connection into a Service so that I can use multiple activities without loosing the connection. How would I go about doing that?
Thanks
BTHandler
public class BTHandler {
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
final ArrayList<String> devices = new ArrayList();
private final Handler mHandler;
private BluetoothAdapter mAdapter;
private BluetoothDevice device;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private BluetoothSocket socket;
private String status;
private int mState;
private boolean connectionStatus = false;
public BTHandler(Context context, Handler handler) { // Konstruktor
mAdapter = BluetoothAdapter.getDefaultAdapter();
mHandler = handler;
}
public void write(String s) {
mConnectedThread.sendRawCommand(s);
Log.v("write", "write");
}
/*
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
*/
public void connect(String deviceAddress) {
mConnectThread = new ConnectThread(deviceAddress);
mConnectThread.start();
}
private void guiHandler(int what, int arg1, String obj) {
Message msg = mHandler.obtainMessage();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.sendToTarget();
}
private class ConnectThread extends Thread {
BluetoothSocket tmp = null;
private BluetoothSocket mmSocket;
public ConnectThread(String deviceAddress) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
device = mAdapter.getRemoteDevice(deviceAddress);
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
tmp = device.createRfcommSocketToServiceRecord(uuid);
//socket.connect();
//Log.v("connect", "connect");
} catch (IOException e) {
//e.printStackTrace();
//Log.v("exception", "e");
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mAdapter.cancelDiscovery();
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes;
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.v("connect", "connect");
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
Log.v("close", "close");
} catch (IOException closeException) {
}
guiHandler(Constants.TOAST, Constants.SHORT, "Connection Failed");
return;
}
guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private ObdMultiCommand multiCommand;
public ConnectedThread(BluetoothSocket socket) {
connectionStatus = true;
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
try {
//RPMCommand engineRpmCommand = new RPMCommand();
//SpeedCommand speedCommand = new SpeedCommand();
ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
while (!Thread.currentThread().isInterrupted()) {
//engineRpmCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
//speedCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
voltageCommand.run(socket.getInputStream(), socket.getOutputStream());
// TODO handle commands result
//Log.d("Log", "RPM: " + engineRpmCommand.getFormattedResult());
//Log.d("Log", "Speed: " + speedCommand.getFormattedResult());
Log.v("Log", "Voltage: " + voltageCommand.getFormattedResult());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
OBDcmds();
// Keep listening to the InputStream until an exception occurs
while (connectionStatus) {
sendMultiCommand();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// CALL this to MainActivity
public void sendRawCommand(String command) {
try {
new OdbRawCommand(command);
} catch (Exception e) {
Log.v("sendRawCommand", "e");
}
}
private void OBDcmds() { // execute commands
try {
new EchoOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new LineFeedOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new TimeoutCommand(100).run(socket.getInputStream(), socket.getOutputStream());
new SelectProtocolCommand(ObdProtocols.AUTO).run(socket.getInputStream(), socket.getOutputStream()); //ISO_15765_4_CAN
} catch (Exception e) {
Log.v("OBDcmds", "e");
// handle errors
}
}
/*
// Call this from the main activity to send data to the remote device
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
*/
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
public void sendMultiCommand() {
try {
// RUN some code here
} catch (Exception e) {
}
}
}
}
MyService
public class MyService extends Service {
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "The new Service was Created", Toast.LENGTH_LONG).show();
}
#Override
public void onStart(Intent intent, int startId) {
// For time consuming an long tasks you can launch a new thread here...
// Do your Bluetooth Work Here
Toast.makeText(this, " Service Started", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
You need to create your variables of the threads and stuff inside the Service.
I want to send real time accelerometer data from my android phone to my laptop, so that I can do some further analysis using that data, but I am facing some challenges in doing so...I am not able to persist connection at the android side and getting
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
03-20 23:30:19.881 10050-13445/com.accel.bluetoothconnect W/System.err: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
03-20 23:30:19.881 10050-13445/com.accel.bluetoothconnect W/System.err: at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:1016)
03-20 23:30:19.881 10050-13445/com.accel.bluetoothconnect W/System.err: at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:973)
03-20 23:30:19.881 10050-13445/com.accel.bluetoothconnect W/System.err: at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:662)
03-20 23:30:19.881 10050-13445/com.accel.bluetoothconnect W/System.err: at com.accel.bluetoothconnect.MainActivity$ConnectingThread.run(MainActivity.java:446)
03-20 23:30:19.951 10050-10050/com.accel.bluetoothconnect W/Accel Value(X)->: 0.0
03-20 23:30:19.951 10050-10050/com.accel.bluetoothconnect W/Accel Value(Y)->: 0.0
03-20 23:30:19.951 10050-10050/com.accel.bluetoothconnect W/Accel Value(Z)->: 10.289082
03-20 23:30:20.151 10050-10050/com.accel.bluetoothconnect W/Accel Value(X)->: 0.0
03-20 23:30:20.151 10050-10050/com.accel.bluetoothconnect W/Accel Value(Y)->: 0.0
03-20 23:30:20.151 10050-10050/com.accel.bluetoothconnect W/Accel Value(Z)->: 10.271125
03-20 23:30:20.351 10050-10050/com.accel.bluetoothconnect W/Accel Value(X)->: 0.0
03-20 23:30:20.351 10050-10050/com.accel.bluetoothconnect W/Accel Value(Y)->: 0.0
03-20 23:30:20.351 10050-10050/com.accel.bluetoothconnect W/Accel Value(Z)->: 10.289082
whereas, on the laptop side where bluecove code is running, it is able to connect and the thread waits for the data.
BlueCove version 2.1.1-SNAPSHOT on winsock
0000110100001000800000805f9b34fb
waiting for connection...
waiting for connection...
waiting for input
finish process
Codes that I am using,
For Android-
public class MainActivity extends Activity implements SensorEventListener {
private final static UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
private static final String TAG="BluetoothConnector";
private static final int REQUEST_ENABLE_BT = 1;
private static final int DISCOVERABLE_BT_REQUEST_CODE = 2;
private static final int DISCOVERABLE_DURATION = 300;
public static final int EXIT_CMD = -1;
int conn_flag = 0;
private Button onBtn;
private Button offBtn;
private Button listBtn;
private Button findBtn;
private TextView text;
private BluetoothAdapter myBluetoothAdapter;
private Set<BluetoothDevice> pairedDevices;
private ListView myListView;
private ArrayAdapter<String> BTArrayAdapter;
BluetoothDevice bluetoothDevice;
private float lastX, lastY, lastZ;
private SensorManager sensorManager;
private Sensor accelerometer;
private float deltaXMax = 0;
private float deltaYMax = 0;
private float deltaZMax = 0;
private float deltaX = 0;
private float deltaY = 0;
private float deltaZ = 0;
private float vibrateThreshold = 0;
private TextView currentX, currentY, currentZ, maxX, maxY, maxZ;
public Vibrator v;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// take an instance of BluetoothAdapter - Bluetooth radio
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(myBluetoothAdapter == null) {
onBtn.setEnabled(false);
offBtn.setEnabled(false);
listBtn.setEnabled(false);
findBtn.setEnabled(false);
text.setText("Status: not supported");
Toast.makeText(getApplicationContext(),"Your device does not support Bluetooth",
Toast.LENGTH_LONG).show();
} else {
text = (TextView) findViewById(R.id.text);
onBtn = (Button)findViewById(R.id.turnOn);
onBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
on(v);
}
});
offBtn = (Button)findViewById(R.id.turnOff);
offBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
off(v);
}
});
listBtn = (Button)findViewById(R.id.paired);
listBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
list(v);
}
});
findBtn = (Button)findViewById(R.id.search);
findBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
find(v);
}
});
myListView = (ListView)findViewById(R.id.listView1);
// create the arrayAdapter that contains the BTDevices, and set it to the ListView
BTArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
myListView.setAdapter(BTArrayAdapter);
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// ListView Clicked item value
String itemValue = (String) myListView.getItemAtPosition(position);
String MAC = itemValue.substring(itemValue.length() - 17);
bluetoothDevice = myBluetoothAdapter.getRemoteDevice(MAC);
// Initiate a connection request in a separate thread
ConnectingThread t = new ConnectingThread(bluetoothDevice);
t.start();
}
});
}
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
// success! we have an accelerometer
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
vibrateThreshold = accelerometer.getMaximumRange() / 2;
} else {
// fai! we dont have an accelerometer!
}
//initialize vibration
v = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);
}
public void on(View view){
if (!myBluetoothAdapter.isEnabled()) {
Intent turnOnIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOnIntent, REQUEST_ENABLE_BT);
Toast.makeText(getApplicationContext(),"Bluetooth turned on" ,
Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(),"Bluetooth is already on",
Toast.LENGTH_LONG).show();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if(requestCode == REQUEST_ENABLE_BT){
if(myBluetoothAdapter.isEnabled()) {
text.setText("Status: Enabled");
Toast.makeText(getApplicationContext(), "Ha! Bluetooth is now enabled." +
"\n" + "Scanning for remote Bluetooth devices...",
Toast.LENGTH_SHORT).show();
// To discover remote Bluetooth devices
discoverDevices();
// Make local device discoverable by other devices
makeDiscoverable();
// Start a thread to create a server socket to listen
// for connection request
ListeningThread t = new ListeningThread();
t.start();
} else {
text.setText("Status: Disabled");
}
}else if (requestCode == DISCOVERABLE_BT_REQUEST_CODE){
if (resultCode == DISCOVERABLE_DURATION){
Toast.makeText(getApplicationContext(), "Your device is now discoverable by other devices for " +
DISCOVERABLE_DURATION + " seconds",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Fail to enable discoverability on your device.",
Toast.LENGTH_SHORT).show();
}
}
}
protected void discoverDevices(){
// To scan for remote Bluetooth devices
if (myBluetoothAdapter.startDiscovery()) {
Toast.makeText(getApplicationContext(), "Discovering other bluetooth devices...",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Discovery failed to start.",
Toast.LENGTH_SHORT).show();
}
}
protected void makeDiscoverable(){
// Make local device discoverable
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVERABLE_DURATION);
startActivityForResult(discoverableIntent, DISCOVERABLE_BT_REQUEST_CODE);
}
public void list(View view){
// get paired devices
pairedDevices = myBluetoothAdapter.getBondedDevices();
// put it's one to the adapter
for(BluetoothDevice device : pairedDevices)
BTArrayAdapter.add(device.getName()+ "\n" + device.getAddress());
Toast.makeText(getApplicationContext(),"Show Paired Devices",
Toast.LENGTH_SHORT).show();
}
final BroadcastReceiver bReceiver = new BroadcastReceiver() {
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);
// add the name and the MAC address of the object to the arrayAdapter
BTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
BTArrayAdapter.notifyDataSetChanged();
}
else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
conn_flag=1;
}
}
};
public void find(View view) {
if (myBluetoothAdapter.isDiscovering()) {
// the button is pressed when it discovers, so cancel the discovery
myBluetoothAdapter.cancelDiscovery();
}
else {
BTArrayAdapter.clear();
myBluetoothAdapter.startDiscovery();
registerReceiver(bReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
}
}
public void off(View view){
myBluetoothAdapter.disable();
text.setText("Status: Disconnected");
Toast.makeText(getApplicationContext(),"Bluetooth turned off",
Toast.LENGTH_LONG).show();
}
#Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
// Register the BroadcastReceiver for ACTION_FOUND
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(bReceiver, filter);
}
#Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
this.unregisterReceiver(bReceiver);
}
#Override
public void onSensorChanged(SensorEvent event) {
Log.w("Accel Value(X)->", String.valueOf(deltaX));
Log.w("Accel Value(Y)->", String.valueOf(deltaY));
Log.w("Accel Value(Z)->", String.valueOf(deltaZ));
if(conn_flag == 1) {
Log.w("Data Transfer", "Finally transferring data");
ConnectingThread ct = new ConnectingThread(bluetoothDevice);
ct.write((int) deltaX);
}
// get the change of the x,y,z values of the accelerometer
deltaX = Math.abs(lastX - event.values[0]);
deltaY = Math.abs(lastY - event.values[1]);
deltaZ = Math.abs(lastZ - event.values[2]);
// if the change is below 2, it is just plain noise
if (deltaX < 2)
deltaX = 0;
if (deltaY < 2)
deltaY = 0;
if ((deltaZ > vibrateThreshold) || (deltaY > vibrateThreshold) || (deltaZ > vibrateThreshold)) {
v.vibrate(50);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
private class ListeningThread extends Thread {
private final BluetoothServerSocket bluetoothServerSocket;
public ListeningThread() {
BluetoothServerSocket temp = null;
try {
temp = myBluetoothAdapter.listenUsingRfcommWithServiceRecord(getString(R.string.app_name), uuid);
} catch (IOException e) {
e.printStackTrace();
}
bluetoothServerSocket = temp;
}
public void run() {
BluetoothSocket bluetoothSocket;
// This will block while listening until a BluetoothSocket is returned
// or an exception occurs
while (true) {
try {
bluetoothSocket = bluetoothServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection is accepted
if (bluetoothSocket != null) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "A connection has been accepted.",
Toast.LENGTH_SHORT).show();
}
});
// Code to manage the connection in a separate thread
/*
manageBluetoothConnection(bluetoothSocket);
*/
try {
bluetoothServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
// Cancel the listening socket and terminate the thread
public void cancel() {
try {
bluetoothServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class ConnectingThread extends Thread {
private BluetoothSocket bluetoothSocket;
private final BluetoothDevice bluetoothDevice;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectingThread(BluetoothDevice device) {
BluetoothSocket temp = null;
bluetoothDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
temp = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
e.printStackTrace();
}
bluetoothSocket = temp;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = bluetoothSocket.getInputStream();
tmpOut = bluetoothSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
myBluetoothAdapter.cancelDiscovery();
try {
// This will block until it succeeds in connecting to the device
// through the bluetoothSocket or throws an exception
bluetoothSocket.connect();
} catch (IOException connectException) {
connectException.printStackTrace();
try {
Log.e("","trying fallback...");
bluetoothSocket =(BluetoothSocket) bluetoothDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class}).invoke(bluetoothDevice,1);
bluetoothSocket.connect();
Log.e("","Connected");
}
catch (Exception e2) {
Log.e("", "Couldn't establish Bluetooth connection!");
}
}
}
public void write(int out) {
try {
mmOutStream.write(out);
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
// Cancel an open connection and terminate the thread
public void cancel() {
try {
mmOutStream.write(EXIT_CMD);
bluetoothSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}}
Android manifest-
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.VIBRATE" />
For fallback code, I referred to- getBluetoothService() called with no BluetoothManagerCallback for Android Nexus 5
and laptop side (bluecove)-
WaitThread.java-
public class WaitThread implements Runnable{
/** Constructor */
public WaitThread() {
}
#Override
public void run() {
waitForConnection();
}
/** Waiting for connection from devices */
private void waitForConnection() {
// retrieve the local Bluetooth device object
LocalDevice local = null;
StreamConnectionNotifier notifier;
StreamConnection connection = null;
// setup the server to listen for connection
try {
local = LocalDevice.getLocalDevice();
local.setDiscoverable(DiscoveryAgent.GIAC);
//UUID uuid = new UUID("04c6093b00001000800000805f9b34fb", false);
UUID uuid = new UUID("0000110100001000800000805f9b34fb", false);
System.out.println(uuid.toString());
String url = "btspp://localhost:" + uuid.toString() + ";name=RemoteBluetooth";
notifier = (StreamConnectionNotifier)Connector.open(url);
} catch (BluetoothStateException e) {
System.out.println("Bluetooth is not turned on.");
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
// waiting for connection
while(true) {
try {
System.out.println("waiting for connection...");
connection = notifier.acceptAndOpen();
Thread processThread = new Thread(new ProcessConnectionThread(connection));
processThread.start();
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}
}
and ProcessConnectionThread.java-
public class ProcessConnectionThread implements Runnable{
private StreamConnection mConnection;
// Constant that indicate command from devices
private static final int EXIT_CMD = -1;
private static final int KEY_RIGHT = 1;
private static final int KEY_LEFT = 2;
public ProcessConnectionThread(StreamConnection connection)
{
mConnection = connection;
}
#Override
public void run() {
try {
// prepare to receive data
InputStream inputStream = mConnection.openInputStream();
System.out.println("waiting for input");
while (true) {
int command = inputStream.read();
if (command == EXIT_CMD)
{
System.out.println("finish process");
break;
}
processCommand(command);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Process the command from client
* #param command the command code
*/
private void processCommand(int command) {
try {
System.out.println("Value sent is: "+command);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Right now i'm just trying to pass x axis data that too in int (just for the moment). Please help me in getting it resolved. Also, this is my first android app and i have tried to connect pieces from various websites, so requesting everyone to please go easy with me.