I have written a code on Android Studio to receive images from a socket server and the application connects to the server every time a button is clicked.
However, when I run the app and click the button nothing shows up but the server sends a message saying the photo is sent. When I click the button again, for the second time (the server is not connected) the image pops up instantly.
I think the issue is that the thread isn't shutting down completely when I click the button once but if I click it again, the thread shuts down forcefully and starts a new one so the image is shown.
The code for the main activity java file is :
package com.example.myapplication;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.Socket;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mTextViewReplyFromServer;
private EditText mEditTextSendMessage;
private ImageView mImg;
private byte [] imgbyte;
Handler updateConversationHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonSend = (Button) findViewById(R.id.btn_send);
mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message);
mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server);
mImg = (ImageView)findViewById(R.id.imageView);
String filepath = "/sdcard/DCIM/img.jpeg";
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_send:
Thread fst = new Thread(new ServerThread());
fst.start();
break;
}
}
public class ServerThread implements Runnable {
byte [] line;
Bitmap bitmap;
public void run() {
try {
Socket client = new Socket("192.168.1.145", 5560);
while (true) {
// LISTEN FOR INCOMING CLIENTS
try {
int bytesRead;
int current = 0;
int filesize=215320;
byte [] mybytearray2 = new byte [filesize];
InputStream is = client.getInputStream();
FileOutputStream fos = new FileOutputStream("/sdcard/DCIM/img.jpg"); // destination path and name of file
//FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray2,0,mybytearray2.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray2, current, (mybytearray2.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray2, 0 , current);
bos.flush();
// bitmap = BitmapFactory.decodeByteArray(mybytearray2 , 0, mybytearray2.length);
// mImg.setImageBitmap(bitmap);
//System.out.println(end-start);
updateConversationHandler.post(new updateUIThread(mybytearray2));
bos.close();
client.close();
break;
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class updateUIThread implements Runnable {
private byte[] byteArray;//private String msg;
public updateUIThread(byte[] array){ //public updateUIThread(String str) {
this.byteArray=array; //this.msg = str;
}
#Override
public void run() {
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray , 0, byteArray .length);
mImg.setImageBitmap(bitmap);//text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
}
Is there anyway I can kill the thread immediately after the image is recieved?
My image also shows up on the android emulator but does not show up on my phone. What could be the reason for this?
Edit : if i start the thread on the oncreate section, the image pops up as soon as the application is started
Edit : python server code :
import socket
from time import sleep
from time import time
host = ''
port = 5560
filePath = "/media/pi/ESD-USB/image.jpg"
def setupServer():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created.")
try:
s.bind((host, port))
except socket.error as msg:
print(msg)
print("Socket bind comlete.")
return s
def setupConnection():
s.listen(1) # Allows one connection at a time.
conn, address = s.accept()
print("Connected to: " + address[0] + ":" + str(address[1]))
return conn
def sendPic(s, filePath):
print(filePath)
pic = open(filePath, 'rb')
chunk = pic.read()
size = len(chunk)
print (size)
t = time()
print("Sending Picture")
s.sendall(chunk)
pic.close()
print("Done sending")
print("Elapsed time = " + str(time() - t) + 's')
s.close()
return "Done sending"
def backup(filePath):
conn = setupConnection()
response = sendPic(conn, filePath)
return response
s = setupServer()
while True:
print(filePath)
backup(filePath)
print("Everything should be backed up now.")
break
I figured out what to do. the while loop was causing an issue and i implemented runonui thread like blackapps suggested.
The working code is shown below :
package com.example.myapplication;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.Socket;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mTextViewReplyFromServer;
private EditText mEditTextSendMessage;
private ImageView mImg;
private byte [] imgbyte;
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonSend = (Button) findViewById(R.id.btn_send);
mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message);
mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server);
mImg = (ImageView)findViewById(R.id.imageView);
String filepath = "/sdcard/DCIM/img.jpeg";
}
#Override
public void onClick(View v) {
Thread fst = new Thread(new ServerThread());
fst.start();
}
public class ServerThread implements Runnable {
byte [] line;
Bitmap bitmap;
public void run() {
try {
Socket client = new Socket("192.168.1.145", 5560);
try {
int bytesRead;
int current = 0;
int filesize = 300000;
byte [] mybytearray2 = new byte [filesize];
InputStream is = client.getInputStream();
FileOutputStream fos = new FileOutputStream("/sdcard/DCIM/img.jpg"); // destination path and name of file
//FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray2,0,mybytearray2.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray2, current, (mybytearray2.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray2, 0 , current);
bos.flush();
bitmap = BitmapFactory.decodeByteArray(mybytearray2 , 0, mybytearray2.length);
long end = System.currentTimeMillis();
runOnUiThread(new Runnable() {
#Override
public void run() {
mImg.setImageBitmap(bitmap);
}
});
bos.close();
client.close();
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
e.printStackTrace();
}
});
e.printStackTrace();
}
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
e.printStackTrace();
}
});
e.printStackTrace();
}
}
}
}
the next step for me is to send the filesize of the image from the python server to the android app. also to figure out why my image does not show up on the an actual android but on the emulator.
Related
I wrote simple android java client , main activity with socketTask and and a handler in mainactivity. and it doesn't working .
I used debuger and found that the problem is in this line :
this.socket = new Socket(IP_ADDRESS, PORT);
I also had this error massage in the studio :
An unexpected packet was received before the handshake
the server is ok and responding to any other program .
Can some one advice what is the problem . I attaching mainactivity and socket task .
thanks a lot .
main activity
package com.example.app24;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import org.json.JSONObject;
public class MainActivity extends AppCompatActivity implements View.OnClickListener
{
Button btnSend ;
TextView tvFromServer;
EditText etToSend;
String strToSend,strFromServer;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSend = (Button) findViewById(R.id.btnSend);
btnSend.setOnClickListener(this);
etToSend = (EditText) findViewById(R.id.etToSend);
tvFromServer = (TextView) findViewById(R.id.tvFromServer);
tvFromServer = (TextView) findViewById(R.id.tvFromServer);
}
#Override
public void onClick(View v)
{
if (v == btnSend)
{
strToSend = etToSend.getText().toString();
new Thread(new Runnable() {
#Override
public void run() {
SocketTask send1 = new SocketTask(strToSend);
strFromServer=send1.sendReceive();
runOnUiThread(new Runnable() {
public void run() {
tvFromServer.setText(strFromServer);
}
});
}
}).start();
}
}
}
'''
SocketTask.
```
package com.example.newproj;
import android.os.AsyncTask;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class SocketTask
{
//private final static String IP_ADDRESS = "172.19.16.179";
private final static String IP_ADDRESS = "192.168.1.124";
private final static int PORT = 8821; // HTTP port
private final static int PACKET_SIZE = 1024; // standard 1kb packet size
private Socket socket;
private String sendingStr="";
private String receivingStr="";
BufferedReader reader;
public SocketTask(String str1)
{
this.sendingStr = str1;
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void send()
{
try {
OutputStreamWriter writer = new OutputStreamWriter(this.socket.getOutputStream(), StandardCharsets.UTF_8); // outputStreamWriter creating
writer.write(this.sendingStr);
writer.flush();
Log.d("Result", "sent");
}
catch (Exception e) {
Log.e("Exception", e.toString());
}
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void receive() {
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
char[] charBuffer = new char[1024];
StringBuilder stringBuilder = new StringBuilder();
reader.read(charBuffer);
stringBuilder.append(charBuffer);
reader.close();
receivingStr = stringBuilder.toString();
}
catch (IOException e)
{
Log.e("Exception", e.toString());
}
}
public String sendReceive()
{
try {
this.socket = new Socket(IP_ADDRESS, PORT);
send();
receive();
this.socket.close();
} catch (Exception e) {
Log.e("Exception", e.toString());
}
return this.receivingStr;
}
}
```
I have following problem :
My Android App is communicating via WLAN with a raspberry pi 3.
My Android App has a start button and a clear button and 2 textviews.
When the start button is pressed, it creates a sound and after that it sends a string a to the pi and the app starts a time counter, that is displayed on one of the textviews.
When the light barrier(connected with Pi) has been crossed, the pi sends a string back(end time) and this string gets received by the AsyncTask in my CLIENT Class and displayed on the second textview. But the counter is still running and that's the problem. In the moment the end time is received , i want the counter to be stopped. I need a a way for my code that these two processes communicate with each other just to stop the counter. When i press the clear button i manage it to stop the counter. My last try, that is included in the code beneath, was to set a variable to 1 in a extra class when the end time is received (in the section "on post execute" i try to set the value to 1). And a fixed timer looks up for that value "all the time", and if this value is 1 the Time counter shall be stopped. I tried this and several things but never have came to a solution. And i tried to debug the last try but it did not work. So please if you have an idea how to tell the counter to stop
The Class "Client" includes the implementation of the AsyncTask, that receives the end time and post it to the textview of the app.
The MainActivity Class includes the process for the counter and the timer that asks for the value in the counter class.
The Counter Class is there to set the variable (my try of a shared resource)
Main Activity
package com.client.androidsrc.client;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.os.Handler;
import android.os.SystemClock;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends Activity {
TextView timetext;
TextView response;
Button buttonConnect, buttonClear;
public long startTime = 0L;
public Handler customHandler = new Handler();
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//ImageView imageView = (ImageView) findViewById(R.id.imageView3);
//imageView.setImageResource(R.drawable.run);
buttonConnect = (Button) findViewById(R.id.connectButton);
buttonClear = (Button) findViewById(R.id.clearButton);
response = (TextView) findViewById(R.id.End_time);
timetext = (TextView) findViewById(R.id.Time);
timetext.setText("00:00:00");
final MediaPlayer mp = MediaPlayer.create(this, R.raw.go);
buttonConnect.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
mp.start();
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
client myClient = new client(response);
myClient.execute();
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);
//client_send send = new client_send();
//send.execute();
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
counter controller = new counter();
if(controller.stopper==1)
{
customHandler.removeCallbacks(updateTimerThread);
startTime = 0L;
timeInMilliseconds = 0L;
updatedTime = 0L;
timetext.setText("");
}
}
}, 0, 50);
}
});
buttonClear.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//timeSwapBuff += timeInMilliseconds;
customHandler.removeCallbacks(updateTimerThread);
startTime = 0L;
timeInMilliseconds = 0L;
updatedTime = 0L;
timetext.setText("00:00:00");
}
});
}
public Runnable updateTimerThread = new Runnable() {
public void run() {
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (updatedTime % 1000);
timetext.setText("" + mins + ":"
+ String.format("%02d", secs) + ":"
+ String.format("%03d", milliseconds));
customHandler.postDelayed(this, 0);
}
};
}
Client Class
package com.client.androidsrc.client;
import android.content.Context;
import android.os.AsyncTask;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Timer;
import java.util.TimerTask;
import android.widget.TextView;
/**
* Created by Florian on 26.11.2016.
*/
public class client extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response ;
TextView textResponse;
client( TextView textResponse) {
dstAddress = "192.168.42.1";
dstPort = 51717;
this.textResponse = textResponse;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(
1024);
byte[] buffer = new byte[1024];
int bytesRead;
PrintStream printStream = new PrintStream(socket.getOutputStream());
printStream.print("3");
//Log.d("Test","5 second test done");
InputStream inputStream = socket.getInputStream();
/*
* notice: inputStream.read() will block if no data return
*/
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response = byteArrayOutputStream.toString("UTF-8");
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
//response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
//response = "IOException: " + e.toString();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
counter mycounter = new counter();
mycounter.stop();
super.onPostExecute(result);
}
}
Counter Class
package com.client.androidsrc.client;
public class counter {
public int stopper = 0;
public void stop () {
stopper = 1;
}
public void setback() {
stopper = 0;
}
}
I googled and saw almost all stackoverflow solutions and android documentation but I was unable to do it. Here is my server side code:-
import socket
import time
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#host = socket.gethostname()
host = "192.168.1.100"
port = 6000
serversocket.bind((host,port))
serversocket.listen(5)
def sample1():
print "the data has arrived"
clientsocket.send("success")
def sample2():
print "the data"
clientsocket.send("success again")
while True:
clientsocket, addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
while 1:
data3 = clientsocket.recv(1024)
data4 = data3.strip()
if data4 == "hello":
sample1()
elif data4 == "hi":
sample2()
else:
print "random data"
if data4 == "stop":
break
Here is my client code on android:-
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Main22Activity extends Activity {
private Socket socket;
private static final int SERVERPORT = 6000;
private static final String SERVER_IP = "192.168.1.100";
TextView risp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main22);
risp = (TextView) findViewById(R.id.display);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
new ConnectionTask().execute();
}
class ConnectionTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... params) {
String responce = null;
try {
String str = "hello";
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
out.println(str);
out.flush();
InputStream input = socket.getInputStream();
int lockSeconds = 10*1000;
long lockThreadCheckpoint = System.currentTimeMillis();
int availableBytes = input.available();
while(availableBytes <=0 && (System.currentTimeMillis() < lockThreadCheckpoint + lockSeconds)){
try{Thread.sleep(10);}catch(InterruptedException ie){ie.printStackTrace();}
availableBytes = input.available();
}
byte[] buffer = new byte[availableBytes];
input.read(buffer, 0, availableBytes);
responce = new String(buffer);
out.close();
input.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return responce;
}
protected void onPostExecute(String responce) {
risp.setText(responce);
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
onClick event is triggered on clicking a button. All permissions firewall settings also checked they are fine. On opening the app, it connects to python server (it shows it received a connection). On clicking, it sends string hello first which makes it jump to sample1 function and android also receives message success in textView. But after that it doesn't stop and python server keeps on printing random data forever and nothing happens on clicking the button again. I want my client to send hello only once after it is pressed, get the data, update UI and wait until button is pressed again. And originally, I am using this for raspberry pi to get temperature data so each time temperature changes, python server will send data and I want to display it on my android app without need of pressing any button. How should I do the thing I originally intend to do? Corrected code will be appreciated. Thanks.
I am trying to recieve a string via RFCOMM in android
I am a newbie to android and please help me
I can send data
but receiving fails
Here is my code
Please help me
package com.example.btspp;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Scanner;
import java.util.UUID;
import java.util.regex.Pattern;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class Buttons extends Activity {
private BluetoothAdapter btAdaptor;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
private InputStream inStream = null;
private static final UUID MY_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
int counter;
volatile boolean stopWorker;
public String addressToConnect;
public static StringBuilder readStr;
TextView tv;
int aa;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_buttons);
tv = (TextView) findViewById(R.id.textView1);
addressToConnect = getIntent().getStringExtra("addressToConnect");
connectToDevice(addressToConnect);
Button btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
sendData("H");
// Toast.makeText(getBaseContext(), addressToConnect,
// Toast.LENGTH_SHORT).show();
}
});
}
private void sendData(String message) {
byte[] msgBuffer = message.getBytes();
try {
// final BT bt = new BT();
outStream.write(msgBuffer);
//readData();
} catch (Exception e) {
// TODO: handle exception
Toast.makeText(getApplicationContext(),
"Not Sent BT Data : " + e.getMessage(), Toast.LENGTH_SHORT)
.show();
}
}
/*private void readData(){
String instring = "";
try {
inStream = btSocket.getInputStream();
} catch (Exception e) {
// TODO: handle exception
}
Scanner scan = new Scanner(new InputStreamReader(inStream));
scan.useDelimiter(Pattern.compile("[\\r\\n]+"));
instring = scan.next();
scan = null;
Toast.makeText(getApplicationContext(),
"Got Data : " + instring, Toast.LENGTH_SHORT)
.show();
//return instring;
}*/
void beginListenForData()
{
final Handler handler = new Handler();
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !stopWorker)
{
try
{
int bytesAvailable = inStream.available();
if(bytesAvailable > 0)
{
byte[] packetBytes = new byte[bytesAvailable];
inStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++)
{
byte b = packetBytes[i];
if(b == delimiter)
{
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable()
{
public void run()
{
tv.setText(data);
}
});
}
else
{
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex)
{
stopWorker = true;
}
}
}
});
workerThread.start();
}
private void connectToDevice(String address) {
btAdaptor = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = btAdaptor.getRemoteDevice(address);
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
btSocket.connect();
outStream = btSocket.getOutputStream();
inStream = btSocket.getInputStream();
beginListenForData();
tv.setText("Bluetooth Opened");
//listenForMessages(btSocket, readStr);
// beginListenForData();
} catch (IOException e) {
// errorExit("Fatal Error",
// "In onResume() and socket create failed: " + e.getMessage() +
// ".");
Toast.makeText(getApplicationContext(),
"Not Connected : " + e.getMessage(), Toast.LENGTH_SHORT)
.show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_buttons, menu);
return true;
}
}
I am a newbie to android and please help me
I can send data
but receiving fails
Here is my code
Please help me
Isn't 13 "\r" the usual delimiter and not 10?
I need to grab text questions from C binary and display it in my TextView. Also, I need to grab an answers from input field and pass it to C binary, etc. I read this topic and tried to run it on Android. C binary works in shell, but my app doesn't work (blank screen). I am very new in Java and I need help.
package com.example.helloapp;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.Toast;
import android.os.Handler;
import android.os.Message;
import android.os.Bundle;
import java.io.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class HelloApp extends Activity
{
private Button btn;
private EditText editText;
private TextView textView;
private BlockingQueue<String> m_queue;
private BufferedReader bufIn;
private InputStream in;
private InputThread inputThread;
private PrintWriter printOut;
private Process p;
private Handler handler;
private String input = null;
// show nice popup on error
private void popup(String msg)
{
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
Thread.UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler()
{
#Override
public void uncaughtException(Thread t, Throwable e) {
e.printStackTrace();
HelloApp.this.finish();
}
};
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView)findViewById(R.id.textView1);
btn = (Button)findViewById(R.id.button1);
Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
// new Thread cannot change our TextView, so we use Handler
handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
String text = (String) msg.obj;
textView.setText(text);
}
};
File f = new File(getCacheDir()+"/hello");
if(!f.exists())
try {
// unpack our binary...
InputStream is = getAssets().open("hello");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
FileOutputStream fos = new FileOutputStream(f);
fos.write(buffer);
fos.close();
// ... and make it executable
try {
Process chmod = Runtime.getRuntime().exec("/system/bin/chmod 777 " +f.getPath());
chmod.waitFor();
} catch(IOException e) { popup(e.getMessage()); } catch(InterruptedException e) { popup(e.getMessage()); }
} catch(IOException e) { popup(e.getMessage()); }
try {
p = Runtime.getRuntime().exec(f.getPath());
InputStream in = p.getInputStream() ;
OutputStream out = p.getOutputStream ();
InputStream err = p.getErrorStream();
printOut = new PrintWriter(out);
m_queue = new ArrayBlockingQueue<String>(10);
inputThread = new InputThread(in, m_queue);
inputThread.start();
} catch(Exception e) { popup(e.getMessage()); }
btn.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
editText = (EditText)findViewById(R.id.editText1);
input = editText.getText().toString();
// pass something to C binary
printOut.println(input+"\n");
printOut.flush();
}
});
}
private void setTextHandler(final String text)
{
Message msg = new Message();
msg.obj = text;
handler.sendMessage(msg);
}
private void mainLoop()
{
String line;
while(true)
{
try {
line = bufIn.readLine();
// stdin is always empty... why?
if(line != null) { setTextHandler(line); }
}
catch(IOException e) { popup(e.getMessage()); return; }
}
}
private class InputThread extends Thread
{
InputThread(InputStream in, BlockingQueue<String> queue)
{
bufIn = new BufferedReader(new InputStreamReader(in));
m_queue = queue;
}
public void run() {
try { mainLoop(); }
catch(Throwable t) { popup(t.getMessage()); }
}
}
}
UPDATE: if I compile the following C code:
#include <stdio.h>
#include <string.h>
int main(void)
{
char *s;
setvbuf(stdout, NULL, _IONBF, 0); // <<<= disable buffering globally
printf("Enter your name:\n");
fflush(stdout);
scanf("%s", &s);
printf("Hello, %s", s);
fflush(stdout);
return 0;
}
I get results only when binary exits, ie. I run android app, see a blank screen (must see "Enter your name:"), input something, press OK button - binary exits and I get "Enter your name: Hello, Eugene" at once.
PROBLEM SOLVED! See updated C code.