How to receive data via Bluetooth on Android? - java

I read many topics, but I couldn't find good answer. I'm working on Android application that uses Bluetooth to send and receive data from Microcontroller. I have already finished sending part and it works fine, but I have problem with receiving data on Android.
I'm using this library: https://android-arsenal.com/details/1/690#!description It doesn't have properly tutorial (or at least I don't see it), it just says about receiving data on android this:
//Listener for data receiving
bt.setOnDataReceivedListener(new OnDataReceivedListener() {
public void onDataReceived(byte[] data, String message) {
// Do something when data incoming
}
});
Does anybody have any idea how to use it? I have tried to write whole Bluetooth part by myself, but it was too hard, so I decided to use this library. I need to listen for incoming datas all the time, but also I can't do it in loop, because it will block the UI thread.

This is basically an callback function and as you can see in the parameter it is giving you 2 things data of type byte[] and message of type String. Now you can just log the 2 and see what values are being given to you like below
Log.d("Data value : " + data.toString() + "Message : " + message);
And then you can do whatever that you intend to do with it like update a view, etc. like below
TextView messageView = findViewById(R.id.message);
messageView.setText(message);

Related

Android/Java: how to send notifications to user, even when app is not "actively" being used?

I want to be able to send a notification to a user IF something changes.
For example, my application is crime-related. So users can submit reports of crimes that have happened in their neighborhoods.
When a new crime is reported, I want to be able to send ALL users in that specific neighbourhood a notification, even if they are not actively using the app.
How can this be done? I'm quite new at this but to my understanding services like Firebase Messaging require you to type out a message manually and select users to send the message to manually. I'm wondering if there's a way this can be done without someone having to manually do work?
Similar to how snapchat/instagram and stuff will send you notifications that someone has sent you a message even when you are not using your phone.
In my case, I just want the same standard notification "New crime in your area" to be displayed...
How can I do this? (Currently for notifications I'm just using Notification Channels), thank you so much!
You can easily do this using Parse Server through FCM integration.
First, you need to setup your Android app to be able to receive push notifications
Just follow this Quickstart: https://docs.parseplatform.org/parse-server/guide/#push-notifications-quick-start
Second, you need to create a cloud code function
I suggest you to create a cloud code function that will receive the neighborhood as parameter, will query for the user installations in that neighborhood and send the push notification to all of them.
It would be something like this:
Parse.Cloud.define('notifyCrime', async req => {
const query = new Parse.Query(Parse.Installation);
query.equalTo('neighborhood', req.params.neighborhood); // I'm supposing you have a field called neighborhood in your installation class - if not, you can save this field there when the user sign up
await Parse.Push.send({
where: query,
data: {
alert: 'There is a crime in your neighborhood'
},
useMasterKey: true
});
});
Reference: https://docs.parseplatform.org/js/guide/#sending-pushes-to-queries
Third, you need to call the cloud function from your Android app
Once some user has reported a crime, you can call the cloud code function that you created in step 2 to notify all other users in the same neighborhood.
It would be something like this:
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("neighborhood", "The neighborhood goes here");
ParseCloud.callFunctionInBackground("notifyCrime", params, new FunctionCallback<Object>() {
void done(Object response, ParseException e) {
if (e == null) {
// The users were successfully notified
}
}
});
Reference: https://docs.parseplatform.org/cloudcode/guide/#cloud-functions
"my understanding services like Firebase Messaging require you to type out a message manually and select users to send the message to manually".
This is not completely true. There is a method name Firebase Topic Messaging, that lets you send notifications to specific user segments only. You have to register from the app for that topic and then, you can send customized message to your user groups based on topics they subscribed to.

Use of eventBus in vertx

I am using vertx in my project and I have problems with eventBus. If I understood right, it ables several languages to communicate using one string representing a server route. I have this code in my Server.java:
vertx.eventBus().registerHandler("getTree", new Handler<Message<String>>() {
public void handle(Message<String> e) {
// e.reply(call of function returning a json string);
}
});
In a javascript file, I need to get that json string just to print it for the moment. I have:
var eventBus = require('vertx/event_bus');
eventBus.send('getTree', '', function(reply) {
console.log('I received a reply ' + reply);
});
}
But nothing happens. Does anyone know why ?
I assume that you would like to see something like I received a reply in your console.
In order to be able to receive anything back to your JavaScript reply handler, you will need to change your Java message handler and call reply method on the incoming message e.g.
vertx.eventBus().registerHandler("getTree", new Handler<Message<String>>() {
public void handle(Message<String> msg) {
msg.reply("message from Java handler");
}
});
Without calling a reply method, nothing will happen in your JavaScript sender / reply receiver code.
After adding the mentioned change to your Java code you should be able to see following logs in console:
I received a reply message from Java handler
Note that even though you use different languages with Vert.x, entire logic is executed by JVM (JavaScript by Rhino open-source implementation).

Is it possible to read Firebase data without attaching any listeners?

I'm working on a Firebase Android app and need a way to read data from Firebase without actually attaching any listeners. I don't care in this particular instance if the data changes after the initial read. Is there a way I can directly access a DataSnapshot without attaching an EventListener to a Firebase reference? Or is there some other way I can directly read from a Firebase reference with some sort of ref.getValue() equivalent?
Thank you.
You can use Firebase's REST API to get access to the "raw" data.
From: https://www.firebase.com/docs/rest-api.html
You can use any Firebase URL as a REST endpoint. All you need to do is append ".json" to the end of the URL and send a request from your favorite HTTPS client. Note that HTTPS is required. Firebase only responds to encrypted traffic so that your data remains safe.
curl https://SampleChat.firebaseIO-demo.com/users/jack/name.json
A successful request will be indicated by a 200 OK HTTP status code. The response will contain the data being retreived:
{"first":"Jack", "last": "Sparrow"}
That same page also mentions a Java wrapper project: https://github.com/bane73/firebase4j
The the Java SDK provides a addListenerForSingleValueEvent method, which is equivalent to your ref.getValue(). It is utilized just like addValueEventListener, but only retrieves a single value.
fb.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snap) {
System.out.println(snap.getName() + " -> " + snap.getValue());
}
#Override public void onCancelled() { }
});
The REST API, as Frank mentioned, is also a great choice.

