Android send file between two phones using socket and progress bar

百般思念 提交于 2019-12-08 10:42:27

问题


i want to make an application for transfer files using wifi direct, but my send and receiver progress bar won't update

my sender

public void Server () {

    new Thread(new Runnable() 
    {

        @Override
        public void run() {
            // TODO Auto-generated method stub
        try {
            //receive ip
          serverSocket = new ServerSocket(port);
          Socket socket = serverSocket.accept();

          BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
          String line = null;
          while ((line = in.readLine()) != null) {
              ClientIP = line;
          }

          in.close();
          socket.close();
          serverSocket.close();
          socket = null;
          serverSocket = null;

          try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

          //send file
          socket = new Socket();
          socket.bind(null);
          socketAddress = new InetSocketAddress(ClientIP, portal);
          socket.connect(socketAddress, SOCKET_TIMEOUT);

          FragmentManager fm = getFragmentManager();
          md = new MyDialog("Send to " + ClientIP );
          md.setRetainInstance(true);
          md.setCancelable(true);
          md.show(fm, "Sender");

          //reset progress bar status
          progressBarStatus = 0;
          //reset filesize
          fileSize = 0;

          byte buf[] = new byte[1024];
          File myFile = new File (path);
          filelength = file.length();

          OutputStream os = socket.getOutputStream();
          FileInputStream fis = new FileInputStream(myFile);
          BufferedInputStream bis = new BufferedInputStream(fis);

          while ((len = bis.read(buf)) != -1) {
                fileSize+=len;
                os.write(buf, 0, len);
                os.flush();
                //count for progress bar
                double d = (double) (fileSize * 100) / filelength;
                progressBarStatus = (int) Math.round(d);
                progressBarHandler.post(new Runnable() {
                    public void run() {
                        md.updateProgress(progressBarStatus);
                    }
                });
          }

          os.close();
          fis.close();
          bis.close();
          socket.close();

          // ok, file is downloaded,
            if (progressBarStatus >= 100) {

                // sleep 2 seconds, so that you can see the 100%
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                isSent = true;

                runOnUiThread(new Runnable() {
                    public void run() {
                        if(isSent) {    
                            Toast.makeText(getApplicationContext(), "File Sent", Toast.LENGTH_SHORT).show();
                        }
                    }
                });

                md.dismiss();
            }


            } catch (IOException e) {
              Log.e(TAG, "I/O Exception", e);
            }  finally {
                if (socket != null) {
                    if (socket.isConnected()) {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            // Give up
                            e.printStackTrace();
                        }
                    }
                }
            } 
        }
    }).start();
}

my receiver

public void Client (final String hostAddress) {

    socketAddress  = new InetSocketAddress(hostAddress, port);
    socket = new Socket();


    new Thread(new Runnable() 
    {

        @Override
        public void run() {
            // TODO Auto-generated method stub

        try {
          //sent ip
          socket.bind(null);
          socket.connect(socketAddress, SOCKET_TIMEOUT);
          PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
          out.println(messsage);
          out.flush();
          out.close();
          socket.close();
          socket = null;

          //receive file
          socket = new Socket();
          serverSocket = new ServerSocket(portal);
          socket = serverSocket.accept();

          final String name;
          final String ext;

          String[] tokens = filename.split("\\.(?=[^\\.]+$)");
          name = tokens[0];
          ext = tokens[1];

          final File f = new File(Environment.getExternalStorageDirectory() + "/"
                    + getPackageName() + "/" + name + System.currentTimeMillis()
                    + "." + ext);


          File dirs = new File(f.getParent());

            if (!dirs.exists())
                dirs.mkdirs();


            f.createNewFile();


            FragmentManager fm = getFragmentManager();

              md = new MyDialog("Receive from " + HostIP);
              md.setRetainInstance(true);
              md.setCancelable(true);
              md.show(fm, "Receiver");

            //reset progress bar status
              progressBarStatus = 0;
              //reset filesize
              fileSize = 0;

              filelength = f.length();

            InputStream is = socket.getInputStream();
            FileOutputStream fos = new FileOutputStream(f);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            byte buf[] = new byte[1024];  



            while ((len = is.read(buf)) != -1) {
                bos.write(buf, 0, len);
                bos.flush();
                fileSize+=len;
                double d = (double) (fileSize * 100) / filelength;
                progressBarStatus = (int) Math.round(d);
                progressBarHandler.post(new Runnable() {
                    public void run() {
                        md.updateProgress(progressBarStatus);
                    }
                });
            }

            is.close();
            fos.close();
            bos.close();
            socket.close();
            serverSocket.close();

            if (progressBarStatus >= 100) {

                // sleep 2 seconds, so that you can see the 100%
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                isSent = true;
                // close the progress bar dialog
                //progressBar.dismiss();
                runOnUiThread(new Runnable() {
                    public void run() {
                        // some code #3 (that needs to be ran in UI thread)
                        if(isSent) {    
                            Toast.makeText(getApplicationContext(), "File Received", Toast.LENGTH_SHORT).show();
                            btn.setEnabled(true);
                        }
                    }
                });

                md.dismiss();
            }

            } catch (IOException e) {
              Log.e(TAG, "IO Exception.", e);
            }
        }
    }).start();
}

