I try to write an app that sends text from Windows computer to Android cellphone.
The text I send can be in English or Hebrew (for example). The connection is via Socket. The code I use on the Windows side (Visual studio 2012):
String buffer = // Some text
// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes(buffer + "\n");
// Send the data through the socket.
int bytesSent = socketSender.Send(msg);
And on the Android side:
//After I establish the Socket
String text = "";
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader in = new BufferedReader(isr);
while ((inputText = in.readLine()) != null)
{
text = inputText;
}
All this works perfectly when sending English text.
When I try to send Hebrew text I replace to this line:
byte[] msg = Encoding.Unicode.GetBytes(buffer + "\n");
But on the Android side I can't "read" it.
I tried to use CharsetEncoder but didn't work (or I did it the wrong way).
Any ideas?
Ok, so the answer is:
on the Windows side:
byte[] msg = Encoding.UTF8.GetBytes(buffer + "\n");
And on the Android side:
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
Related
Working on a project where an Android client communicates with a .Net server via sockets.
It can pass text messages without issue.
It now needs to be expanded to pass an jpeg image.
The server side code:
Dim fs As FileStream = New FileStream(imagePath, FileMode.Open)
Dim br As BinaryReader = New BinaryReader(fs)
sendBytes = br.ReadBytes(fs.Length)
logger.Debug("sending " & sendBytes.Length & " bytes")
clientStream.Write(sendBytes, 0, sendBytes.Length)
clientStream.Flush()
clientStream.Close()
The Android client code:
message send / receive
socket = new Socket(dstAddress, dstPort);
DataOutputStream writer = new DataOutputStream(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
byte[] outputBytes = requestString.getBytes();
writer.write(outputBytes);
Log.d(method, "Message sent: " + requestString);
while ((responseString = reader.readLine()) != null) {
response += responseString + "\n";
}
reader.close();
writer.close();
socket.close();
then trying to reconstruct the image from the response:
byte[] imageBytes = reponse.getBytes();
Log.d(method, "imageBytes.length: " + imageBytes.length);
ByteArrayInputStream is = new ByteArrayInputStream(imageBytes);
ImageView imageV = new ImageView(activity);
imageV.setImageBitmap(BitmapFactory.decodeStream(is));
LogCat error message is: SkImageDecoder::Factory returned null
PLUS the server log says it sent 14548 bytes,
BUT the client log says it received 25294 bytes.
An encoding issue?
I tried adding encoding to the server BinaryReader, no luck.
I also tried on the client side:
imageV.setImageBitmap(BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length));
I have spent hours looking through dozens of posts, I also tried other changes I can't even remember.
but, always "Factory returned null"
What am I doing wrong?
Edit----
Tried changing to
byte[] imageBytes = Base64.decode(response, Base64.DEFAULT)
That generated: IllegalArgumentException: bad base-64
You cannot use readLine() to read the bytes of an image.
Declare a buffer and in a loop read() bytes in the buffer and save them.
You cannot use intermediate Strings either.
If the server only sends an image you could even use
imageV.setImageBitmap(BitmapFactory.decodeStream(socket.getInputStream()));)
variable of position in inputstream may be set to 1024 after the first decode. So add inputstream.reset() before the second decode. Hope that works.
I am trying to download the json file which contains slovenian characters,While downloading json file as a string I am getting special character as specified below in json data
"send_mail": "Po�lji elektronsko sporocilo.",
"str_comments_likes": "Komentarji, v�ecki in mejniki",
Code which I am using
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
try {
InputStream input1 = new BufferedInputStream(url.openStream(), 300);
String myData = "";
BufferedReader r = new BufferedReader(new InputStreamReader(input1));
StringBuilder totalValue = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
totalValue.append(line).append('\n');
}
input1.close();
String value = totalValue.toString();
Log.v("To Check Problem from http paramers", value);
} catch (Exception e) {
Log.v("Exception Character Isssue", "" + e.getMessage());
}
I want to know how to get characters downloaded properly.
You need to encode string bytes to UTF-8. Please check following code :
String slovenianJSON = new String(value.getBytes([Original Code]),"utf-8");
JSONObject newJSON = new JSONObject(reconstitutedJSONString);
String javaStringValue = newJSON.getString("content");
I hope it will help you!
Decoding line in while loop can work. Also you should add your connection in try catch block in case of IOException
URL url = new URL(f_url[0]);
try {
URLConnection conection = url.openConnection();
conection.connect();
InputStream input1 = new BufferedInputStream(url.openStream(), 300);
String myData = "";
BufferedReader r = new BufferedReader(new InputStreamReader(input1));
StringBuilder totalValue = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
line = URLEncoder.encode(line, "UTF8");
totalValue.append(line).append('\n');
}
input1.close();
String value = totalValue.toString();
Log.v("To Check Problem from http paramers", value);
} catch (Exception e) {
Log.v("Exception Character Isssue", "" + e.getMessage());
}
It's not entirely clear why you're not using Android's JSONObject class (and related classes). You can try this, however:
String str = new String(value.getBytes("ISO-8859-1"), "UTF-8");
But you really should use the JSON libraries rather than parsing yourself
When creating the InputStreamReader at this line:
BufferedReader r = new BufferedReader(new InputStreamReader(input1));
send the charset to the constructor like this:
BufferedReader r = new BufferedReader(new InputStreamReader(input1), Charset.forName("UTF_8"));
problem is in character set
as per Wikipedia Slovene alphabet supported by UTF-8,UTF-16, ISO/IEC 8859-2 (Latin-2). find which character set used in server, and use the same character set for encoding.
if it is UTF-8 encode like this
BufferedReader bufferedReader= new BufferedReader(new InputStreamReader(inputStream), Charset.forName("UTF_8"));
if you had deffrent character set use that.
I have faced same issue because of the swedish characters.
So i have used BufferedReader to resolved this issue. I have converted the Response using StandardCharsets.ISO_8859_1 and use that response. Please find my answer as below.
BufferedReader r = new BufferedReader(new InputStreamReader(response.body().byteStream(), StandardCharsets.ISO_8859_1));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null)
{
total.append(line).append('\n');
}
and use this total.toString() and assigned this response to my class.
I have used Retrofit for calling web service.
I finally found this way which worked for me
InputStream input1 = new BufferedInputStream(conection.getInputStream(), 300);
BufferedReader r = new BufferedReader(new InputStreamReader(input1, "Windows-1252"));
I figured out by this windows-1252, by putting json file in asset folder of the android application folder, where it showed same special characters like specified above,there it showed auto suggestion options to change encoding to UTF-8,ISO-8859-1,ASCII and Windows-1252, So I changed to windows-1252, which worked in android studio which i replicated the same in our code, which worked.
I'm trying to send some commands to Android (client) from VB.NET (server) using sockets. I can connect the client to the server, but I don't know how to receive the commands sent by the server.
Here's a part of my Android code:
public void connect(View v){ //called on button click
SERVER_IP = ip.getText().toString(); //it gets the server's ip from an editText
SERVER_PORT = Integer.parseInt(port.getText().toString()); //and the port too
Toast.makeText(this, "Trying to connect to\n" + SERVER_IP + ":" + SERVER_PORT + "...", Toast.LENGTH_SHORT).show();
new Thread(new Runnable() {
public void run() {
InetAddress serverAddr;
try {
serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVER_PORT); //It establishes the connection with the server
if(socket != null && socket.isConnected()){ //not sure if it is correct
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//Here comes the problem, I don't know what to add...
}
} catch (Exception e) {
}
}
}).start();
}
And here's a part of my VB.NET send code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
send(TextBox1.text)
End Sub
Private Sub Send(ByVal command)
Dim temp() As Byte = UTF8.GetBytes(command) 'Is UTF8 right to use for that?
stream.Write(temp, 0, temp.Length)
stream.Flush()
End Sub
Question1: is it right to us UTF8 instead of for example ASCII encoding?
Question2: what would I change in the Android code if it wanted to use a timer that sends a command every second?
Thanks.
To read input from a BufferedReader you need to do something similiar to this:
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while((line = input.readLine()) != null){
// do something with the input here
}
A nice tutorial on sockets is available from oracle in the docs: http://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
The default charset on Android is UTF-8 http://developer.android.com/reference/java/nio/charset/Charset.html, so no worries there but you can always send a byte stream from the server onto the client and decode it however you want.
To receive a byte stream you need to do this:
BufferedInputStream input = new BufferedInputStream(socket.getInputStream());
byte[] buffer = new byte[byteCount];
while(input.read(buffer, 0, byteCount) != -1 ){
// do something with the bytes
// for example decode it to string
String decoded = new String(buffer, Charset.forName("UTF-8"));
// keep in mind this string might not be a complete command it's just a decoded byteCount number of bytes
}
As you see it's much easier if you send strings instead of bytes.
If you want to receive input from the server periodically, one of the solutions would be to create a loop which opens a socket, receives input, process it, closes the socket, and then repeats, our you could just keep the loop running endlessly until some command like "STOP" is received.
I've prepared socket client connection like this:
Socket socket = new Socket();
socket.setSoTimeout(500);
hostname = "XX.YY.ZZ.XX";
socket.connect(new InetSocketAddress(hostname, port), 6000);
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
false);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
and I read data using i.e. this code:
if (in.ready() == true) {
String message = in.readLine();
Log.e("MyApplication", "data=" + message);
}
When I look in logcat I see ? char instead of every national characters.
I'm sure data sending to my android application is in utf-8 charset therefore I tried to use code like this:
UTF8Str = new String(message.getBytes(),"UTF-8");
or creating BufferReader like this:
in = new BufferedReader(new InputStreamReader(
socket.getInputStream(),"UTF-8"));
but everything without success.
Can somebody help me resolve problem conversion chars to display them in logcat as nationals (my main goal is to display them in TextView). Everything worked two weeks ago but after some Ecclipse reconfiguration (I can't back to old settings) stoped.
~Artik
Does Android TCP Socket Client read one more line the response??
inputStreamReader = new InputStreamReader(socket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
response = bufferedReader.readLine();
response = bufferedReader.readLine();
Log.i(TAG, "Response :: " + response);
I cannot read two line. Because my server will response
200 OK \n
Content.......
And the content will stream to the client every seconds, I don't wanna connect the socket every times. Can sbd help??
An example that will continue to read until an empty new line is found:
inputStreamReader = new InputStreamReader(socket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
String line = bufferedReader.readLine(); // add first line
while (line != "")
{
response += line;
line = bufferedReader.readLine();
}
Log.i(TAG, "Response :: " + response);