1

i want to dowload video using phone from my local server and save it on sdcard, but android client crashes, i need a little help. I used this code http://www.rgagnon.com/javadetails/java-0542.html

Here is server code:

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

  public final static int SOCKET_PORT = 13267;  // you may change this
  public final static String FILE_TO_SEND = "d:/sintel.mp4";  // you may change this

  public static void main (String [] args ) throws IOException {
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    OutputStream os = null;
    ServerSocket servsock = null;
    Socket sock = null;
    try {
      servsock = new ServerSocket(SOCKET_PORT);
      while (true) {
        System.out.println("Waiting...");
        try {
          sock = servsock.accept();
          System.out.println("Accepted connection : " + sock);
          // send file
          File myFile = new File (FILE_TO_SEND);
          byte [] mybytearray  = new byte [(int)myFile.length()];
          fis = new FileInputStream(myFile);
          bis = new BufferedInputStream(fis);
          bis.read(mybytearray,0,mybytearray.length);
          os = sock.getOutputStream();
          System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
          os.write(mybytearray,0,mybytearray.length);
          os.flush();
          System.out.println("Done.");
        }
        finally {
          if (bis != null) bis.close();
          if (os != null) os.close();
          if (sock!=null) sock.close();
        }
      }
    }
    finally {
      if (servsock != null) servsock.close();
    }
  }
}

Client code:

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;


import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;




public class MainActivity extends ActionBarActivity {

    public final static int SOCKET_PORT = 13267;      // you may change this
    public final static String SERVER = "127.0.0.1";  // localhost
    public final static String FILE_TO_RECEIVED = "/storage/external_SD/sintel.mp4";;  // you may change this, I give a
    // different name because i don't want to
    // overwrite the one used by server...

    public final static int FILE_SIZE = 14000000; // file size temporary hard coded
    // should bigger than the file to be downloaded


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);





    }



    public void buttonClicked(View view)throws IOException{

        int bytesRead;
        int current = 0;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        Socket sock = null;
        try {
            sock = new Socket(SERVER, SOCKET_PORT);
            System.out.println("Connecting...");

            // receive file
            byte [] mybytearray  = new byte [FILE_SIZE];
            InputStream is = sock.getInputStream();
            fos = new FileOutputStream(FILE_TO_RECEIVED);
            bos = new BufferedOutputStream(fos);
            bytesRead = is.read(mybytearray,0,mybytearray.length);
            current = bytesRead;

            do {
                bytesRead =
                        is.read(mybytearray, current, (mybytearray.length-current));
                if(bytesRead >= 0) current += bytesRead;
            } while(bytesRead > -1);

            bos.write(mybytearray, 0 , current);
            bos.flush();
            // System.out.println("File " + FILE_TO_RECEIVED
            //       + " downloaded (" + current + " bytes read)");
        }
        finally {
            if (fos != null) fos.close();
            if (bos != null) bos.close();
            if (sock != null) sock.close();
        }

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="download video"
        android:id="@+id/bdownload"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="199dp"
        android:onClick="buttonClicked"
        android:nestedScrollingEnabled="false" />
</RelativeLayout>

and manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.aidan.client" >

    <uses-permission android:name="android.permission.INTERNET" >
    </uses-permission>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".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>

</manifest>

2 Answers2

1

You are doing heavy Networking task in your UI thread which crash your app....
Put your buttonClicked code inside background thread

public void buttonClicked(View view)throws IOException{
    new Thread(new Runnable() {
        @Override
        public void run() {
            int bytesRead;
    int current = 0;
    FileOutputStream fos = null;
    BufferedOutputStream bos = null;
    Socket sock = null;
    try {
        sock = new Socket(SERVER, SOCKET_PORT);
        System.out.println("Connecting...");

        // receive file
        byte [] mybytearray  = new byte [FILE_SIZE];
        InputStream is = sock.getInputStream();
        fos = new FileOutputStream(FILE_TO_RECEIVED);
        bos = new BufferedOutputStream(fos);
        bytesRead = is.read(mybytearray,0,mybytearray.length);
        current = bytesRead;

        do {
            bytesRead =
                    is.read(mybytearray, current, (mybytearray.length-current));
            if(bytesRead >= 0) current += bytesRead;
        } while(bytesRead > -1);

        bos.write(mybytearray, 0 , current);
        bos.flush();
        // System.out.println("File " + FILE_TO_RECEIVED
        //       + " downloaded (" + current + " bytes read)");
    }
    finally {
        if (fos != null) fos.close();
        if (bos != null) bos.close();
        if (sock != null) sock.close();
    }       
        }
    }).start();
}
Piyush Sharma
  • 1,891
  • 16
  • 23
Vishal Gaur
  • 658
  • 6
  • 18
  • It looks like throws exception in your code doesn't work, bcoz statement are underlined, i tried to do it in background using AsyncTask, you can check it here http://lakjeewa.blogspot.com/2014/05/simple-android-client-server-application.html but i cant put there "throws IOException" and most of code is underlined – AidanSalvatore Nov 20 '15 at 13:01
  • why don't you try catch the exception rather than throw it – Vishal Gaur Nov 20 '15 at 13:07
  • good point, so i catched the exceptions, but another problem came out, connection problems, logs here http://wklej.org/id/1850892/ – AidanSalvatore Nov 20 '15 at 13:21
  • change server 127.0.0.1 to 10.0.2.2 – Vishal Gaur Nov 20 '15 at 13:28
  • http://stackoverflow.com/questions/5495534/java-net-connectexception-localhost-127-0-0-18080-connection-refused – Vishal Gaur Nov 20 '15 at 13:29
  • thanks, you help me a lot. I've read the topic and i used 192.168.X.X bcoz i test my app on phone. I can connect to server now, server sending file to my phone, and it says that everything is fine but there is no file on my sd card so something is wrong and i got no errors. That's strange. Logs here http://wklej.org/id/1850932/ – AidanSalvatore Nov 20 '15 at 13:54
  • You might be right, but saving works perfectly on PC, the problem is with saving on sd card, so i think it's something wrong with android stuff – AidanSalvatore Nov 22 '15 at 12:09
  • chage fos = new FileOutputStream(FILE_TO_RECEIVED); and write fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory(), "sintel.mp4")); – Vishal Gaur Nov 22 '15 at 14:20
  • i tried this, but nothing happens, path is correct coz i tested it in other app. – AidanSalvatore Nov 22 '15 at 18:11
0

You can use Android own DownloadManager instaed of providing your own implementation.

It will also provide you progress in navigation drawer which will remove your lots of headache.

VikasGoyal
  • 3,308
  • 1
  • 22
  • 42