I wanted to know how to send a byte in binary form via bluetooth.
At the moment I use this code:
mSendButton = (Button) findViewById(R.id.button_send);
mSendButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Send a message using content of the edit text widget
TextView view = (TextView) findViewById(R.id.edit_text_out);
String message = view.getText().toString();
sendMessage(message);
}
});
only in this way sends string and not a byte.
Thanks for the help.
This is the source:
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
According to your source code, you are sending byte array already with the write method. If you called mChatService.write(byte[]data) so calling something like this, should work:
mChatService.write(new byte[]{5});
Where 5 is the byte value you want to send, in other words, the call to the sendMessage method is only translating your String into a byte array which is then sent to the bluetooth service.
Related
I'm trying to write to a tag but I don't want to send a text, I want to send an array of bytes because that way I'll have a better sending control and I'll be able to establish fixed data according to the position of the array when I read it, I was investigating and I didn't find anything in particular .
The tag I have has NfcV and Ndef as techlist. I tried MifareClassic but it doesn't show up as null. Any other ideas please.
I want to emphasize that the byte array must be exclusively the data that I send, because I have seen other scripts like NdefRecord but they respect parameters at the beginning of the frame by writing data that I do not want but that function needs it to write.
private void write(String text, Tag tag) throws IOException, FormatException {
//byte[] data= Const.ResponseDataDeviceWrite;
//NdefRecord records = new NdefRecord(data);
// NdefRecord[] records = { createRecord(text) };
byte[] data = {66,104,111,108,97,32,32,32,32,32,32,32,32};
//records=data;
// NdefMessage message = new NdefMessage(records);
//NdefMessage message = createRecord(text);
// Get an instance of Ndef for the tag.
Ndef ndef = Ndef.get(tag);
// If Ndef.get is null then try formatting it and adding message
if (ndef != null) {
// Enable I/O
ndef.connect();
// Write the message
/* NdefRecord[] records = {
NdefRecord.createMime("text/plain", data)
};*/
//NdefMessage message = new NdefMessage(data);
ndef.writeNdefMessage(new NdefMessage(new NdefRecord(NdefRecord.TNF_UNKNOWN, null, null, data)));
//ndef.writeNdefMessage(message);
// Close the connection
ndef.close();
} else {
NdefFormatable ndefFormatable = NdefFormatable.get(tag);
// Really should do a null test on ndefFormatable here but as the code is looking for an exception don't test for null
ndefFormatable.connect();
// Format at write message at the same time
// ndefFormatable.format(message);
ndefFormatable.close();
}
}
Example what came out in writing and what should be, previously it was possible to write but in an application in c#
enter image description here
There is a Mifare Classic-specific solution as they have a java library. You just need to identify the tag as MifareClassic and then you can use the writeBlock() method.
https://developer.android.com/reference/android/nfc/tech/MifareClassic#writeBlock(int,%20byte[])
You can initalize a tag using for example
MifareClassic mifareTag = MifareClassic.get(tag);
Make sure to import android.nfc.tech.MifareClassic;
I have probably a simple question but has me stumped. For my Android Wear application, I have two sensors working (step counter and heartrate).The wear app then sends these values back to the mobile application. I am sending them using the Message API. My stepcount sendMessage() and heartrate sendMessage() method look the same. Here is my heartrate sendMessage method.
private void sendMessageToHandheld(final String message) {
if (mGoogleApiClient == null)
return;
Log.d(LOG_TAG,"sending a message to handheld: "+message);
// use the api client to send the heartbeat value to our handheld
final PendingResult<NodeApi.GetConnectedNodesResult> nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient);
nodes.setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
#Override
public void onResult(NodeApi.GetConnectedNodesResult result) {
final List<Node> nodes = result.getNodes();
if (nodes != null) {
for (int i=0; i<nodes.size(); i++) {
final Node node = nodes.get(i);
Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), message, bytes);
}
}
}
});
}
Problem is I am only using one messageReceived method on the mobile. So I cant differentiate from the step value coming in or the heartrate value coming in.
#Override
public void onMessageReceived(MessageEvent messageEvent) {
super.onMessageReceived(messageEvent);
Log.d(LOG_TAG, "received a message from wear: " + messageEvent.getPath());
if (messageEvent.getPath().contains("HEARTBEAT")){
// save the new heartbeat value
currentValue = Integer.parseInt(messageEvent.getPath());
if(handler!=null) {
// if a handler is registered, send the value as new message
Log.d(LOG_TAG, "received a heartbeat message from wear: " + messageEvent.getPath());
handler.sendEmptyMessage(currentValue);
}
}
else {
// save the new steps value
currentStepValue = Integer.parseInt(messageEvent.getPath());
if (handler != null) {
// if a handler is registered, send the value as new message
Log.d(LOG_TAG, "received a step message from wear: " + messageEvent.getPath());
handler.sendEmptyMessage(currentStepValue);
}
}
I tried passing in a byte array into the Heartrate sendMessage() and other strings as flags so that I could tell the values apart but no luck. Anyone know what the best way to go about this would be?
Any help would be appreciated.
Cheers
It seems you are sending the data inside the path attribute. This is not the correct use of this parameter.
Let's take a look at the MessageApi.sendMessage(GoogleApiClient client, String nodeId, String path, byte[] data method.
What you want to do is use String path to provide identifier for your message, for example in your case it would be step_counter and heartbeat. This way you can identify it on the other side, when you receive the message.
The sensor data should go into data field. You can put it raw there, but a better way is to create a DataMap and then serialize it into byte[]. This way you can enrich the data later easily.
I could get the data appear saved in variable sbprint on screen from main activity. The varible sbprint i get from background activity that buffer bluetooth data. I want to log the data appear on screen to another class.
The problem is i can't use serializable since the data always stream from my bluetooth module in real-time mode. The code based on here
I use handler to update my UI from data buffered
NOTE: I obtain shared preference inside handler (this is inside MainActivity.java)
h = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case RECIEVE_MESSAGE: // if receive massage
byte[] readBuf = (byte[]) msg.obj;
String strIncom = new String(readBuf, 0, msg.arg1); // create string from bytes array
sb.append(strIncom); // append string
int endOfLineIndex = sb.indexOf("\r\n"); // determine the end-of-line
if (endOfLineIndex > 0) { // if end-of-line,
String sbprint = sb.substring(0, endOfLineIndex); // extract string
sb.delete(0, sb.length()); // and clear
txtArduino.setText("Data from Arduino: " + sbprint); // update TextView
SharedPreferences logPreferences = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
SharedPreferences.Editor editor = logPreferences.edit();
String textLog = txtArduino.getText().toString();
editor.putString("log", textLog);
editor.commit();
}
//Log.d(TAG, "...String:"+ sb.toString() + "Byte:" + msg.arg1 + "...");
break;
}
};
};
the h Handler get the message object from ConnectedThread class based on bluetooth documentation in this command,
h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget(); // Send to message queue Handler
My question is, how do I pass the variable sbprint into my new screen in another class using handler just like above.
here's how i received data from data passed in another. I pass the data in variable buffer by getting from shared preferences as suggested
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_datalog);
tvDatalog = (TextView) findViewById(R.id.tvDatalog);
SharedPreferences logPreferences = PreferenceManager.getDefaultSharedPreferences(this);
String text = logPreferences.getString("log", "null");
tvDatalog.setText(text+"\r\n");
}
NOTE:
I got the data from my MainActivity but seems like my asynctask that works inside my MainActivity stopped as the screen change to another class. How do i make my background activity also works on both class. I mean whenever i am changing my screen on one to another the background activity always working.
If I understand correctly, you might want to use an interface. You can define an interface in the Activity that contains the Handler. Then you can implement the interface in the desired Class.
I'm can send data from the phone to the arduino and get a response in the phone, but just in the same activity, for practical reasons I need to show the data received in the phone in another activity, so I try to pass the received data using the put extras option but I get an error and te aplication crashed, because the data is receiving in other thread I think that that could cause problems if the received data isn't complete before launch the second activity, any sugestions?
ok i have done this a really long time ago and i don't remember exactly what changes i made in the bluetooth sample so just follow these steps and you will be sending and receiving strings from any class.
if you are using the bluetooth chat example in android sdk samples, then do the following:
-in the bluetoothchat class:
*change "private" BluetoothChatService mChatService into "public".
then in the activity you want to send a string from do this
BluetoothChat.mChatService.write(byteArray);
where byteArray is as it sounds an array of bytes, so you need a a string to byte array converter to make things easy:
public static byte[] convertStringToByteArray(String s)
{
byte[] byteArray = null;
if(s!=null)
{
if(s.length()>0)
{
try
{
byteArray = s.getBytes();
} catch (Exception e)
{
e.printStackTrace();
}
}
}
return byteArray;
}
that's for sending, and as for receiving:
what i did is make a Boolean for entering and exiting a specific class so for example when i enter a class i would make this Boolean true and forward the string i receive in the Bluetoothchat class to the class i want, like for example you will go to the bluetooth chat class at these code lines:
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage);
where readMessage is the string message you recieve , but instead you will make it "readMessage" a public static variable.....so you would say if i'm in activity for example number one then set the static boolean value to true and you would make a function for example called update which checks if the boolean was true then get the readMessage string and do whatever you want with it , like set text for example:
if(Bluetoothchat.one==true)
tv.settext(Bluetoothchat.readMessage);
then you need to change this boolean to false when you exit the current activity you are in so the application won't crash, so you can do something like this:
#Override
public void onBackPressed() {
BluetoothChatone.one=false;
super.onBackPressed();
}
and if you get errors tell me so i can see what i have missed to tell you.
i am using a single port to receive both files and messages in a messenger app. i wanted to ask how can i differenntiate between the files and the messages? i have researched and found that m going to have to make a protoco, i tried but i cant seem to make one. is there any way to accomplish this?
right now i am receiving the connection like this :
public class ReceiveConnection extends Thread {
Socket clientSocket = null;
public ReceiveConnection(Socket socket)
{
this.clientSocket = socket;
SocketOperator.this.sockets.put(socket.getInetAddress(), socket);
}
#Override
public void run() {
try {
BufferedReader in = new BufferedReader(newInputStreamReader(clientSocket.getInputStream()));
while ((inputLine = in.readLine()) != null) {
if (inputLine.contains("TEXT") == true)
{
Log.i("SocketOP","text");
appManager.messageReceived(inputLine);
}
}
if (inputLine.contains("TEXT") == false)
{
InputStream is=clientSocket.getInputStream();
while(is!= null){
Log.i("SocketOP","filee");
appManager.fileReceived(is);
}
}
i have concatinated the string "TEXT" with my text message so it is coming through. putting an ELSE statement isnt working. how can i add a notifier with the file so that i know when the file is being received?
You should create a message header that contains the following data:
Starts with unique byte sequence (2-4 bytes long) that acts as a message separator. This should be a unique non-text sequence that is not very common ( e.g. not CRLF or other control sequence).
Contains message type byte, so that you know if this is text message or file.
Contains length of the message, which helps while extracting the message.