【问题标题】:Android send file between two phones using socket and progress barAndroid使用套接字和进度条在两部手机之间发送文件
【发布时间】:2013-06-12 04:35:13
【问题描述】:

我想创建一个使用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);
}
}

我不知道为什么我的代码不起作用,我的进度条不会更新并且文件不会发送。 任何人都可以帮助我吗?谢谢之前

【问题讨论】:

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


    【解决方案1】:

    你有很多代码,但据我所知,接收器应该使用 AsyncTask,我就是这样做的,它对我有用。代替线程使用 Asynctask 和 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关闭连接,然后等待服务器连接?为什么不使用第一个套接字进行文件传输?连接已经建立。

    【讨论】:

    • 感谢 ja_mesa 为您解答,我知道问题所在。这是因为我在发送文件时无法访问 ui 线程。我没有使用异步任务,因为我已经在我的应用程序中使用了线程。所以,我不能在我的线程中使用异步任务。你知道吗,如何调用 md.updateProgress(progressBarStatus);使用 ui 线程?
    • 我使用了两个连接,这是因为在第一个连接中,服务器使用套接字接收客户端 IP,第二个连接用于发送文件。谢谢你的建议 ja_mesa。
    • this的线程更新用户界面
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 2011-09-13
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多