and i use dialog fragment because i use API 14+

my dialog class

public class MyDialog extends DialogFragment {
ProgressBar mProgressBar;
String title;

public MyDialog (String title) {
    this.title = title;
}

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    setRetainInstance(true);

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState)
{
    View view = inflater.inflate(R.layout.popup, container);
    mProgressBar = (ProgressBar)view.findViewById(R.id.pb);

    getDialog().setTitle(title);

    getDialog().setCanceledOnTouchOutside(false);

    return view;
}

@Override
public void onDestroyView()
{
    if (getDialog() != null && getRetainInstance())
        getDialog().setDismissMessage(null);
    super.onDestroyView();


}

@Override
public void onCancel(DialogInterface dialog) {
    // TODO Auto-generated method stub
    super.onCancel(dialog);
    Toast.makeText(getActivity().getApplicationContext(), "Connection lost. Retry", Toast.LENGTH_SHORT).show();
    getActivity().finish();
}

public void updateProgress(int percent)
{
    mProgressBar.setProgress(percent);
}
}

i don't know why my code isn't working, my progress bar won't update and file not send. Anyone can help me? thx before


回答1:


You've got a lot of code, but as long as I know, the receiver should use an AsyncTask, that's how I do it and it works for me. Instead of a thread use an Asynctask and the OnProgressUpdate method of the AsyncTask to update the ProgressDialog in the main thread. For example:

 public class getFile extends AsyncTask<Void, String, Void>
 {

     ProgressDialog pB;
     String hostAddress=null;
     InetSocketAddress socketAddress;
     Socket socket=null;
     ServerSocket serverSocket=null;
     int port=3001;
     int SOCKET_TIMEOUT = 3000;

     public getFile(String _hostAddress, Context context)
     {
         this.pB = new ProgressDialog(context);
         this.pB.setTitle(context.getText(R.string.sYourMessageText);
         this.pB.setMessage(null);
         this.pB.setProgressNumberFormat(null);
         this.pB.setProgressPercentFormat(null);
         this.pB.setCancelable(false);
         Drawable d = getResources().getDrawable(R.drawable.x_greenprogress);
         pB.setProgressDrawable(d);
         pB.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
         hostAddress=_hostAddress;
     }

     @Override
     protected void onPreExecute()
     {
         this.pB.show();
     }

     @Override
     protected Void doInBackground(Void... params)
     {
        try {
          //sent ip
          socketAddress  = new InetSocketAddress(this.hostAddress, port);
          socket = new Socket();
          socket.bind(null);
          socket.connect(socketAddress, SOCKET_TIMEOUT);
          PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
          out.println(messsage);
          out.flush();
          out.close();
          socket.close();
          socket = null;

          //receive file
          socket = new Socket();
          serverSocket = new ServerSocket(portal);
          socket = serverSocket.accept();

          final String name;
          final String ext;

          String[] tokens = filename.split("\\.(?=[^\\.]+$)");
          name = tokens[0];
          ext = tokens[1];

          final File f = new File(Environment.getExternalStorageDirectory() + "/"
                    + getPackageName() + "/" + name + System.currentTimeMillis()
                    + "." + ext);


          File dirs = new File(f.getParent());

          if (!dirs.exists())
             dirs.mkdirs();

         f.createNewFile();


         InputStream is = socket.getInputStream();
         FileOutputStream fos = new FileOutputStream(f);
         BufferedOutputStream bos = new BufferedOutputStream(fos);
         byte buf[] = new byte[1024];
         while ((len = is.read(buf)) != -1)
         {
             bos.write(buf, 0, len);
             bos.flush();
             fileSize+=len;
             // to update the progress bar just call:
             this.publishProgress("" + (int) ((fileSize * 100) / filelength));
         }
         is.close();
         fos.close();
         bos.close();
         socket.close();
         serverSocket.close();
     }

     @Override
     protected void onProgressUpdate(String... progress)
     {
         this.pB.setProgress(Integer.parseInt(progress[0]));
     }

     @Override
     protected void onPostExecute(Void result)
     {
         if (this.pB.isShowing())
             this.pB.dismiss();
     }

 }

EDIT: By the way, why do you connect to the server, send an IP close the connection and wait for the server to connect? Why don't use the first socket to do the file transfer? The connection has already been established.



来源:https://stackoverflow.com/questions/17031618/android-send-file-between-two-phones-using-socket-and-progress-bar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!