Android sending data to Arduino via Bluetooth - java

Using various tutorials, I have managed to connect my Android phone to a HC-05 bluetooth module connected to an Arduino. What I'm trying to do is have 5 Buttons set up that will transmit a unique integer per button only when the button is held down, otherwise they will send a "0" when the button is released. ergo BUTTON1 sends a "1" when pressed and "0" when released, BUTTON2 sens a "2" when pressed and a "0" when released. Currently, I cannot figure out how to send ANY data over the connection. From reading and watching various tutorials I've gained a small understanding but seem to be missing something.
Towards the bottom of my code in the public void run(), i have set up an OnClickListener for one of my buttons to try to send...well something once its pressed just to see if I can send SOMETHING useful to the Arduino.
Here is where I have my OnClickListener. I believe I should be sending "T" to the Arduino.
pUpBtn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
String testr="T:";
byte[] msgBuffer = testr.getBytes();
try {
mmOutStream.write(msgBuffer);
} catch (IOException e) {
e.printStackTrace();
}
}
});

First
Basically as per your requirement you can not use onClickListner instead use onTouchListner
Example
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
//send integer value here.(pressed)
} else if (event.getAction() == MotionEvent.ACTION_UP) {
//Send zero here.(released)
}
}
};
here is a sample code for sending and receiving data from bluetoothSPP
this method is to connect bluetooth device to remote device
private void connectToDevice(BluetoothDevice mBTDevice) {
try {
SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
mBtSocket = mBTDevice.createRfcommSocketToServiceRecord(SPP_UUID);
mBtSocket.connect();
} catch (IOException e) {
Log.d("connectBT", "while connecting device");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
use this for sending bytes.
public void send(String data) {
byte[] buffer = data.getBytes();
try {
mOutputStream = mBtSocket.getOutputStream();
mOutputStream.write(buffer);
Log.d("message", data + " sent");
} catch (IOException e) {
e.printStackTrace();
}
}
use this function for sending Integers
public void send() {
byte[] buffer = new bytes[size];
buffer[0]=(byte)'1';//prepare data like this
..
..
try {
mOutputStream = mBtSocket.getOutputStream();
mOutputStream.write(buffer);
Log.d("message", " sent");
} catch (IOException e) {
e.printStackTrace();
}
}
Hope this helps :)

Related

How to run socket code in another threads?

In my application I have adapter and in this adapter I should call socket.
I want call socket in another thread and not call in MainThread.
I write socket code, but I don't know how can I call this in another thread.
My socket code :
mSocket.on("finish", new Emitter.Listener() {
#Override
public void call(final Object... args) {
try {
Constants.currentActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
Log.e("socketLogs", args[0] + "");
try {
startTimer();
final FinishResponse finishResponse = new Gson().fromJson(args[0].toString(), FinishResponse.class);
countDownerLayout.setVisibility(View.GONE);
winnerLay.setVisibility(View.VISIBLE);
bidCount.setVisibility(View.GONE);
offerCount.setVisibility(View.GONE);
price.setVisibility(View.GONE);
timeView.setVisibility(View.GONE);
userPic.setVisibility(View.GONE);
winnerLay.setBackgroundColor(ContextCompat.getColor(context, R.color.white));
//if (finishResponse.getRes().getWinnerAvatar() != null && !finishResponse.getRes().getWinnerAvatar().equals("")) {
Glide.with(context)
.load(Constants.SERVER + finishResponse.getRes().getWinnerAvatar())
.placeholder(R.mipmap.ic_launcher)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(User);
/* } else {
User.setImageDrawable(ContextCompat.getDrawable(context, R.mipmap.ic_launcher_round));
}*/
edtUserName.setText(finishResponse.getRes().getWinnerName());
edtUserName.setTextColor(ContextCompat.getColor(context, R.color.black));
txtStartPrice.setText("Sell");
txtStartPrice.setBackgroundColor(ContextCompat.getColor(context, R.color.TextColorGreen));
txtStartPrice.setTextColor(ContextCompat.getColor(context, R.color.white));
try {
String[] splitDate = finishResponse.getRes().getEnd().split(" ");
String[] dateSpliet = splitDate[0].split("-");
TimeUtils timeUtils = new TimeUtils(Integer.parseInt(dateSpliet[0]), Integer.parseInt(dateSpliet[1]), Integer.parseInt(dateSpliet[2]));
txtPrice.setText(splitDate[1] + " " + timeUtils.getIranianDate());
} catch (Exception e) {
}
} catch (JsonSyntaxException e) {
}
}
});
} catch (Exception e) {
}
}
});
I write above code in getView method from Adapter.
But I want write above code in another thread , and not run in MainThread.
How can I do it?
Just create new Thread for this
Runnable runnable = new Runnable() {
#Override
public void run() {
// do stuff
}
};
new Thread(runnable).start();
I would give some recommendations concerning your code. First, it is bad to call Socket in adapter in getView. You should Call it in fragment or Activity (if you don't use MVP or some other architecture).
Next big problem is that you have current activity saved in constants
Constants.currentActivity
It will cause memory leaks, you activity will live even if you close it, and your app will have many problems with such approach.

How to finish a specific intent under different method

So I have two methods. The intent works as a "Night mode" filter for screen. It is called out when button is pressed in 1 method. But I can't figure out how can I finish the intent under the other method when the off button is clicked. Any help is appriciated! I wanna finish the overlay intent which acts as a filter under the "turnNightOff" method.
Heres the code:
private void turnNightOn() {
try {
modeOnOffButton.setImageResource(R.drawable.nightmodeonbutton);
Intent filter = new Intent(this,NightmodeFilter.class);
startActivity(filter);
} catch (Exception e) {
e.printStackTrace();
}
}
private void turnNightOff() {
try {
modeOnOffButton.setImageResource(R.drawable.nightmodeonoffbutton);
} catch (Exception e) {
e.printStackTrace();
}
}

Scheduled Timer blocking itself

I've got following piece of code:
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
TextureView textureView = (TextureView) findViewById(R.id.texture);
if (textureView != null) {
try {
Log.i("MainActivity", "Read start");
String str = readQr(textureView.getBitmap());
if (str != null)
Log.i("MainActivity", str);
else Log.i("MainActivity", "No QR Code found.");
} catch (NotFoundException ex) {
Log.i("MainActivity", "No QR Code found.");
} catch (ChecksumException | FormatException e) {
e.printStackTrace();
}
}
}
}, 0, 250);
It should check for a QR code in the TextureView four times a second. The calculation takes a bit less than one second. The problem is, that the timer opens only one thread, which blocks itself => The task gets run only around one time a second.
According to this comment scheduleAtFixedRate should do the trick... But it does not, it behaves exactly like schedule in my situation.
What would be the best option to achieve what I want?
EDIT: I replaced the Timer by a ScheduledExecutorService, as suggested in the comments, but it still results in the exactly same behaviour.
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10); // I know it's too much, I just tried using 10 Threads because 4 did still not work.
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
final TextureView textureView = (TextureView) findViewById(R.id.texture);
if (textureView != null) {
try {
Log.i("MainActivity", "Read start");
String str = readQr(textureView.getBitmap());
if (str != null)
Log.i("MainActivity", str);
else Log.i("MainActivity", "No QR Code found.");
Log.i("MainActivity", "Read end");
} catch (NotFoundException ex) {
Log.i("MainActivity", "No QR Code found.");
Log.i("MainActivity", "Read end");
} catch (ChecksumException | FormatException e) {
e.printStackTrace();
Log.i("MainActivity", "Read end");
}
}
}
}, 0, 250, TimeUnit.MILLISECONDS);
A possible solution would be for the timer task to launch a new thread to perform the check, so as long as the new thread launch doesnt take more than 0.25 seconds it would be able to keep up.
The problem is that the actual check is going to overlap, meaning that you may have 3-4 tasks all finding the QR code at the same time. So is that what you want as it may have concurrency issues further down the line.
You want to check the QR code in the background thread and update the ui, then you should use background thread and Handler for updating the UI. It can be done in number of ways. this is one way.
public class FifthActivity extends AppCompatActivity {
Handler uiHandler;
Handler backgroundHandler;
TextView textureView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.collapsing_layout);
textureView = (TextView) findViewById(R.id.textView_fifth);
uiHandler=new Handler(){
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
textureView.setText(msg.getData().getString("msg"));
}
};
HandlerThread thread=new HandlerThread("BackgroundTask");
thread.start();
backgroundHandler=new Handler(thread.getLooper());
backgroundHandler.post(new Runnable() {
#Override
public void run() {
Log.i("FifthActivity", "Read start");
String str = ""+ new Random().nextInt(10);
if (str != null) {
Log.i("FifthActivity", str);
Message message=uiHandler.obtainMessage();
Bundle bundle=new Bundle();
bundle.putString("msg",str);
message.setData(bundle);
uiHandler.sendMessage(message);
// textureView.setText(str);
}
else Log.i("FifthActivity", "No QR Code found.");
backgroundHandler.postDelayed(this,250);
}
});
}
}
You can also use asynctask or Observer pattern Mechanism also

