Giter VIP home page Giter VIP logo

harryjph / android-bluetooth-serial Goto Github PK

View Code? Open in Web Editor NEW
173.0 6.0 62.0 174 KB

A library for Android to simplify basic serial communication over Bluetooth, for example when communicating with Arduinos.

License: Apache License 2.0

Java 58.87% Kotlin 41.13%
android bluetooth serial arduino android-bluetooth-serial arduinos java bluetooth-arduino bluetooth-connection serial-communication

android-bluetooth-serial's People

Contributors

augonis avatar harryjph avatar matinzd avatar stefanlechner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

android-bluetooth-serial's Issues

BluetoothManager.getInstance() never null

It;s probably because I am new to Android / Kotlin.

Trying to make a use of that module, So far working fine with list and bluetooth enabled.
I have part of code that checks the instance as in readme:

private var bluetoothManager: BluetoothManager? =BluetoothManager.getInstance()
  override fun onCreate(savedInstanceState: Bundle?) {
    if (bluetoothManager == null) {}
}

But Android studio gives me a hint, that bluetoothManager is never null

Google Play requires that apps target API level 29 or higher.

Android Studio reports following problem when opening build.gradle of library module (Module: android-bluetooth-serial.androidBluetoothSerial):

targetSdkVersion 28

Google Play requires that apps target API level 29 or higher.

No candidates found for method call targetSdkVersion.
android-bluetooth-serial.androidBluetoothSerial

Recomended action: Update targetSdkVersion to 31

Null checks

Especially on methods like closeDevice()

This can cause NullPointerExceptions.

Newline driven approach