How to create a poll system for IRC using Pirc

I'm a beginner java user, and beginning streamer on Twitch.tv. I have been working on developing an IRC bot all night that would streamline moderation on my channel (I want to have that level of customization that using a cookie cutter IRC bot can't give).
One thing that is stumbling me is poll creation. I have looked through the Pirc javadocs and there is no command as far as I can see that checks for messages sent by a channel op, which is crucial to keeping trolls from creating polls, and with my limited knowledge I do not know how to grab extra parameters from a message.
What I want is this:
!poll <question> <c1> <c2> <c3> <seconds>
Any help here? I will add you to my thanks screen on my outro for each stream.
From my quick look through the PIRC javadocs, it looks like the method you want is #onMessage(String channel,
String sender,
String login,
String hostname,
String message)
From here, you can get any information required. Now depending on how you're handling incoming messages, all you need to do it search for the command, which in this case is "!poll" which you'll receive from the message string. From there, you can further parse the information, and do what you want with it.
If you haven't been using them already, the javadocs for pirc are location here: http://www.jibble.org/javadocs/pircbot/index.html
As Jdsfighter said, you need to use the onMessage(...) method from the PircBot superclass. This method is called whenever a message is sent to your channel. I kinda assume you have understood this by now, as making the bot react to chat is alpha and omega when making an IRC bot.
When concerned with Moderators (Operators in IRC terms), the Twitch IRC servers behave in a way that isnt completely understood by PircBot, and I have not been successfull with the User.isOp(...) method from the User class. What I've found successfull is to include the following in my Bot class (not the main class):
Set<String> OPs = new HashSet<String>();
protected void onUserMode(String channel, String sourceNick, String sourceLogin, String sourceHostname, String recipient) {
recipient = recipient.split(" ")[2];
OPs.add(recipient);
}
This Method is called whenever you see a line begining with MODE in the console, like this one:
jtv MODE #channel +o moderatorName
Now, you need to make a method that is called whenever the message recieved starts with "!poll", and checks if the sender of the message is in the OPs Set.
Here's an outline for you, to be placed in the onMessage() method
if (message.toLowerCase().startsWith("!poll") {
if (OPs.contains(sender)) {
//TODO Add body
}
}
Now you just have to make some code that catches the rest of the line after "!Poll" and posts a message back to the channel about the different poll options.
You obviously need somewhere to store your alternatives and how many votes they get each, I suggest simply two arrays, one String[] and one int[].

How to use PubNub publish callback to find out which message to re-publish in case of an error

The publish callback in PubNub API returns with a message like below -
[1,"Sent","13729639808030640"]
But this does not give any indication as to for which message this callback is for. In case of publish error, the first value in the return array will be 0. But how do you find out which message to re-publish?
The publisher can be publishing messages at a high rate and not waiting to receive the callback before publishing another message. So when the callback is invoked the publisher might have already published 10 more messages.
PubNub REST API provide JSONP format as well. You can create map of "callback function" identifiers to actual messages and when processing completed, you can obtain reference on original message using "callback function" identifier from response.
For example:
https://pubsub.pubnub.com/publish/demo/demo/0/iosdev/m_2c453/%22Hello%20world2%22
As you can see, there is m_2c453 in URI, it will be used by server in response:
m_2c453([1,"Sent","14034711347326358"])
And here we know, that m_2c453 has been used to send "Hello world" message.
But, I think platform dependent PubNub SDK should handle all this for you.
Transferred here since it's too long for a message reply.
In reply with #Geremy, so if message 1,2,3,4,5 will be sent, i'll get a publish callback in 1,2,3,4,5 order? there won't be a case where a response will fail in say 2 and 4? In that case, if we'll continue in the notion that we get an ordered response, this would mean that a response failed to arrive for messages 4 and 5 instead of 2 and 4. Might I suggest to the pubnub team that they add a fourth data in the JSONArray they return, it would contain the id field in the message that was published ( if there is such a data e.g. { "id":123, message:"hello"} ), if there's is none, obviously the returned id would be null or empty string.
I faced a similar challenge. I wanted to queue messages while the device is offline, and then send them on reconnect. In the callback i needed a way of knowing which message was sent to remove it from the queue. I came up with this solution:
function sendData(channel, data, callback) {
Pubnub.publish({
channel: channel,
message: data,
callback : callback
});
}
//This code is placed within the "reconnect" callback of the subscription
if ($localStorage.chatQueue.length) {
for (var i = 0; i < $localStorage.chatQueue.length; i++) {
sendData(
$localStorage.chatQueue[i].channel,
$localStorage.chatQueue[i].data,
function(){
console.log("arguments");
console.log(arguments);
console.log("this");
console.log(this);
index = $localStorage.chatQueue.indexOf(this);
console.log("Message in offline queue sent, index = "+index);
if (index > -1) {
$localStorage.chatQueue.splice(index, 1);
}
}.bind($localStorage.chatQueue[i])
);
}
}
The trick is binding this in the callback function to the message object. It seems to work. I guess one could also just bind the i variable which would give a direct pointer to the message in the queue.
I was inspired by this answer in another question: https://stackoverflow.com/a/19472945/3319392

Categories