How to have a continuous receive UDP in an async function for android?

I am trying to establish a UDP send/Receive app. I send a message, the server responds back, and then the server MAY send more info over time. I created a thread to send the message, and another Async thread to continuously check in the background for new messages. However, I am not receiving the messages correctly. It works correctly if I have a constant feed of receive packets, but it doesn't work when the receive is random.
For example:
Port 1: constantly sends data to my client, so I receive new packets every second. The result is fine, my app shows each and every new packet. My "Receiving update" even ticks to go like "Receiving." "Receiving.." "Receiving..."
Port 2: i receive packets randomly. it shows them only if I keep clicking my send button. My receiving progress dots only iterate when I press the send button. Sometimes a packet flashes and goes away.
I am trying to make port 2 work. I tried putting my inbackground() function to sleep for 2 seconds after I publish a progress, but that didn't help. I am really confused how to make it so I can constantly receive UDP packets. Here is my code.
EDIT: Now port 2 displays correctly, the message doesn't just flash and disappear. However, my Receiving... progress dots update really slow. My question is, in my "doInBackground" function, I have the infinite while loop, doesn't that loop execute constantly really fast? So even if there is no new message, I still publish at the end of the loop so that my "Receiving.." progress dots should move right?
EDIT AGAIN: I literally changed nothing to the source code, just some layout stuff, and now port 2 doesn't work again. It doesn't show any new receives or the receiving update bar.
If I go to port 1 with the constant feed, then everything updates perfectly...
I tried looking at other questions, couldn't decipher what to do. Thanks for your help!
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.provider.Settings.Global;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
Button button;
TextView txt1, txtH, txtE, txtER, txtUpdate;
String msg;
CharSequence oldMsg="a";
Integer updateCount=0;
Activity mActivity;
DatagramSocket socket;
boolean msgSent = false;
boolean errorSend = false;
boolean errorReceive = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt1 = (TextView) findViewById(R.id.textView2);
txtH = (TextView) findViewById(R.id.textView1);
txtE = (TextView) findViewById(R.id.textView6);
txtER = (TextView) findViewById(R.id.textView8);
txtUpdate = (TextView) findViewById(R.id.textView9);
//I start my async class here
new receiveUDP().execute();
button = (Button) findViewById(R.id.button1);
//When I click this, I send a message
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Thread sendThread = new Thread(){
public void run(){
try{
byte[] data ="Some MSG".getBytes();
InetAddress address = InetAddress.getByName("Some address");
DatagramPacket pack = null;
pack = new DatagramPacket(data,data.length, address, somePort);
socket.send(pack);
msgSent=true;
} catch (Exception e){
boolean errorSend = true;
}
}
};
sendThread.start();
try {
sendThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (msgSent){
txtH.setText("SENT!");
}
}
});
if (errorSend){
txtE.setText("Error Sending Socket");
}
}
public class receiveUDP extends AsyncTask <Void, CharSequence, Void>{
#Override
protected Void doInBackground(Void... params) {
//Constantly check to see if we received a new packet.
while (true){
try{ //if no socket, create a new socket
if (socket == null){
socket = new DatagramSocket(somePort, InetAddress.getByName("address"));
socket.setBroadcast(true);
}
byte[] buf = new byte[2500];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
//Get the data of the packet to be a string
msg = new String(packet.getData(),0,packet.getLength());
} catch (Exception e){
errorReceive=true;
e.printStackTrace();
}
publishProgress(msg);
}
}
protected void onProgressUpdate(CharSequence...progress) {
updateCount++;
// If no errors, and if new message is different than old message
// Then change the text field to show new message.
if(!(errorReceive)){
if(!(oldMsg.equals(progress[0]))){
txt1.setText(progress[0]);
oldMsg = progress[0];
}
}else
{
txtER.setText("Error Receiving");
}
//Progress dots...
if(updateCount==1){
txtUpdate.setText("Receiving.");
}
else if(updateCount==2){
txtUpdate.setText("Receiving..");
}
else {
txtUpdate.setText("Receiving...");
updateCount=0;
}
}
}
}
i did it this way with success (consider that my received message is a string using the following symbol to divide parameters |
for this reason you see that i use the split command once message received
p.s.: don't use the emulator, try it on real phone.
p.p.s.: use startReceiveUdp to start listening when you create the activity, then use stopReceiveUdp in your gui thread to stop listening, just before to dismiss your activity (i use it inside onDismiss sub, overriding it).
ReceiveSocket receiveSocket;
void startReceiveUdp()
{
if (receiveSocket==null) {
receiveSocket=new ReceiveSocket();
receiveSocket.execute("");
}
}
void stopReceiveUdp()
{
if (receiveSocket!=null) receiveSocket.cancel(true);
}
private class ReceiveSocket extends AsyncTask<String, String, String> {
DatagramSocket clientsocket;
#Override
protected String doInBackground(String... params) {
while (true) {
try {
publishProgress(receiveMessage());
if(isCancelled()) break;
} catch (Exception e) {
//
}
}
return "";
}
String[] receiveMessage(){
String[] rec_arr = null;
try {
int port = 8081;
if (clientsocket == null) clientsocket=new DatagramSocket(port);
byte[] receivedata = new byte[30];
DatagramPacket recv_packet = new DatagramPacket(receivedata, receivedata.length);
//Log.d("UDP", "S: Receiving...");
clientsocket.receive(recv_packet);
String rec_str = new String(recv_packet.getData()); //stringa con mesasggio ricevuto
rec_str= rec_str.replace(Character.toString ((char) 0), "");
//Log.d(" Received String ",rec_str);
//InetAddress ipaddress = recv_packet.getAddress();
//int port = recv_packet.getPort();
//Log.d("IPAddress : ",ipaddress.toString());
//Log.d(" Port : ",Integer.toString(port));
rec_arr=rec_str.split("\\|");
return rec_arr;
} catch (Exception e) {
Log.e("UDP", "S: Error", e);
}
return rec_arr;
}
#Override
protected void onPostExecute(String result) {
//
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(String... rec_arr) {
//ricevi la stringa,
//splittala
//esegui l'azione richiesta sulla GUI
if (rec_arr.length>1){
String clientType=rec_arr[0];
String command=rec_arr[1];
if(command.contentEquals("go")){
//press button go
startAction(null);
}
}
}
}

Android ListView MediaPlayer

I am trying to loop through my listView and hightlight the textviews and play the text being highlighted.
Problem is all the audio files play at a same time and highlight and unhighlight at a same time as well. and the whole app seems to feeeze while the audio gets played..
I know I have to use Threads maybe but still not sure how to this.
Here is my code
//This is how I call it
Player plOptions = new Player(sound,tf);
plOptions.start();
// this is the thread
private class Player extends Thread
{
String sPlayerPath;
TextView tf;
public Player(String sPath_, TextView tv_) {
sPlayerPath = sPath_;
tf= tv_;
}
#Override
public void run()
{
final MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(sPlayerPath);
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
TextHighLight(tf);
}
});
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
TextUnHighLight(tf);
}
});
}
}
You should provide the code in onListItemSelected to answer the question why all items are being played,highlighted at the same time.
But what I understand from what you did provide, is that you dont need a thread. just use prepareAsync() instead of prepare(), android will handle the threading for you.This will greatly simplify your code.
Initialize your media player when in create method.Implement onCompletionListener event and provide the method to play the next song.In the next method reset the media player then it will work perfectly.
for eg and some imp note:
If you are clicking in the listview and the media file plays in another activity it will play multiple songs. for eg ActivityA contains ur list and ActivityB contains mediacontrols. In this case it will play multiple song to avoid this situation u must use service

Categories