I have an simple sender/receiver android app based on bluetooth. Connection between two phone is succesfully created. But data is not sending and receiving.
Code what I tried :
public class MainActivity extends Activity
{
TextView myLabel;
EditText myTextbox;
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
InputStream mmInputStream;
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
volatile boolean stopWorker;
void findBT()
{
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null)
{
myLabel.setText("No bluetooth adapter available");
}
if(!mBluetoothAdapter.isEnabled())
{
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if(pairedDevices.size() > 0)
{
for(BluetoothDevice device : pairedDevices)
{
String deviceName = device.getName();
deviceName=deviceName.replaceAll("[^A-Za-z]+", "");
//String deviceHardwareAddress = device.getAddress(); // MAC address
Log.i("## name : ",deviceName+" ");
if(deviceName.equals("GalaxyTabAwithSPen")) {
mmDevice = device;
break;
}
}
}
// tel GalaxyTabAwithSPen
// tablet GhhBbbGalaxyS
}
void openBT()
{
if(mmDevice==null)
Log.i("test","notnull");
ParcelUuid list[] = mmDevice.getUuids();
for(ParcelUuid x: list){
System.out.println(x.toString());
}
Log.i("size :"+list.length," "+list[1].toString());
UUID uuid = UUID.fromString(list[1].toString()); //Standard SerialPortService ID
//UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
beginListenForData();
myLabel.setText("Bluetooth Opened");
}
catch (Exception ex){
Log.i("IO ex : ", ex.getMessage());
}
}
void beginListenForData()
{
final Handler handler = new Handler();
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !stopWorker)
{
try
{
int bytesAvailable = mmInputStream.available();
if(bytesAvailable > 0)
{
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++)
{
byte b = packetBytes[i];
if(b == delimiter)
{
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable()
{
public void run()
{
myLabel.setText(data);
}
});
}
else
{
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex)
{
Log.i("IO ex read " ,ex.getMessage());
stopWorker = true;
}
}
}
});
workerThread.start();
}
void sendData() throws IOException
{
String msg = myTextbox.getText().toString();
msg += "\n";
mmOutputStream.write(msg.getBytes());
myLabel.setText("Data Sent");
}
When I click open both tablet and mobile phone, myLabel text changed to "Blueetooth Opened" succesfully.
But when I try to send text to phone from tablet or to table from phone, nothing sended. Data listener is working. mmInputStream.available() always returns 0.
Some log details :
D/BluetoothUtils: isSocketAllowedBySecurityPolicy start : device null
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
D/BluetoothSocket: connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[49]}
Related
In the below code which is for bluetooth messaging with arduino i am trying to change color on some static strings.
1.On the start button listener i have a message"Connection opened" which i am changing color using the xml file and creating there a string with specific color. This method works only there.
2. i tried another method with spannable string on the send button listener but is not working at all the message comes in black.
what i want to to do is that when i send a message on my textview i see the "send data: "+ string(msg i send) and i want this send data to be red for examle and the same for the receive one.
What i tried untill now is on the code.If there is any idea to try i will be grateful.
public class MainActivity extends Activity {
private final UUID PORT_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");//Serial Port Service ID
private BluetoothDevice device;
private BluetoothSocket socket;
private OutputStream outputStream;
private InputStream inputStream;
Button startButton, sendButton,clearButton,stopButton;
TextView textView;
EditText editText;
boolean deviceConnected=false;
//Thread thread;
byte[] buffer;
//int bufferPosition;
boolean stopThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startButton = findViewById(R.id.buttonStart);
sendButton = findViewById(R.id.buttonSend);
clearButton = findViewById(R.id.buttonClear);
stopButton = findViewById(R.id.buttonStop);
editText = findViewById(R.id.editText);
textView = findViewById(R.id.textView);
textView.setMovementMethod(new ScrollingMovementMethod());
setUiEnabled(false);
startButton.setOnClickListener(v -> {
if(BTinit())
{
if(BTconnect())
{
setUiEnabled(true);
deviceConnected=true;
beginListenForData();
//textView.append("Connection Opened!");
String greenString = getResources().getString(R.string.Connection_Opened);
textView.append(Html.fromHtml(greenString));
}
}
});
sendButton.setOnClickListener(v -> {
String t = "Send Data: ";
SpannableString spannableString = new SpannableString(t);
ForegroundColorSpan green = new ForegroundColorSpan(getResources().getColor(R.color.private_green));
spannableString.setSpan(green, 0, 9, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
String string = editText.getText().toString();
String str = string.concat("\n");
try {
outputStream.write(str.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
textView.append(spannableString + str);
});
stopButton.setOnClickListener(v -> {
try {
stopThread = true;
outputStream.close();
inputStream.close();
socket.close();
setUiEnabled(false);
deviceConnected=false;
textView.append("Connection Closed!");
}catch (IOException e){
e.printStackTrace();
}
});
clearButton.setOnClickListener(v -> textView.setText(""));
}
public void setUiEnabled(boolean bool)
{
startButton.setEnabled(!bool);
sendButton.setEnabled(bool);
stopButton.setEnabled(bool);
textView.setEnabled(bool);
}
public boolean BTinit()
{
boolean found=false;
BluetoothAdapter bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(getApplicationContext(),"Device doesnt Support Bluetooth",Toast.LENGTH_SHORT).show();
}
if(bluetoothAdapter !=null)
{
Intent enableAdapter = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableAdapter, 0);
}
assert bluetoothAdapter != null;
Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
if(bondedDevices.isEmpty())
{
Toast.makeText(getApplicationContext(),"Please Pair the Device first",Toast.LENGTH_SHORT).show();
}
else
{
for (BluetoothDevice iterator : bondedDevices)
{
//private final String DEVICE_NAME="ArduinoBT";
String DEVICE_ADDRESS = "98:DA:C0:00:2C:E2";
if(iterator.getAddress().equals(DEVICE_ADDRESS))
{
device=iterator;
found=true;
break;
}
}
}
return found;
}
public boolean BTconnect()
{
boolean connected=true;
try {
socket = device.createRfcommSocketToServiceRecord(PORT_UUID);
socket.connect();
} catch (IOException e) {
e.printStackTrace();
connected=false;
}
if(connected)
{
try {
outputStream=socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
inputStream=socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
return connected;
}
void beginListenForData()
{
final Handler handler = new Handler();
stopThread = false;
buffer = new byte[1024];
Thread thread = new Thread(() -> {
while(!Thread.currentThread().isInterrupted() && !stopThread)
{
try
{
int byteCount = inputStream.available();
if(byteCount > 0)
{
byte[] rawBytes = new byte[byteCount];
inputStream.read(rawBytes);
final String string=new String(rawBytes, StandardCharsets.UTF_8);
handler.post(() -> textView.append("Receive data: " + string));
}
}
catch (IOException ex)
{
stopThread = true;
}
}
});
thread.start();
}
}
Try like this;
Spannable text = new SpannableString("Send Data:");
text.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.private_green)), 0, 9, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
I'm trying to write a code I can write all the results values from accelerometer sensor into a .txt file. I can't write all the data in somehow. I think there is a problem in my loop. It is just reading about 10 to 15 samples.
How can I write all the values of the sensor into that file until I toggle off the button to stop? here is the code I wrote.
Thanks in advance!
public class MainActivity extends Activity implements SensorEventListener {
public SensorManager sm;
Sensor accelermeter;
private static final String DEBUG = "LogAccelermeter";
ToggleButton OnStore;
Button OffStore;
Button btnOn, btnOff;
TextView txtArduino, txtString, txtStringLength, sensorView0, sensorView1, sensorView2, sensorView3;
Handler bluetoothIn;
final int handlerState = 0; //used to identify handler message
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder recDataString = new StringBuilder();
private ConnectedThread mConnectedThread;
// SPP UUID service - this should work for most devices
private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
TextView sensorText;
// String for MAC address
private static String address;
private GestureDetectorCompat mDetector;
FileOutputStream fileOutputStream;
double TotalAccelerate;
ArrayList<Double> list;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = new ArrayList<Double>();
//Link the buttons and textViews to respective views
btnOn = (Button) findViewById(R.id.buttonOn);
btnOff = (Button) findViewById(R.id.buttonOff);
txtString = (TextView) findViewById(R.id.txtString);
txtStringLength = (TextView) findViewById(R.id.testView1);
sensorView0 = (TextView) findViewById(R.id.sensorView0);
sensorView1 = (TextView) findViewById(R.id.sensorView1);
sensorView2 = (TextView) findViewById(R.id.sensorView2);
sensorView3 = (TextView) findViewById(R.id.sensorView3);
//for Accelermeter
sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensorText = (TextView) findViewById(R.id.sensor);
accelermeter = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sm.registerListener(this, accelermeter, SensorManager.SENSOR_DELAY_NORMAL);
mDetector = new GestureDetectorCompat(this, new MyGestureListener());
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
File Root = Environment.getExternalStorageDirectory();
File dir = new File(Root.getAbsolutePath() + "/MyApp");
if (!dir.exists()) {
dir.mkdir();
}
File file = new File(dir, "MyMessage.txt");
try {
fileOutputStream = new FileOutputStream(file, true);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(), "SDcard not found", Toast.LENGTH_LONG).show();
}
OnStore = (ToggleButton) findViewById(R.id.onStore);
OnStore.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if (OnStore.isChecked()){
try {
for(double TotalAccelerate : list){
// System.out.println("final"+ TotalAccelerate);
String space = "\n";
byte[] convert = space.getBytes();
fileOutputStream.write(convert);
String finalData;
finalData = String.valueOf(TotalAccelerate);
fileOutputStream.write(finalData.getBytes());
Log.i(DEBUG, "ans: " + finalData);
}
// fileOutputStream.close();
Toast.makeText(getApplicationContext(), "Message saving", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}if (!OnStore.isChecked()){
try {
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fileOutputStream.close();
list.clear();
Collections.synchronizedList(list);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),"Message Stopped.",Toast.LENGTH_LONG).show();
}
}
});
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) { //if message is what we want
String readMessage = (String) msg.obj; // msg.arg1 = bytes from connect thread
recDataString.append(readMessage); //keep appending to string until ~
int endOfLineIndex = recDataString.indexOf("~"); // determine the end-of-line
if (endOfLineIndex > 0) { // make sure there data before ~
String dataInPrint = recDataString.substring(0, endOfLineIndex); // extract string
txtString.setText("Data Received = " + dataInPrint);
int dataLength = dataInPrint.length(); //get length of data received
txtStringLength.setText("String Length = " + String.valueOf(dataLength));
if (recDataString.charAt(0) == '#') //if it starts with # we know it is what we are looking for
{
String sensor0 = recDataString.substring(1, 5); //get sensor value from string between indices 1-5
String sensor1 = recDataString.substring(6, 10); //same again...
String sensor2 = recDataString.substring(11, 15);
String sensor3 = recDataString.substring(16, 20);
sensorView0.setText(" Sensor 0 Voltage = " + sensor0 + "V"); //update the textviews with sensor values
sensorView1.setText(" Sensor 1 Voltage = " + sensor1 + "V");
sensorView2.setText(" Sensor 2 Voltage = " + sensor2 + "V");
sensorView3.setText(" Sensor 3 Voltage = " + sensor3 + "V");
}
recDataString.delete(0, recDataString.length()); //clear all string data
// strIncom =" ";
dataInPrint = " ";
}
}
}
};
btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
checkBTState();
// Set up onClick listeners for buttons to send 1 or 0 to turn on/off LED
btnOff.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("0"); // Send "0" via Bluetooth
Toast.makeText(getBaseContext(), "Turn off LED", Toast.LENGTH_SHORT).show();
}
});
btnOn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("1"); // Send "1" via Bluetooth
Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show();
}
});
}//end OnCreate Method
#Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
}
#Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
double xx = event.values[0];
double yy = event.values[1];
double zz = event.values[2];
TotalAccelerate = Math.round(Math.sqrt(Math.pow(xx, 2)
+ Math.pow(yy, 2)
+ Math.pow(zz, 2)));
Log.i(DEBUG, "Accelerometer = " + TotalAccelerate);
list.add(TotalAccelerate);
findPeaks(list);
sensorText.setText("Total: " + TotalAccelerate);
Log.i(DEBUG, "list values " + list);
}
//Find peak values.
public static ArrayList<Double> findPeaks(List<Double> points) {
ArrayList<Double> peaks = new ArrayList<Double>();
if (points == null || points.size() < 1)
return peaks;
Double x1_n_ref = 0.0;
int alpha = 0; //0=down, 1=up.
int size = points.size();// -1)/100;
for (int i = 0; i < size; i += 5) {
Double IndexValues = points.get(i);
if (IndexValues > 9) {
Double delta = (x1_n_ref - IndexValues);
if (delta < 0) {
x1_n_ref = IndexValues;
alpha = 1;
} else if (alpha == 1 && delta > 0) {
peaks.add(x1_n_ref);
alpha = 0;
}
} else if (alpha == 0) {
x1_n_ref = IndexValues;
}
}
return peaks;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
this.mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
private static final String DEBUG_TAG = "Gestures";
#Override
public boolean onDown(MotionEvent event) {
Log.d(DEBUG_TAG, "onDown: " + event.toString());
Toast.makeText(getApplication(), "OnDown Touch Occur", Toast.LENGTH_LONG).show();
if (event.getX() > 0) {
mConnectedThread.write("1");
}
return true;
}
#Override
public void onLongPress(MotionEvent event) {
Log.d(DEBUG_TAG, "onLongPress: " + event.toString());
mConnectedThread.write("0");
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
//creates secure outgoing connecetion with BT device using UUID
}
#Override
public void onResume() {
super.onResume();
//Get MAC address from DeviceListActivity via intent
Intent intent = getIntent();
//Get the MAC address from the DeviceListActivty via EXTRA
address = intent.getStringExtra(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
//create device and set the MAC address
BluetoothDevice device = btAdapter.getRemoteDevice(address);
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_LONG).show();
}
// Establish the Bluetooth socket connection.
try {
btSocket.connect();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
//insert code to deal with this
}
}
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
//I send a character when resuming.beginning transmission to check device is connected
//If it is not an exception will be thrown in the write method and finish() will be called
mConnectedThread.write("x");
}
#Override
public void onPause() {
super.onPause();
try {
//Don't leave Bluetooth sockets open when leaving activity
btSocket.close();
} catch (IOException e2) {
//insert code to deal with this
}
}
//Checks that the Android device Bluetooth is available and prompts to be turned on if off
private void checkBTState() {
if (btAdapter == null) {
Toast.makeText(getBaseContext(), "Device does not support bluetooth", Toast.LENGTH_LONG).show();
} else {
if (btAdapter.isEnabled()) {
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
//create new class for connect thread
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
//creation of the connect thread
public ConnectedThread(BluetoothSocket socket) {
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
//Create I/O streams for connection
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[256];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInStream.read(buffer); //read bytes from input buffer
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
//write method
public void write(String input) {
byte[] msgBuffer = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(msgBuffer); //write bytes over BT connection via outstream
} catch (IOException e) {
//if you cannot write, close the application
Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
Could you try this for the toggle button onClick callback? It should write all the data when it's unchecked.
OnStore.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if (OnStore.isChecked()){
// should do nothing
} else if (!OnStore.isChecked()){
try {
for(double TotalAccelerate : list){
//System.out.println("final"+ TotalAccelerate);
String space = "\n";
byte[] convert = space.getBytes();
fileOutputStream.write(convert);
String finalData;
finalData = String.valueOf(TotalAccelerate);
fileOutputStream.write(finalData.getBytes());
Log.i(DEBUG, "ans: " + finalData);
}
fileOutputStream.flush();
fileOutputStream.close();
Toast.makeText(getApplicationContext(), "Message saving", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),"Message Stopped.",Toast.LENGTH_LONG).show();
}
}
});
To regulate the code to start/stop listen to the sensor event, add the following variable somewhere in this class:
private boolean isListening = false;
And make the following modifications to your existing code:
OnStore.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if (OnStore.isChecked()){
//
// set listening flag to true
//
isListening = true;
} else if (!OnStore.isChecked()){
//
// set listening flag to false
//
isListening = false;
try {
for(double TotalAccelerate : list){
//System.out.println("final"+ TotalAccelerate);
String space = "\n";
byte[] convert = space.getBytes();
fileOutputStream.write(convert);
String finalData;
finalData = String.valueOf(TotalAccelerate);
fileOutputStream.write(finalData.getBytes());
Log.i(DEBUG, "ans: " + finalData);
}
fileOutputStream.flush();
fileOutputStream.close();
Toast.makeText(getApplicationContext(), "Message saving", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),"Message Stopped.",Toast.LENGTH_LONG).show();
}
}
});
#Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
//
// regulate
//
if (isListening) {
double xx = event.values[0];
double yy = event.values[1];
double zz = event.values[2];
TotalAccelerate = Math.round(Math.sqrt(Math.pow(xx, 2)
+ Math.pow(yy, 2)
+ Math.pow(zz, 2)));
Log.i(DEBUG, "Accelerometer = " + TotalAccelerate);
list.add(TotalAccelerate);
findPeaks(list);
sensorText.setText("Total: " + TotalAccelerate);
Log.i(DEBUG, "list values " + list);
}
}
I am new to Android programming. I am trying to connect two android mobiles through bluetooth. I am using android 4.4.4 in one mobile and android 6 in another. And I am using Windows 7, Android Studio.
Code-
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button openButton = (Button)findViewById(R.id.open);
Button sendButton = (Button)findViewById(R.id.send);
Button closeButton = (Button)findViewById(R.id.close);
myLabel = (TextView)findViewById(R.id.label);
myTextbox = (EditText)findViewById(R.id.entry);
//Open Button
openButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
try
{
findBT();
openBT();
}
catch (IOException ex) { }
}
});
//Send Button
sendButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
try
{
sendData();
}
catch (IOException ex) { }
}
});
//Close button
closeButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
try
{
closeBT();
}
catch (IOException ex) { }
}
});
}
void findBT()
{
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null)
{
myLabel.setText("No bluetooth adapter available");
}
if(!mBluetoothAdapter.isEnabled())
{
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if(pairedDevices.size() > 0)
{
for(BluetoothDevice device : pairedDevices)
{
if(device.getName().equals("motoG"))
{
mmDevice = device;
break;
}
}
}
myLabel.setText("Bluetooth Device Found");
}
void openBT() throws IOException
{
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //Standard SerialPortService ID
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mBluetoothAdapter.cancelDiscovery();
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
beginListenForData();
myLabel.setText("Bluetooth Opened");
}
void beginListenForData()
{
final Handler handler = new Handler();
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !stopWorker)
{
try
{
int bytesAvailable = mmInputStream.available();
if(bytesAvailable > 0)
{
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++)
{
byte b = packetBytes[i];
if(b == delimiter)
{
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable()
{
public void run()
{
myLabel.setText(data);
}
});
}
else
{
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex)
{
stopWorker = true;
}
}
}
});
workerThread.start();
}
void sendData() throws IOException
{
String msg = myTextbox.getText().toString();
msg += "\n";
mmOutputStream.write(msg.getBytes());
myLabel.setText("Data Sent");
}
void closeBT() throws IOException
{
stopWorker = true;
mmOutputStream.close();
mmInputStream.close();
mmSocket.close();
myLabel.setText("Bluetooth Closed");
}
}
Error- In .connect(), I am getting an exception -
read failed, socket might closed or timeout, read ret: -1.
getBluetoothService() called with no BluetoothManagerCallback
connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[55]}
I tried using insecureRFcom, it din't work. I re-paired my device, but didn't work. I removed all other paired devices from mobile, it din't work. I looked around this website and tried many approaches, but nothing works. Hope someone can help me figure out the problem.
I'm having issues communicating with a HID USB device in Android Studio.
I have code in Python which works perfectly, so the device is fine.
Also note, that I've used this java class for another device where I receive data only and it works wonderfully.
But this new device, I need to send and receive data. So I am using controlTransfer to send data on endpouint 0.
Here's the code (snippets) in Python:
import hid
DEVICEMODE = 0x0B
GBLINK = 0x02
self.dongle = hid.device()
self.dongle.open(self.idVendor, self.idProduct)
self.sendCommand(0, DEVICEMODE, 0x00, 0x01)
self.sendCommand(0, GBLINK, 0x40, 0xFF)
def sendCommand(self, pucknum, cmd, msb, lsb):
command = (0b11000000 & (devicenum << 6)) | cmd
self.dongle.set_nonblocking(1)
self.dongle.write([0x00, command, msb, lsb]) # first byte is report id
self.dongle.set_nonblocking(0)
The code then goes on to send various commands via the sendCommand method.
In Java, I have the following
public class DongleDevice implements Runnable {
protected final String TAG = "DongleDevice";
public UsbDevice usbDevice;
public UsbManager usbManager;
public UsbDeviceConnection usbDeviceConnection;
private UsbInterface intf;
private UsbEndpoint endpoint;
public int version = -1;
public Thread thread;
public volatile boolean threadRunning = false;
private boolean status = false;
private boolean firstTime = true;
private UsbRequest request = null;
public DongleDevice() {
thread = new Thread(this);
}
public void requestPermission() {
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
deviceFound = false;
deviceReady = false;
while (deviceIterator.hasNext()) {
usbDevice = deviceIterator.next();
if (usbDevice.getVendorId() == Constants.VENDOR_ID) {
deviceFound = true;
break;
}
}
if (deviceFound == true) {
PendingIntent pi = PendingIntent.getBroadcast(context, 0, new Intent("PERMISSION_GRANTED"), 0);
usbManager.requestPermission(usbDevice, pi);
}
}
public void openDevice () {
final Handler handler = new Handler();
boolean handlePlaced = handler.postDelayed(new Runnable() {
public void run() {
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
deviceFound = false;
deviceReady = false;
while (deviceIterator.hasNext()) {
usbDevice = deviceIterator.next();
if (usbDevice.getVendorId() == Constants.VENDOR_ID) {
deviceFound = true;
break;
}
}
if (deviceFound == true) {
if (usbManager.hasPermission(usbDevice)) open();
else closeDevice();
}
}
}, 2000);
}
private void open() {
endpoint = intf.getEndpoint(0);
usbDeviceConnection = usbManager.openDevice(usbDevice);
status = usbDeviceConnection.claimInterface(intf, true);
if (status) {
getVersion();
thread.start();
} else {
closeDevice();
}
}
private void getVersion() {
byte[] rawDescriptors;
rawDescriptors = usbDeviceConnection.getRawDescriptors();
version = (int)(rawDescriptors[12] & 0x01);
}
public void closeDevice() {
deviceReady = false;
deviceFound = false;
if (threadRunning == true) {
if (request != null) {
request.cancel();
}
}
}
public void onDestroy() {
closeDevice();
}
public boolean isOpen() {
return deviceFound;
}
#Override
public void run() {
threadRunning = true;
deviceReady = true;
ByteBuffer buffer = ByteBuffer.allocate(60);
if (request != null) request.cancel();
request = new UsbRequest();
status = request.initialize(usbDeviceConnection, endpoint);
P_Device pd1 = new P_Device(0); //a class for parsing the 60 byte data packet received
byte[] command;
int response;
int requestType = 0x21;
int requestId = 0x9;
int value = 0x200; // 0x300 also works
int index = 0;
int timeout = 5000;
byte DEVICEMODE = 0x0B;
byte GBLINK = 0x02;
while (deviceFound == true) {
command = new byte[] {DEVICEMODE, 0x00, 0x01}; // send command followed by two bytes
response = usbDeviceConnection.controlTransfer(requestType, requestId, value, index, command, command.length, timeout);
Logger.d(TAG,"controlTransfer response = " + response); // I get 3 as a response
try { thread.sleep(100); } catch (Exception e) { }
for (int i=0; i<20; i++) {
command = new byte[]{GBLINK, (byte) 64, (byte) 255}; // should blink for ~300 ms at full intensity
response = usbDeviceConnection.controlTransfer(requestType, requestId, value, index, command, command.length, timeout);
Logger.d(TAG, "controlTransfer response = " + response); // I get 3 as a response
try { thread.sleep(500); } catch (Exception e) { }
}
for (int i=0; i<20; i++) {
request.queue(buffer, 60);
if (usbDeviceConnection.requestWait().equals(request)) {
//buffer.flip();
buffer.position(0);
pd1.parse(buffer) // all results are 0, and they shouldn't be.
}
try { thread.sleep(100); } catch (Exception e) { }
}
command = new byte[] {DEVICEMODE , 0x00, 0x00};
response = usbDeviceConnection.controlTransfer(requestType, requestId, value, index, command, command.length, timeout);
Logger.d(TAG,"controlTransfer response = " + response); // I get 3 as a response
try { thread.sleep(100); } catch (Exception e) { }
deviceFound = false;
}
threadRunning = false;
deviceReady = false;
}
}
When I run my code I get the confirmation that the bytes sent are 3 (a -1 would indicate an error). But the device isn't blinking as it should, and I get all 0's from the read.
Any help would be appreciated.
I'm new at coding in Android. I've been following the book "Professional Android 4 App Development" I am basically trying to figure out a way to receive a bunch of strings over Bluetooth sent by any device. This is what I have so far
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set up the window layout
setContentView(R.layout.data);
ListView myData = (ListView)findViewById(R.id.list);
final ArrayList<String> mData = new ArrayList<String>();
final ArrayAdapter<String> aa;
aa = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mData);
//Bind Array to List View
myData.setAdapter(aa);
startDiscovery();
String add = BluetoothDevice.EXTRA_DEVICE;
BluetoothDevice device = mAdapter.getRemoteDevice(add);
connectToServerSocket(device, MY_UUID);
mData.add(0, incoming);
aa.notifyDataSetChanged();
}
This is my onCreate and these are the classes or functions I'm not sure how to call them...
private ArrayList<BluetoothDevice> deviceList =
new ArrayList<BluetoothDevice>();
private void startDiscovery() {
registerReceiver(discoveryResult,
new IntentFilter(BluetoothDevice.ACTION_FOUND));
if (mAdapter.isEnabled() && !mAdapter.isDiscovering())
deviceList.clear();
mAdapter.startDiscovery();
}
BroadcastReceiver discoveryResult = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String remoteDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
BluetoothDevice remoteDevice =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
deviceList.add(remoteDevice);
Log.d(TAG, "Discovered" + remoteDeviceName);
}
};
This is my Socket:
private void connectToServerSocket(BluetoothDevice device, UUID uuid){
try{
BluetoothSocket clientSocket = device.createRfcommSocketToServiceRecord(uuid);
clientSocket.connect();
StringBuilder incoming = new StringBuilder();
listenforData(clientSocket, incoming);
transferSocket = clientSocket;
}catch(IOException e){
Log.e("BLUETOOTH","Bluetooth client I/O Exception", e);
}
}
And My listen for data looks like this:
private void listenforData(BluetoothSocket socket, StringBuilder incoming){
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
try{
InputStream instream = socket.getInputStream();
int bytesRead = -1;
while(true){
bytesRead = instream.read(buffer);
if (bytesRead != -1){
String result = "";
while((bytesRead == bufferSize)&&(buffer[bufferSize-1]!=0)){
result = result + new String(buffer,0,bytesRead-1);
bytesRead= instream.read(buffer);
}
result = result + new String(buffer, 0, bytesRead -1);
incoming.append(result);
}
socket.close();
}
}catch (IOException e){
Log.e(TAG, "Message received failed.", e);
}
finally{
}
}}
What I am missing is how to retrieve the strings from the socket listener and place them on the ListView. I need some guidance. Am I even doing this correctly?