After debugging a while, I figured out, that the communication is hard newline driven.

            synchronized(inputStream) {
                try {
                    val receivedString = **reader.readLine()**
                    if (!TextUtils.isEmpty(receivedString)) {
                        emitter.onNext(receivedString)
                    }
                } catch (e: Exception) {
                    if (!emitter.isCancelled && !closed.get()) {
                        emitter.onError(e)
                    }
                }

My communication requries a # or \r\n as delimiter.
There are several ways to solve this, the easiest and most flexibility providing solution, seems to me, changing from reader.readLine() to a scanner with a regex.
Are you interested in a modification like this ?

Tiny typo

Thank you so much for publishing this project! It's really gotten me off on the right foot. I found a super-tiny bug that is easier to post as an issue than PR. In the file android-bluetooth-serial/demoApplication/src/main/java/com/harrysoft/androidbluetoothserial/demoapp/CommunicateViewModel.java a single "s" should be removed from the onMessageReceived:

messagesData.postValue -> messageData.postValue

This will make it possible to listen for single messages, not just the whole collection.

Java IO exception while using the library in kotlin

Hello. I used the library in my application which is written in Kotlin. I translated the code into kotlin and did some fixes but I am getting
java.io.IOException: read failed, socket might closed or timeout, read ret: -1

again and again. This post from stackEx() deals with this but I guess that deals with a different problem.

I am afixing my mainActivity which is just the java code translated into kotlin. To be precise onError is giving the error which is called onConnect
Thanks


package com.bottlerunner.bluetoothlibrabrytesting

import android.Manifest
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.harrysoft.androidbluetoothserial.BluetoothManager
import com.harrysoft.androidbluetoothserial.BluetoothSerialDevice
import com.harrysoft.androidbluetoothserial.SimpleBluetoothDeviceInterface
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import javax.xml.transform.ErrorListener


class MainActivity : AppCompatActivity() {

    val bluetoothManager: BluetoothManager = BluetoothManager.getInstance() //Harry's bluetooth manager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        connectDevice("FC:AA:B6:AA:AC:22")

        val pairedDevices: Collection<BluetoothDevice> = bluetoothManager.pairedDevicesList
        for (device in pairedDevices) {
            if (ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.BLUETOOTH_CONNECT
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                Toast.makeText(this,"permission denied",Toast.LENGTH_SHORT).show()

            }

            Log.d("My Bluetooth App", "Device name: " + device.name)
            Log.d("My Bluetooth App", "Device MAC Address: " + device.address)
            Log.d("Debugg",device.bondState.toString())
        }


        val btn = findViewById<Button>(R.id.button)
        btn.setOnClickListener {
            connectDevice("FC:AA:B6:AA:AC:22")          //Tab
            ActivityCompat.requestPermissions(this, arrayOf( Manifest.permission.BLUETOOTH),0  )
            Log.d("Permission","Reached end of btn")
        }

    }


    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (requestCode == 1) {
            // Request for camera permission.
            if (grantResults.size == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission has been granted. Start camera preview Activity.
                Log.d("Permission","Reached onRequestPermissionResult")
                ActivityCompat.requestPermissions(this, arrayOf( Manifest.permission.BLUETOOTH),0  )
                Toast.makeText(this,"Permission granted",Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this,grantResults.toString(),Toast.LENGTH_SHORT).show()}
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }


    var onMessageSentListener = SimpleBluetoothDeviceInterface.OnMessageSentListener{
        Toast.makeText(this, "Sent a message! Message was: " + it, Toast.LENGTH_LONG).show() // Replace context with your context instance.
    }

    var onMessageReveivedListener = SimpleBluetoothDeviceInterface.OnMessageReceivedListener{
        // We received a message! Handle it here.
        Toast.makeText(this, "Received a message! Message was: " + it, Toast.LENGTH_LONG).show(); // Replace context with your context instance.
    }

    var errorListener = SimpleBluetoothDeviceInterface.OnErrorListener{
        Toast.makeText(this,"Durr phite muh, error" + it.message, Toast.LENGTH_SHORT).show()
    }

    lateinit var deviceInterface: SimpleBluetoothDeviceInterface

    var onConnected = Consumer<BluetoothSerialDevice>{
        // You are now connected to this device!
        // Here you may want to retain an instance to your device:
        deviceInterface = it.toSimpleDeviceInterface()

        // Listen to bluetooth events
        deviceInterface.setListeners(onMessageReveivedListener, onMessageSentListener, errorListener)

        // Let's send a message:
        deviceInterface.sendMessage("Hello world!")
    }

    var onError = Consumer<Throwable> {
        Toast.makeText(this, "How lovely error" +it.message,Toast.LENGTH_SHORT).show()
        Log.d("onError" ,it.message + "\n"+ it.cause)

    }

    fun connectDevice(mac:String) {
        bluetoothManager.openSerialDevice(mac)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(onConnected, onError)
        Log.d("Debugg","reached 114")
    }

}

Uncaught exception thrown by finalizer, Socket not created.

Hi Harry,
Thanks for the library, work like a charm!

However, there is an error on Logcat when executing OpenSerialDevice. Anyway, all the functions are still working, i.e. sending and receiving data. How do you think about this error and is there anyway to eliminate it? I am afraid it will crash on the long term usage.

Thanks!

image

Kotlin library

Could you please provide a Kotlin library?
As a newbie I am probably doing something wrong, not sure, if that can work that way. I have implemented 'com.github.harry1453:android-bluetooth-serial:v1.1' but its Java library and its not working with files from demo app.
Or is there other way to implement library from androidbluetoothserial master?

Kotlin app

Hi, can you say what's wrong ? App's crashing when I'm trying to connectDevice.
thanks in anyway
`

    class ControlActivity: AppCompatActivity() {
        private var bluetoothManager = BluetoothManager.getInstance()

    companion object {
        lateinit var m_address: String
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.control_layout)

        m_address = intent.getStringExtra(MainActivity.EXTRA_ADDRESS)!!
        println(m_address)
        connectDevice(m_address)
}


private fun connectDevice(mac: String) {
        bluetoothManager.openSerialDevice(mac)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(this::onConnected, this::onError)!!
}

private fun onConnected(connectedDevice: BluetoothSerialDevice) {
    // You are now connected to this device!
    // Here you may want to retain an instance to your device:
    val deviceInterface: SimpleBluetoothDeviceInterface? = connectedDevice.toSimpleDeviceInterface()
    //deviceInterface = connectedDevice.toSimpleDeviceInterface()

    // Let's send a message:
    deviceInterface!!.sendMessage("Hello world!")

}

}
`

