I made a app the connects to a ble device and receives data from it. I was following this link "http://toastdroid.com/2014/09/22/android-bluetooth-low-energy-tutorial" at the Hints and observation section it says to Queue All GATT operations. How do I do that?
Check out NordicSemiconductors open source project Puck Central, or more specifically the GattManager class, who perfectly demonstrates how to queue all GATT operations.
If you don't want to handle this sort low level bluetooth specifics yourself however, I can recommend the great library RxAndroidBle, which does much of the heavy lifting for you.
To queue the requests you could make a queue class which has an Arraylist of requests.
Every time you want to make a request add it to the queue and start processing the queue (if the queue isn't already being processed). Once you've processed the current item check if there are still items to process and carry on processing them.
You'll also probably need to add a timeout in case one of the requests gets stuck.
Sample code on how you could process a queue using a handler:
private void startProcessingQueue() {
if (queueIsRunning) {
return;
}
queueIsRunning = true;
h.postDelayed(new Runnable(){
public void run(){
processQueue();
if(queue.isEmpty()) {
queueIsRunning = false;
return;
}
h.postDelayed(this, QUEUE_PROCESSING_DELAY);
}
}, QUEUE_PROCESSING_DELAY);
}
Related
My team is building an Android application that will use websockets to communicate with an existing backend. We chose to use the AndroidAsync by Koushik Dutta to handle this communication.
I would like to register a ping to be sent periodically, to check if the connection is still alive. I'm using Wireshark to check the network traffic. This is a screenshot of the result that Wireshark is showing:
From what I see here, I believe that the ping is being sent, and the pong is being received.
A snippet of my code is:
private void keepAlive() {
ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor();
Runnable runnable = new Runnable() {
public void run() {
Log.d(TAG, "Pinging...");
WebSocketHandler.this.webSocket.ping("LALALA");
}
};
pingScheduledFuture = scheduler.scheduleAtFixedRate(runnable, 0, PING_PERIOD,
TimeUnit.SECONDS);
}
The onPongReceived method just prints into Logcat
#Override
public void onPongReceived(String s) {
// TODO here I'm aware if connection is still alive
Log.d(TAG, "Pong received! " + s);
}
However, Pong received! is never printed! Also, if I put a breakpoint there, the app will never stop executing at that point
Anyone has any idea on what may I be missing here?
Best regards and thanks in advance
I'm not familiar with AsyncSocket but a quick google revealed that you have to register a callback setPongCallback() somewhere for your pong to be received. Are you doing this? You're not showing a lot of code.
The problem was extremely lame, but here's the solution. I forgot to set the callback to the websocket, like this:
WebSocketHandler.this.webSocket.setPongCallback(WebSocketHandler.this);
And then, the pongs were correctly received.
I'm working on a Thread that handles all server connections:
public void run() {
//this initializes Socket and PrintWriter/DataInputStream
connect(server, port);
while(true) {
//queue is a BlockingQueue where I put the messages to send
while(!queue.isEmpty()) s
//COMMUNICATE-WITH-SERVER-CODE
}
}
}
The code works, but after a minute or so, my phone starts overheating and battery goes down fast. I know it's because of the infinite loop.
How can I solve it? I want a Thread which, once started, keeps the connection to the server (so that DataInputStream and PrintWriter won't be initialized every time). And I want the thread to be responsive: when I click a Button it should sent instantaneously a message to the server for processing.
I have implemented a Handler for communicating Thread->Activity. But how can I communicate Activity->Thread?
Any tip would be welcome.
Generally the solution would be to add a polling intervall, ex: sleep the thread for 500ms after each iteration. But in this case there is no need for that, because we do not have to poll a BlockingQueue. From the doc
A Queue that additionally supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available in the queue when storing an element.
If we use a BlockingQueue, then the queue.pop() call blocks if the queue is empty and remains blocked until an entry is pushed onto the queue. There fore there is no need for looping.
However, we will need to have some sort of mechanism to keep the thread from terminating. Here is a simple example:
public void run() {
try {
while (true) {
handleServerIO(queue.take());
}
}catch (InterruptedException ex) {
... handle ...
}
}
I am coding an application where a remote service has to run at all time and to perform these taks :
Create and keep a bluetooth connection to another device
Ask this device for informations periodically (1 second)
Get GPS Location periodically (1 second)
Write previous datas in a text file every 1 second
For this, I created from my remote service 2 Threads : one for the data request (loopThread) and one for the GPS Location (gpsThread). The loopThread, after getting the datas from the blueTooth Device should ask the gpsThread for the location. It has to be very quick, that's why I am using a Thread, so i can store the Location in a variable which can be sent.
The remote serviceand the 2 threads should communicate through handlers.
The problem is : I can make each Handlers communicate with the remote service, but not with each other.
I create Threads like this :
myGPSThread = new GPSThread(mainServiceHandler,locationManager);
myLoopThread = new AcquisitionThread(mainServiceHandler, sockIn, sockOut);
I tried sending the Handler of one to the other by message, but Handlers seem not to be parcelable.
Does anyone have the solution to this?
If you want to stick to your Handler based approach, you can set up your two Threads as follows.
For your Threads, subclass HandlerThread instead of Thread. Also, make them implement Handler.Callback and don't start() them right away.
final class GPSThread extends HandlerThread implements Handler.Callback {
private Handler otherThreadHandler;
public void setOtherThreadHandler(Handler otherThreadHandler) {
this.otherThreadHandler = otherThreadHandler;
}
#Override
public void handleMessage(Message msg) {
// like in your comment
}
}
myGPSThread = new GPSThread(locationManager);
myLoopThread = new AcquisitionThread(sockIn, sockOut);
myGPSThreadHandler = new Handler(myGPSThread.getLooper(), myGPSThread);
myLoopThreadHandler = new Handler(myLoopThread.getLooper(), myLoopThread);
myGPSThread.setOtherThreadHandler(myLoopThreadHandler);
myLoopThread.setOtherThreadHandler(myGPSThreadHanlder);
myGPSThread.start();
myLoopThread.start();
If you want low latency and your event-driven code is short and friendly, you may want to create the HandlerThreads with a better-than-default priority; see here.
As already mentioned, you can as well set up two "ordinary" Threads which operate on two LinkedBlockingQueues; these Threads would block in their run() methods upon waiting for a message (aka Object) from the other Thread.
I'm trying to connect a USB-Device ( build by myself ) to communicate with my development board ( ODROID-X )
Unfortunately, the examples are very little, as far as the asynchronous communication. I'd some problems with the interrupt driven data exchange - how to build the connection by using the asynchronous interrupt mode?
In one direction, the transmission was possible ... but in both it doesn't work. Is there an example like this:
send a ByteBuffer with endpoint_OUT
get a message from device on endpoint_IN
both in interrupt mode.
Thanks a lot for your support.
Hardy
Perhaps I am misunderstanding the question here.
The sample missile lanucher app that is part of the API package from level 12 onwards uses the queue() and requestWait() methods to handle interrupt type endpoints.
Requests are either In or Out and depend on the direction of the EndPoint.
The code for a pretty noddy request->reply looks something like this. You would want to structure real code differently but this gives you the gist of what needs to happen (I hope)
public void run() {
int bufferMaxLength=mEndpointOut.getMaxPacketSize();
ByteBuffer buffer = ByteBuffer.allocate(bufferMaxLength);
UsbRequest request = new UsbRequest(); // create an URB
request.initialize(mConnection, mEndpointOut);
buffer.put(/* your payload here */;
// queue the outbound request
boolean retval = request.queue(buffer, 1);
if (mConnection.requestWait() == request) {
// wait for confirmation (request was sent)
UsbRequest inRequest = new UsbRequest();
// URB for the incoming data
inRequest.initialize(mConnection, mEndpointIn);
// the direction is dictated by this initialisation to the incoming endpoint.
if(inRequest.queue(buffer, bufferMaxLength) == true){
mConnection.requestWait();
// wait for this request to be completed
// at this point buffer contains the data received
}
}
}
If you are actually looking for a way to run this IO in an asynchronous manner without binding a thread to it, then I think you need to consider using the DeviceConnection.getFilehandle() method to return a standard file handle which in theory you can then use as if it were any other file type resource. I would note however that I have not tried this.
If neither of these addresses the issue please revise the question to clarify what you are struggling to find examples of.
I hope this helps.
Im using a web service, so I want to use an async thread for the HTTP authentication request and another thread later to make additional service requests while my main thread runs.
Would like to see a good example of how to do this and how to show busy messages somehow in main app. How does the main app know when the thread finished? And what if my thread encounters exceptions, how do I deal with that?
HTTP requests are sent later, use the same cookies setup up by the first auth request, so will the later requests pick up the same cookies and just work?
Even better look here for the async part: Is there an accepted best-practice on making asynchronous HTTP requests in Android?
Look at here How to execute web request in its own thread?
AndroidAsync library I wrote to handle this automatically, it will run in the background and reinvoke onto the UI thread:
https://github.com/koush/AndroidAsync
// url is the URL to download. The callback will be invoked on the UI thread
// once the download is complete.
AsyncHttpClient.getDefaultInstance().get(url, new AsyncHttpClient.StringCallback() {
// Callback is invoked with any exceptions/errors, and the result, if available.
#Override
public void onCompleted(Exception e, String result) {
if (e != null) {
e.printStackTrace();
return;
}
System.out.println("I got a string: " + result);
}
});