Nexus 7 Android File Transfer (Socket Programming in Android) - android

public class WiFiLibrary {
public Socket client = null;
public FileInputStream fileInputStream = null;
public BufferedInputStream bufferedInputStream = null;
public OutputStream outputStream = null;
public void Connect()
{
try
{
client = new Socket("169.254.84.140",9999);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void SendFile()
{
try
{
File file = new File("/sdcard/TEST/TEST.xml");
byte[] mybytearray = new byte[(int) file.length()];
fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
/**reads the file */
bufferedInputStream.read(mybytearray, 0, mybytearray.length);
outputStream = client.getOutputStream();
/** writes file to the output stream byte by byte */
outputStream.write(mybytearray, 0, mybytearray.length);
outputStream.flush();
bufferedInputStream.close();
outputStream.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public void Disconnect()
{
try
{
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Here is my client class code for android. But when i said connect it crashes and closes. I add permissions my Manifest (There is no problem on the manifest). I used some part of code s in the past with a different tablet. But I try it Nexus 7 and it just crashed.
Here is my manifest permissions also:
android:minSdkVersion="16"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
Could anyone an idea what is the problem about my nexus 7 ?? I opened nexus 7 as developer also but nothing was changed. Samely it crashed.

I got this
http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged. See the document Designing for Responsiveness.

Related

Issues when fetching data/Json/file from assets manager on Android 10

Below is my code for reading Json file from assets, It works on every other device except Pixel 3 XL which android version is 10.This device returning null from assets
StringBuilder builder = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader( newInputStreamReader( MyApp.getAppInstance().getAssets().open(fileName)));
// do reading, usually loop until end of file reading
String mLine;
builder = new StringBuilder();
while ((mLine = reader.readLine()) != null) {
builder.append(mLine);
}
} catch (IOException e) {
//log the exception
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {}
}
}
return builder.toString();
}
Make sure you have given the required permission in manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and for Android 10 issue try using
android:requestLegacyExternalStorage="true"
inside your application tag

ObjectInputStream 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

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. :)

Source not found error

i am new android developer
when ever i run this code i get this error "Source not found." just when it reaches the
url.openStream()
any idea how to fix this?
try {
URL url = new URL("http://pollsdb.com/test.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
}
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
<uses-permission
android:name="android.permission.INTERNET" />
add that under your first manifest tag in your AndroidManifest.xml
I have the same problem too. But now, i have been solved this problem by reference http://developer.android.com/guide/components/processes-and-threads.html
about the thread use.
You need to create a worker thread to work for open the URL stream rather than using the main thread(UI thread).
Of course, you also need to add
<uses-permission android:name="android.permission.INTERNET" />
in your AndroidManifest.xml

Android Socket error in client-server app

When I want to make connection with my server my android application is crashing on the line where a make a new socket.
The code where I make the connection in my ClientAppl.java looks like this.
public class ClientAppl {
private InetAddress host;
private int port;
private Socket link = null;
ObjectInputStream istream;
ObjectOutputStream ostream;
private static MainActivity mainActivity;
private static ClientAppl instance = new ClientAppl(mainActivity);
private ClientAppl(MainActivity frm){
ClientAppl.mainActivity = frm;
}
public static ClientAppl getInstance(){
return instance;
}
public void makeConnection(String sIP, int port) throws IOException, java.net.ConnectException{
if(link == null){
System.out.println("Make connection...");
this.host = InetAddress.getByName(sIP);
this.port = port;
link = new Socket(host, port);
System.out.println("Inputkanaal & outputkanaal vastleggen...");
ostream = new ObjectOutputStream(link.getOutputStream());
System.out.println("OK - output");
istream = new ObjectInputStream(link.getInputStream());
System.out.println("OK - input");
AcceptMessageHandler amh = new AcceptMessageHandler();
Thread t = new Thread(amh);
t.start();
}
}
In MainActivity.java I added this code to start a connection.
txtServerIP = (EditText)findViewById(R.id.txtServerIP);
txtServerPoort = (EditText)findViewById(R.id.txtServerPoort);
try {
ClientAppl.getInstance().makeConnection(txtServerIP.getText().toString(), Integer.parseInt(txtServerPoort.getText().toString()));
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (ConnectException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
And this is my manifest-file. What's wrong? :(
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="be.howest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET">
</uses-permission>
<application android:icon="#drawable/ic_launcher" android:label="#string/app_name">
<activity
android:name="project.client.pc.view.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
5-14 15:55:28.669: E/AndroidRuntime(572): android.os.NetworkOnMainThreadException
You have always been warned against doing networking operations on the main (UI) thread, and you are now effectively prohibited from doing so by pro-active checks which will cause this fatal exception.
As Chris points out, you'll need to do all of your TCP socket interactions on threads other than the UI thread. In my code, I establish the socket in an AsyncTask, which sounds scary but if I can do it, you certainly can. Here's a decent tutorial:
http://www.vogella.com/articles/AndroidPerformance/article.html
Subsequently, spawn a new thread for each socket "conversation" -- that's not too difficult either.

Categories

Resources