文件上传进度在上传前跳至100%

时间:2013-04-01 17:26:30

标签: java android android-asynctask

我无法对此文件上传功能执行进度百分比。我google了很多,我找不到解决方案

这是我的代码:

protected void onProgressUpdate(Integer... progress) {
    super.onProgressUpdate(progress);

    notification.contentView.setProgressBar(R.id.progressBar, 10, progress[0], false);
    contentView.setTextViewText(R.id.text, "changed");
    mNotificationManager.notify(NOTIFICATION_ID, notification);
}

@Override
protected String doInBackground(String... urls) {

    String upLoadServerUri = upurl;
    String fileName = urls[0];
    HttpURLConnection connection = null;
    DataOutputStream outputStream = null;
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 100 * 1024 * 1024;
    File sourceFile = new File(fileName);
    int sentBytes = 0;
    long fileSize = sourceFile.length();

     try {
            FileInputStream fileInputStream = new FileInputStream(new File(urls[0]));

            URL url = new URL(upurl);
            connection = (HttpURLConnection) url.openConnection();

            // Allow Inputs & Outputs
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setUseCaches(false);

            // Enable POST method
            connection.setRequestMethod("POST");

            connection.setRequestProperty("Connection", "Keep-Alive");
            connection.setRequestProperty("Content-Type",     "multipart/form-data;boundary="+boundary);

            outputStream = new DataOutputStream(     connection.getOutputStream() );
            outputStream.writeBytes(twoHyphens + boundary + lineEnd);
            outputStream.writeBytes("Content-Disposition: form-data; name=\"file[]\";filename=\""+ fileName + "\"" + lineEnd);
            outputStream.writeBytes(lineEnd);

            bytesAvailable = fileInputStream.available();
            Log.v("Size",bytesAvailable+"");

            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];

            // Read file
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            while (bytesRead > 0) {
                // Update progress dialog
                sentBytes += bytesRead;
                publishProgress((int)(sentBytes * 100 / fileSize));

                outputStream.write(buffer, 0, bufferSize);

                bytesAvailable = fileInputStream.available();
                Log.v("Available",bytesAvailable+"");

                bufferSize = Math.min(bytesAvailable,     maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0,      bufferSize);
            }

            outputStream.writeBytes(lineEnd);
            outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

            Scanner s = new Scanner(connection.getInputStream());
            s.useDelimiter("\\Z");
            final String response = s.next();

            // Responses from the server (code and message)
            int serverResponseCode       = connection.getResponseCode();
            String serverResponseMessage = connection.getResponseMessage();

            if(serverResponseCode == 200) {
                 runOnUiThread(new Runnable() {
                      public void run() {

                         Toast.makeText(BabupMain.this, "server say :" + response , Toast.LENGTH_SHORT).show();
                         Toast.makeText(BabupMain.this, "File Upload Complete.", Toast.LENGTH_SHORT).show();
                      }
                  });
             }

            fileInputStream.close();
            outputStream.flush();
            outputStream.close();

        } catch (MalformedURLException ex) {

            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(BabupMain.this, "Error 1 ", Toast.LENGTH_SHORT).show();
                }
            });

        } catch (final Exception e) {

            runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(BabupMain.this, "Error 2 "+ e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
        }

        //publishProgress();

        return null;
}

4 个答案:

答案 0 :(得分:1)

很难说,但考虑改变

publishProgress((int)(sentBytes * 100 / fileSize))

double progress = (double)sentBytes / fileSize;
publishProgress((int)progress);

修改

我会改变这个:

bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];

bytesRead = fileInputStream.read(buffer, 0, bufferSize);

while (bytesRead > 0)
{

      // Update progress dialog
    sentBytes += bytesRead;
    publishProgress((int)(sentBytes * 100 / fileSize));

    outputStream.write(buffer, 0, bufferSize);

    bytesAvailable = fileInputStream.available();
    Log.v("Available",bytesAvailable+"");



    bufferSize = Math.min(bytesAvailable,     maxBufferSize);
    bytesRead = fileInputStream.read(buffer, 0,      bufferSize);
}

buffer = new byte [maxBufferSize];

while (true)
{
    int bytesToRead = Math.min(maxBufferSize, fileInputStream.available());

    // Break if complete
    if(bytesToRead == 0){ break; }

    // Read bytes
    bytesRead = fileInputStream.read(buffer, 0, bytesToRead);

    // Write bytes
    outputStream.write(buffer, 0, bytesRead);

    // Update progress dialog
    sentBytes += bytesRead;

    // Publish progress
    double progress = (double)sentBytes / fileSize;
    publishProgress((int)progress);
}

如果您遇到此问题,我会放弃FileInputStream.available()方法,从File.length()获取总字节数,并在bytesRead >= File.length()时退出循环。< / p>

答案 1 :(得分:0)

如果任何一个面临同样的问题,请检查此网址:解决了内存泄漏的问题

http://developer.android.com/guide/topics/ui/notifiers/notifications.html#Progress

答案 2 :(得分:0)

只是简短地看一下......

  1. sentBytes * 100 / fileSize

    int sentBytes = 0;
    long fileSize = sourceFile.length();

    注意用int计算,long会在小数点变为turncate。可能会加倍。

  2. 第二个由于缺少代码而无法看到,但是评论为它提供了screems

      

    但通知变得粘滞,手机冻结

    你在后台线程(doInBackground())中使用了publishProgress(),我跳转你不要尝试在后台线程中触摸GUI

    您可以使用Handler()发布将由gui线程使用的Runnable

答案 3 :(得分:0)

这里有一个简单而又好的解决方案:&{34;发布内容&#34;部分中的https://developer.android.com/reference/java/net/HttpURLConnection.html

添加:

connection.setChunkedStreamingMode(0);

就在之后:

connection.setDoOutput(true);