Android使用套接字和进度条在两部手机之间发送文件

时间:2013-06-10 19:47:34

标签: android sockets file-transfer android-progressbar android-dialogfragment

我想使用wifi直接制作传输文件的应用程序,但我的发送和接收器进度条不会更新

我的发件人

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();
}

我的接收器

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();
}

我使用对话框片段因为我使用API​​ 14 +

我的对话类

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);
}
}

我不知道为什么我的代码无效,我的进度条不会更新,文件也不会发送。 有人可以帮帮我吗?先于

1 个答案:

答案 0 :(得分:0)

你有很多代码,但只要我知道,接收器应该使用AsyncTask,我就是这样做的,它对我有用。而不是线程使用Asyncctask的Asynctask和OnProgressUpdate方法来更新主线程中的ProgressDialog。 例如:

 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();
     }

 }

编辑: 顺便说一下,为什么要连接到服务器,发送IP关闭连接并等待服务器连接?为什么不使用第一个套接字进行文件传输?这种联系已经建立。