ObjectInputStream Android - android

I have some trouble with the ObjectInputStream in an little android project. On my Laptop I have a Server running, which respondes an int to a String, which comes from my client (running on my andoid device).
Here is my Server:
ServerSocket socketmaker = new ServerSocket(30001);
Socket tSocket = socketmaker.accept();
ObjectInputStream in = new ObjectInputStream(tSocket.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(tSocket.getOutputStream());
String text = "";
int hashed = 0;
text = (String) in.readObject();
System.out.print("The Client asks with \""+text+"\"");
hashed = hash(text);
out.writeUTF(String.valueOf(hashed));
System.out.print(" and we answer with the hash \""+hashed+"\"\n");
out.close();
in.close();
tSocket.close();
And here comes the app:
public void onClick(View v) {
String server = host.getText().toString();
int portNr = Integer.parseInt(port.getText().toString());
try {
Socket tSocket = new Socket(server, portNr);
ObjectOutputStream out = new ObjectOutputStream(tSocket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(tSocket.getInputStream());
String text = content.getText().toString();
out.writeObject(text);
int re = Integer.parseInt(in.readUTF());
Toast.makeText(ClientActivity.this, re, Toast.LENGTH_SHORT).show();
out.close();
in.close();
tSocket.close();
} catch(Exception e) {
//print ex here...
}
}
host, port, conent are EditText's and allow the client to put in the serverinfo.
I run the server on a console and it receives the text from the client and prints out:
The Client asks with "test" and we answer with the hash "48"
But then the app closes with an error.
So the error has to be with the server sending the int and the app receiving it.But I also set the permissions in the Manifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
I also tried it with:
writeObject(int) - Integer.parseInt(readObject())
writeObject(String) - readObject()
writeInt(int) - readInt()
but none of them worked.
So please help me, and excuse my bad english (non native).
Thanks

Related

Can't connect to a computer on network running a server in java from my app

I am trying to connect a simple android client to a simple java server on another computer running on the same wi-fi network, i was able to connect with a java code(non android) on eclipse, and the server works just fine, but when i take the same code and put in my android app (android studio), it throws an IOException.
As of right now my protocol just returns a string "yay" and i just want to display it in a View.
My code:
private void createCom2(TextView showResult){
Socket pazeSocket = null;
PrintWriter pw = null;
BufferedReader br = null;
String ip = "10.0.0.4";
try {
pazeSocket = new Socket(ip, 4444);
pw = new PrintWriter(pazeSocket.getOutputStream());
br = new BufferedReader(new InputStreamReader(pazeSocket.getInputStream()));
} catch (UnknownHostException e) {
Toast.makeText(this,"Don't know about host: " + ip , Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(this,"Couldn't get I/O for the connection to: " + ip , Toast.LENGTH_SHORT).show();
}
}
Thanks.
You need Internet permission for your app. Add this line to your manifest file:
<uses-permission android:name="android.permission.INTERNET"/>
and read more abut permissions here, if you like:
http://developer.android.com/guide/topics/manifest/manifest-intro.html

Socket & SDK minVersion

I coded an app before that uses the socket class to create a TCP/IP Client like this:
Socket soc;
DataOutputStream out;
DataInputStream in;
//in try-catch loop
soc = new ("192.168.1.101", 100);
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
.....//code on I/O through socket
And it works fine on my previous ap, running sdk 9
Now I am trying to use the same function in my new app, which make uses of fragment and needed sdk 11. But the app crashes whenever it runs the socket code.
Once I change the android:minSdkVersion to 9 in manifest.xml, it works again. But I needed minSDK 11 for fragment.
What should I do? I have only code Android for few months, forgive me if I asked stupid question.Thanks a lot!
Edited: This is the OnClick function that triggered the Socket funcitons:
private Button.OnClickListener m_BtnConnectDisconnectOnClick = new Button.OnClickListener()
{
public void onClick(View v)
{
try
{
//Obtaining IP Address & Port number
String str_ip = m_EditPumpIP.getText().toString();
int int_port = Integer.parseInt(m_EditPumpPort.getText().toString());
//Establish Pump Connection
socket = new Socket(str_ip, int_port);
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
//Update Status
m_TextSystemStatus.setText("OK");
}
catch (IOException e)
{
//Update Status
m_TextSystemStatus.setText("Fail");
}
}
};
Put this in AsyncTask
//Establish Pump Connection
socket = new Socket(str_ip, int_port);
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
Like This example

UDP Packets (via WiFi Direct) never arrive

those of you who read my previous questions may already know this: I'm currently trying to get a hold on the whole WiFi Direct stuff. What I've done so far is creating the connection.
What I'm trying to do is sending a packet via UDP to the groupOwner (which's IP is of course known) - but it seems to get lost on it's way each time..
Here's a bit of my code, I've got a service for receiving files and an intentservice for submitting them in the background:
FileReceiverService.java
#Override
public void run() {
Log.d(TAG, "Thread starting...");
try {
app.log("Opening UDP socket to receive files.");
DatagramSocket socket = new DatagramSocket(PORT);
app.log("Socket open!");
socket.setSoTimeout(5000);
app.log("Waiting for packet..");
while (isRunning && !isInterrupted()) {
DatagramPacket packet = new DatagramPacket(
new byte[WiFiPacket.PACKET_SIZE],
WiFiPacket.PACKET_SIZE);
try {
socket.receive(packet);
app.log("Received " + packet.getLength()
+ " bytes, trying to parse!");
parsePacket(packet);
} catch (SocketTimeoutException e) {
} catch (Exception e) {
app.log("Something went wrong: " + e.getMessage());
e.printStackTrace();
}
}
socket.close();
app.log("Closing UDP socket");
} catch (Exception e) {
e.printStackTrace();
}
}
Where the constant WiFiPacket.PACKET_SIZE is set to 1024*32 (32 KBytes, because I've received "ERRBLABLA MSG too long" errors with higher values).
FileTransferService.java
#Override
protected void onHandleIntent(Intent intent) {
App app = (App) getApplication();
Context context = getApplicationContext();
boolean rightIntent = false;
WiFiFile file = null;
if (intent.getAction().equals(ACTION_SEND_TEXT)) {
rightIntent = true;
file = WiFiFile.fromText(intent.getExtras().getString(EXTRAS_TEXT));
} else if (intent.getAction().equals(ACTION_SEND_FILE)) {
rightIntent = true;
file = WiFiFile.fromFile(intent.getExtras().getString(
EXTRAS_FILE_PATH));
}
if (rightIntent && file != null) {
app.getOnWiFiTransmissionChangedListener().onNewOutgoingTransfer(
file);
String text = intent.getExtras().getString(EXTRAS_TEXT);
String host = intent.getExtras().getString(
EXTRAS_GROUP_OWNER_ADDRESS);
DatagramSocket socket = null;
int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
Log.d(TAG, "Sending packets to " + host + ":" + port);
try {
socket = new DatagramSocket();
int bytesSent = 0;
for (WiFiPacket p : file) {
Log.d(TAG, "Preparing another packet..");
byte[] payload = p.getBytes();
DatagramPacket packet = new DatagramPacket(payload,
payload.length, InetAddress.getByName(host), port);
Log.d(TAG, "Sending packet..");
socket.send(packet);
bytesSent += payload.length;
Log.d(TAG, "Packet send! Contained " + payload.length
+ " bytes! All over we've sent about " + bytesSent
+ " bytes!");
List<WiFiFile> list = new ArrayList<WiFiFile>();
list.add(file);
app.getOnWiFiTransmissionChangedListener()
.onTransferProgressChanged(list);
}
app.getOnWiFiTransmissionChangedListener()
.onFileTransferSuccessful(file);
Log.d(TAG, "Client: Data written");
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
} finally {
if (socket != null) {
if (socket.isConnected()) {
socket.close();
}
}
}
}
}
The code may not be the best, but as for right now the only thing I care about is to receive the damn packet. :)
For your information: I'm splitting instances of the class WiFiFile into WiFiPackets which do not exceed the PACKET_SIZE limit, thus contain some sort of own header information about the file's offset, the total length, the sender (username/inetaddress) and stuff like that.
My logging tells me that about 25KBytes were sent, the socket.send does not throw any errors but instead calls my listeners (also the one telling me the transfer is completed).
As far as I know, UDP packets can easily be dropped on their way, but I've tried it roughly 10 times and I think the probability of a 25KB packet getting lost EVERYTIME is very small.
Do you see anything I'm missing? I'm staring at my code since hours, trying to figure it out, putting more and more debug/log statements in it, but without any progress.
Thanks!
PS:
IP addresses and port are correct.
PS2:
AndroidManifest.xml
<uses-feature
android:name="android.hardware.wifi.direct"
android:required="true" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
Okay, I solved this problem.
I sent the messages directly after receiving the callback for a successful group creation, thinking that the group really would be "ready"... Solved this by sending out an initial message in a TimerTask every ~200-500ms, cancelling the Task after receiving ack.
Hope this helps some of you, facing the same problem. :)

Android network errors connecting to an address

Snippet provided:
public void update(){
try {
Socket appSoc = new Socket( "XXX.XXX.XXX.X" ,XXXXX);
BufferedReader in = new BufferedReader(new
InputStreamReader(appSoc.getInputStream()));
for (int i = 0; i < 100; i++) {
String message = in.readLine();
add(message);}
}
catch (Exception e) {
add("ERROR" + e);
}
}
add(String text) adds text to a textview.
Using the domain name instead of the IP address says that the phone cannot find the domain, is this an android problem, because it runs fine on java on the desktop.
You are probably missing the Internet persmission in your manifest. Make sure it is located outside of the application tag, like this:
<manifest>
<application>
.
.
.
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
In your androidmanifest.xml, check to see if you have given proper internet permissions.
<uses-permission android:name="android.permission.INTERNET"></uses-permission>

Problem Reading Saved File : Android

I am read & write username & password to android device using my application to internal storage. I am successful writing to the device, but while reading I get error. On start of the aplication I read that file and I get "The applicaton (...) has stopped unexpectedly. Please try again." with "Force Close" button and the app closes. I tried different ways to read, but all showed same results. I write my data as username + "\n" + passwrd + "\n". This is the code for reading data :
private static String ReadFromFile(String fileName) {
String text = "";
FileInputStream fis = null;
byte[] fileData;
try {
StringBuffer sb = new StringBuffer();
int c = 0;
fis = AppContext.openFileInput(fileName);
if (fis.available() != 0) {
fileData = new byte[fis.available()];
c = fis.read(fileData);
Log.i(TAG, "Read Byes = " + c );
java.util.StringTokenizer stk = new java.util.StringTokenizer(new String(fileData), "\n");
text = stk.toString();
} else
throw new IOException("fis.available() <= 0"); /*
c = (char)fis.read();
while (c != -1){
if (c != -1)
sb.append(c);
c = (char)fis.read();
}
text = sb.toString();
*/
fis.close();
} catch (FileNotFoundException e) {
text = "null " + e.getMessage();
} catch (IOException e) {
text = "null " + e.getMessage();
} finally {
fis = null;
}
return text;
}
/*
try {
StringBuffer sb = new StringBuffer();
RandomAccessFile raf = new RandomAccessFile(ENC_LOGIN_FILE, "r");
while ((str1 = raf.readLine()) != null){
sb.append(str1);
}
str1 = sb.toString();
} catch (FileNotFoundException e) {
errorMessage = "File Not Found: " + e.getMessage();
//e.printStackTrace();
} catch (IOException ioe) {
errorMessage = "IOExcp: " + ioe.getMessage();
//e.printStackTrace();
}*/
No path is used and the filename directly is given to write & read file. I checked out Problem facing in reading file from Internal memory of android from where I tried StringTokenizer.
Can anyone help me know where am I going wrong. The following permission are set :
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"></uses-permission>
<uses-permission android:name="android.permission.WRITE_SETTINGS"></uses-permission>
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"></uses-permission>
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"></uses-permission>
<uses-permission android:name="android.permission.READ_SYNC_STATS"></uses-permission>
<uses-permission android:name="android.permission.READ_LOGS"></uses-permission>
Also how do I debug the application. How to check the data written in Log. If I use SOP, where does it dispaly - it doesn't display in Console window ? Please help me, I am n newbie in android development.
One more thing to clarify : My motto is to store username and password in such a way that user must not be able to read them directly. I have already used MODE_PRIMITIVE. Is their a need to use JSONObject to save this data. I had a look at JSON in couple of sites & API but couldn't make out why and where it should be used. Using MODE_PRIMITIVE I believe even the user can't read the file. Only my application can read it. Then I don't think I should use JSON. Please correct me if I am wrong.
Any help is highly appreciated.
Thanks.
A suggestion:
If you are only saving username and password then use SharedPreferences instead of saving the data in a file. It is a much secure way and plus very hassle free.
Use this blog article on How to use Shared Preferences:
http://saigeethamn.blogspot.com/2009/10/shared-preferences-android-developer.html
fis = AppContext.openFileInput(fileName);
fileData = new byte[fis.available()];
java.util.StringTokenizer stk =
new java.util.StringTokenizer(new String(fileData), "\n");
It appears to me that you're trying to create a new String using an uninitialized array as input. You've asked for the array to be a specific size, but you haven't done anything to read data into the array. (Note that available() only asks for the size of the data that can be read without blocking; it doesn't actually read the data. For that you need the read() method.)
Try this:
fis = AppContext.openFileInput(fileName);
fileData = new byte[fis.available()];
fis.read(fileData);
java.util.StringTokenizer stk =
new java.util.StringTokenizer(new String(fileData), "\n");
You should check the return value of fis.read(), but give this a try to see if it lets you progress further.

Categories

Resources