I am currently trying to receive data on my android smartphone (version 4.4.4) send from my RFduino (some kind of arduino) via Bluetooth. Therefore i made a small android application.
Now everything works fine, until i try to connect my BluetoothSocket. First i got the an IOException: read failed -1 which i tried to solve like this:
IOException: read failed, socket might closed - Bluetooth on Android 4.3
Which worked. But now my application just freezes after i call connect(). I know that this is because the method blocks until it has found a connection, but why does this not connect?
My RFduino uses BluetoothBLE (low energy): Do i have to use the BluetoothGatt classes as counter-part?
Here is my code:
public BluetoothConnection(Activity parentActivity) {
this.mActivity = parentActivity;
findBluetooth();
openBluetooth();
}
private void findBluetooth() {
this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (this.mBluetoothAdapter == null) {
}
if (!this.mBluetoothAdapter.isEnabled()) {
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
this.mActivity.startActivityForResult(enableBluetooth, 0);
}
Set<BluetoothDevice> pairedDevices = this.mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
if (device.getName().equals("RFduino")) {
this.mBluetoothDevice = device;
break;
}
}
}
}
private void openBluetooth() {
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
BluetoothSocket tmp = this.mBluetoothDevice.createRfcommSocketToServiceRecord(uuid);
this.mBluetoothSocket = new NativeBluetoothSocket(tmp);
this.mBluetoothSocket.connect();
} catch (IOException e) {
// try the fallback
Log.w("BT", "Had to use fallback method!");
try {
this.mBluetoothSocket = new FallbackBluetoothSocket(this.mBluetoothSocket.getUnderlyingSocket());
Thread.sleep(500);
this.mBluetoothSocket.connect();
} catch (FallbackException e1) {
Log.w("BT", "Could not initialize FallbackBluetoothSocket classes.", e);
} catch (InterruptedException e1) {
Log.w("BT", e1.getMessage(), e1);
} catch (IOException e1) {
Log.w("BT", "Fallback failed. Cancelling.", e1);
}
}
try {
this.mInputStream = this.mBluetoothSocket.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
While NativeBluetoothAdapter and FallbackBluetoothAdapter are depicted in the thread i posted above.
Thanks for any suggestions.
Related
How to connect a bluetooth with desktop and android phone. i able to parring and connect bluetooth but unable to connected with Mouse, keyboard & pen device type.
Below given are both mobile device. but A50 device connect using other app and i want to connect M30s as mouse, keyboard.
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
e.printStackTrace();
}
mmSocket = tmp;
}
public void run() {
btAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
Hope this helps
App in Playstore
SourceCode in Github
Nothing to post here as code is in github
Its in kotlin ,convert to java using androidstudio
These one below are java but lacks/misses readme
1
2
3
I'm making an app in which Bluetooth controls an Arduino car. I'm trying to get a switch to turn the motors ON and OFF (right now an LED), but when I run the app with the following code, it gets crashed.
if (on_off_switch.isChecked()) {
command = "1";
try {
outputStream.write(command.getBytes()); //transmits the value of command to the bluetooth module
} catch (IOException e) {
e.printStackTrace();
}
} else {
command = "10";
try {
outputStream.write(command.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
But when I run the app without that code section, it runs just fine. But when I run it with the code, the app doesn't get start and the Logcat says:
--------- beginning of crash
2018-11-10 14:22:36.570 3311-3311/com.example.btcar2 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.btcar2, PID: 3311
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.btcar2/com.example.btcar2.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.OutputStream.write(byte[])' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2830)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2905)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1606)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:169)
at android.app.ActivityThread.main(ActivityThread.java:6595)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.OutputStream.write(byte[])' on a null object reference
at com.example.btcar2.MainActivity.onCreate(MainActivity.java:51)
at android.app.Activity.performCreate(Activity.java:7016)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2783)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2905)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1606)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:169)
at android.app.ActivityThread.main(ActivityThread.java:6595)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
I don't know how to fix it. Please just write if you have a question that might help my situation, thanks.
Here is the rest of my code
public class MainActivity extends AppCompatActivity {
final String DEVICE_ADDRESS = "00:12:12:24:06:48"; //MAC Address of Bluetooth Module
private final UUID PORT_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
private BluetoothDevice device;
private BluetoothSocket socket;
private OutputStream outputStream;
Button bluetooth_connect_btn;
String command; //string variable that will store value to be transmitted to the bluetooth module
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Switch on_off_switch = (Switch) findViewById(R.id.on_off_switch);
on_off_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.v("Switch State=", "" + isChecked);
}
});
if (on_off_switch.isChecked()) {
command = "1";
try {
outputStream.write(command.getBytes()); //transmits the value of command to the bluetooth module
} catch (IOException e) {
e.printStackTrace();
}
} else {
command = "10";
try {
outputStream.write(command.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
bluetooth_connect_btn = (Button) findViewById(R.id.bluetooth_connect_btn);
//Button that connects the device to the bluetooth module when pressed
bluetooth_connect_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (BTint()) {
BTconnect();
}
}
});
}
//Initializes bluetooth module
public boolean BTint() {
boolean found = false;
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) //Checks if the device supports bluetooth
Toast.makeText(getApplicationContext(), "Device doesn't support bluetooth", Toast.LENGTH_SHORT).show();
if (!bluetoothAdapter.isEnabled()) //Checks if bluetooth is enabled. If not, the program will ask permission from the user to enable it
{
Intent enableAdapter = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableAdapter, 0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
if (bondedDevices.isEmpty()) //Checks for paired bluetooth devices
Toast.makeText(getApplicationContext(), "Please pair the device first", Toast.LENGTH_SHORT).show();
else {
for (BluetoothDevice iterator : bondedDevices) {
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); //Creates a socket to handle the outgoing connection
socket.connect();
Toast.makeText(getApplicationContext(),
"Connection to bluetooth device successful", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
connected = false;
}
if (connected) {
try {
outputStream = socket.getOutputStream(); //gets the output stream of the socket
} catch (IOException e) {
e.printStackTrace();
}
}
return connected;
}
#Override
protected void onStart() {
super.onStart();
}
}
As Amjad Alwareh said, outputStream object is null. You can see that from this statement in Logcat:
java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.OutputStream.write(byte[])' on a null object reference
By putting this code
if (on_off_switch.isChecked()) {
command = "1";
try {
outputStream.write(command.getBytes()); //transmits the value of command to the bluetooth module
} catch (IOException e) {
e.printStackTrace();
}
} else {
command = "10";
try {
outputStream.write(command.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
in onCreate you are attempting to perform some actions with Bluetooth module without making sure that you have a connection.
I don't know your design and what are you trying to achieve. But I can suggest to put code above in a separate method like this:
private void performAction() {
if (on_off_switch.isChecked()) {
command = "1";
try {
outputStream.write(command.getBytes()); //transmits the value of command to the bluetooth module
} catch (IOException e) {
e.printStackTrace();
}
} else {
command = "10";
try {
outputStream.write(command.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
And then call it in BTconnect() if you want to make something right after connection is established:
// code before
if (connected) {
try {
outputStream = socket.getOutputStream(); //gets the output stream of the socket
performAction(); // call it here
} catch (IOException e) {
e.printStackTrace();
}
}
Or call this method in onCheckedChanged
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.v("Switch State=", "" + isChecked);
performAction(); // call it here
}
outputStream is null , You must create a new object of it , like what are you doing in BTconnect() outputStream = socket.getOutputStream();
I am trying to connect my App to the bluetooth device and after that i am doing the functionality Read and Write. I am able to do connectivity and Write command to device. But i am not able to do Read functionality.
The "Read" functionality is like, as soon as device socket will get connect to the App, it should send the device information continuously. But i my case, read() method is calling but every time i am getting the length on InputStream in 0.
Below is the code what i am writing. Please check it where i am going wrong and please help me.
public class ConnectionThread implements Runnable {
private static final String CLASSTAG = ConnectionThread.class.getSimpleName();
public static BluetoothSocket mSocket;
private InputStream inStream;
private OutputStream outStream;
private boolean canceled = false;
private Context mContext;
public ConnectionThread(Context context, BluetoothDevice device) {
this.mContext = context;
try {
mSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(Constants.mUUID));
} catch (IOException e) {
Log.e(CLASSTAG, "createRfcommSocketToServiceRecord", e);
}
}
#SuppressLint("NewApi")
#Override
public void run() {
// Cancel discovery because it will slow down the connection
if(BluetoothAdapter.getDefaultAdapter().isDiscovering()) {
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
}
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mSocket.connect();
} catch (IOException e) {
Log.e(CLASSTAG, "connect failed", e);
// Unable to connect; close the socket and get out
disconnect();
return;
}
// Get the input and output streams, using temp objects because
// member streams are final
try {
inStream = mSocket.getInputStream();
outStream = mSocket.getOutputStream();
} catch (IOException e) {
Log.e(CLASSTAG, "IO streams init failed", e);
disconnect();
return;
}
while (!canceled) {
read();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Log.e(CLASSTAG, "sleep failed", e);
}
}
}
#SuppressLint("NewApi")
public void applyCommand(String configCommand) throws IOException {
byte[] bytes = null;
bytes = new BigInteger(configCommand,16).toByteArray();
if (mSocket.isConnected()) {
//write(bytes);
outStream.write(bytes);
Log.d(CLASSTAG, "Command apply: " + bytes + " (" + configCommand + ")");
}
Toast.makeText(mContext, mContext.getString(R.string.cmd_updated), Toast.LENGTH_LONG).show();
}
private void read() {
byte[] buffer = new byte[128];
// Keep listening to the InputStream while connected
try {
// Read from the InputStream
if (inStream.available() > 0) {
int bytes = inStream.read(buffer);
if (bytes > 0) {
Log.d(CLASSTAG, "Response: " + new String(buffer, 0, bytes));
}
}
// Send the obtained bytes to the UI Activity
// mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(CLASSTAG, "reading from input stream failed", e);
disconnect();
}
}
public void disconnect() {
try {
if (outStream != null) {
outStream.close();
}
if (inStream != null) {
inStream.close();
}
mSocket.close();
canceled = true;
} catch (IOException e) {
Log.e(CLASSTAG, "close socket", e);
}
}
}
I'm making a app which can send a character ("B") to activate microcontroller then accept the result data from it. The data will be numbers 0-100. However I'm stuck in converting stream data to string.
I've tried the codes in comment but the process ended up being looping forever.
Here is my codes :
public Bluetooth(startover so, Handler handler, ProgressDialog pd) {
// TODO Auto-generated constructor stub
this.handler=handler;
activity=so;
this.pd=pd;
}
#Override
public void run() {
// TODO Auto-generated method stub
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.enable();
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
try
{
btSocket =device.createRfcommSocketToServiceRecord(MY_UUID);
//Toast.makeText(this, "Bluetooth_socket is created", Toast.LENGTH_LONG).show();
}
catch (Exception e)
{
Log.e(TAG, "ON RESUME: Socket creation failed.", e);
}
try
{
btSocket.connect();
Log.e(TAG, "ON RESUME: BT connection established, datatransfer link open.");
//Toast.makeText(this, "Bluetooth_socket is connected", Toast.LENGTH_LONG).show();
}
catch (Exception e)
{
try
{
btSocket.close();
}
catch (IOException e2)
{
Log.e(TAG, "ON RESUME: Unable to close socket during connection failure", e2);
}
}
message = "B";
sendMessage(message);
InputStream mInput=null;
try {
mInput = btSocket.getInputStream();
System.out.println("Input Open");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(!Thread.currentThread().isInterrupted() && mBluetoothAdapter.isEnabled()) {
try {
int bytesAvailable = mInput.available();
if(bytesAvailable > 0) {
System.out.println("Pesan Diterima");
BufferedReader r = new BufferedReader(new InputStreamReader(mInput));
StringBuilder total = new StringBuilder(bytesAvailable);
String line;
//BACA LEBIH DARI 1 KARAKTER
//while ((line = r.readLine()) != null) {
// total.append(line);
//}
final String message=total.toString();
handler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
pd.dismiss();
System.out.println("Turn "+message);
activity.startActivity(new Intent(activity.getApplicationContext(),result.class).putExtra("data", message));
}
});
break;
}
}
catch (IOException ex) {
}
}
super.run();
}
private void sendMessage (String message) {
byte[] send = message.getBytes();
try {
OutputStream OutStream = btSocket.getOutputStream();
OutStream.write(send);
System.out.println("Send "+message);
}
catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
}
I have a little C++/Java - Socket Server (UDP) running on my PC.
Now, i want to connect with my Android App to the Server. But when i send a package my App crash.
public void Socketinit() {
// 1. Socket erstellen!
try {
serverAddr = InetAddress.getByName("192.168.0.101");
socket = new DatagramSocket();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
createListeners();
}
and
entprivate void createListeners() {
confirm.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
buf = input.getText().toString().getBytes();
DatagramPacket packet = new DatagramPacket(buf,buf.length, serverAddr, SERVERPORT);
try {
socket.send(packet);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
It crashs on "socket.send(packet);"
I can connect to my Server via C++ so the Server is up and running. Where is the Clientproblem in my code ?
thanks
You are propably getting the NetworkOnMainThreadException (see Logcat or check in the debugger).
You can use an AsyncTask to resolve this.
Propably you are also missing the Internet permission in the manifest.
Here are further details: How to fix android.os.NetworkOnMainThreadException?