Error message:

    E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.secondproject, PID: 3294
    java.lang.BootstrapMethodError: Exception from call site #0 bootstrap method
        at com.harrysoft.androidbluetoothserial.BluetoothManager.openSerialDevice(BluetoothManager.java:56)
        at com.example.secondproject.ControlActivity.connectDevice(ControlActivity.kt:34)
        at com.example.secondproject.ControlActivity.onCreate(ControlActivity.kt:29)
        at android.app.Activity.performCreate(Activity.java:7327)
        at android.app.Activity.performCreate(Activity.java:7318)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1275)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3101)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3264)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1955)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7078)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
     Caused by: java.lang.ClassCastException: Bootstrap method returned null
        at com.harrysoft.androidbluetoothserial.BluetoothManager.openSerialDevice(BluetoothManager.java:56) 
        at com.example.secondproject.ControlActivity.connectDevice(ControlActivity.kt:34) 
        at com.example.secondproject.ControlActivity.onCreate(ControlActivity.kt:29) 
        at android.app.Activity.performCreate(Activity.java:7327) 
        at android.app.Activity.performCreate(Activity.java:7318) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1275) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3101) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3264) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1955) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7078) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

Not receiving data from Bluetooth device

I am running the demo app, I am able to send data to device but not able to get data from it. The onMessageReceived method is not being called. Can you help me with this

BluetoothManager does not remove closed devices

The BluetoothManager closeDevice(String mac) { ... } removes the closed device from the bluetooth managers device list.

Calling close() on the BluetoothManager closes the device but does not remove it from the device list.

Trying to reconnect to a previously connected device will result in the BluetoothManager finding a closed device and the BluetoothSerialDevice to throw IllegalArgumentException since requireNotClosed() will fail.

Importing Library

I know this is a dumb question, but I'm pretty new to this. How would I import this library into Android Studio?

java.io.IOException: read failed, socket might closed or timeout in OpenSerialDevice

Hello Harry,

I am trying to connect my Android device (an older Samsung) to the virtual COM port on my PC. My goal is to send real-time data from the phone to my PC.

I have successfully paired my PC and the phone.

Unfortunately, the function OpenSerialDevice from the HarrySoft BluetoothManager returns an error.
This is the code (snippet from this project):

Collection<BluetoothDevice> pairedDevices = bluetoothManager.getPairedDevicesList();
for (BluetoothDevice device : pairedDevices) {
	Log.d("TrackerFragment", "Device name: " + device.getName());
	Log.d("TrackerFragment", "Device MAC Address: " + device.getAddress());

	for (ParcelUuid pid : device.getUuids()) {
		Log.d("TrackerFragment", "UUID: " + pid.getUuid().toString());
	}
	 bluetoothManager.openSerialDevice(device.getAddress()).subscribeOn(Schedulers.io())
						.observeOn(AndroidSchedulers.mainThread())
						.subscribe(this::onConnected, this::onError);
	break;
}

And the output shows that indeed the paired device (my PC) is shown. I even checked if the UUID was present:

D/TrackerFragment: Device name: DESKTOP-L7GA7BN
Device MAC Address: 00:1B:DC:0F:99:DB
D/TrackerFragment: UUID: 00001101-0000-1000-8000-00805f9b34fb
UUID: 0000110a-0000-1000-8000-00805f9b34fb
UUID: 00001112-0000-1000-8000-00805f9b34fb
UUID: 0000111f-0000-1000-8000-00805f9b34fb
UUID: 00001400-0000-1000-8000-00805f9b34fb
D/BluetoothAdapter: cancelDiscovery
D/BluetoothAdapter: cancelDiscovery = true
D/BluetoothUtils: isSocketAllowedBySecurityPolicy start : device null
D/BluetoothSocket: connect(): myUserId = 0
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
D/TrackerFragment: onError, error=java.io.IOException: read failed, socket might closed or timeout, read ret: -1

Do you have any ideas on what causes this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.