I need know how much bytes has been uploaded for u

2019-01-28 06:42发布

问题:

I am developing an app for upload video to a Apache/PHP Server. In this moment I already can upload videos. I need show a progress bar while the file is being uploaded. I have the next code using AsyncTask and HTTP 4.1.1 Libraries for emulate the FORM.

class uploadVideo extends AsyncTask<Void,Void,String>{

    @Override
    protected String doInBackground(Void... params) {
        // Create a new HttpClient and Post Header
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("http://www.youtouch.cl/videoloader/index.php");           
        try {
            // Add your data
            File input=new File(fileName);              

            MultipartEntity multi=new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);                

            multi.addPart("video", new FileBody(input));                

            httppost.setEntity(multi);

            // Execute HTTP Post Request
            HttpResponse response = httpclient.execute(httppost);               

            HttpEntity entity = response.getEntity();

            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(
                            entity.getContent(), "UTF-8"));
            String sResponse = reader.readLine();
            return sResponse;

        } catch (ClientProtocolException e) {
            Log.v("Uri Galeria", e.toString());
            e.printStackTrace();                

        } catch (IOException e) {
            Log.v("Uri Galeria", e.toString());
            e.printStackTrace();                
        }
        return "error";
    }

    @Override
    protected void onProgressUpdate(Void... unsued) {
                //Here I do should update the progress bar
    }

    @Override
    protected void onPostExecute(String sResponse) {
        try {
            if (pd.isShowing())
                pd.dismiss();

            if (sResponse != null) {
                JSONObject JResponse = new JSONObject(sResponse);
                int success = JResponse.getInt("SUCCESS");
                String message = JResponse.getString("MESSAGE");
                if (success == 0) {
                    Toast.makeText(getApplicationContext(), message,
                            Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getApplicationContext(),
                            "Video uploaded successfully",
                            Toast.LENGTH_SHORT).show();

                }
            }
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(),
                    e.getMessage(),
                    Toast.LENGTH_LONG).show();
            Log.e(e.getClass().getName(), e.getMessage(), e);
        }
    }

I need know where I can get how much bytes has been uploaded. File.length is the total size.

回答1:

Check my answer here, I guess it answers your question: But update the file path of the image to your to be uploaded video

https://stackoverflow.com/questions/15572747/progressbar-in-asynctask-is-not-showing-on-upload



回答2:

Have you tried extending FileBody? Presumably the POST will either call getInputStream() or writeTo() in order to actually send the file data to the server. You could extend either of these (including the InputStream returned by getInputStream()) and keep track of how much data has been sent.



回答3:

thank to cyngus's idea I have resolved this issue. I have added the next code for tracking the uploaded bytes:

Listener on upload button:

    btnSubir.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            //pd = ProgressDialog.show(VideoAndroidActivity.this, "", "Subiendo Video", true, false);

            pd = new ProgressDialog(VideoAndroidActivity.this);
            pd.setMessage("Uploading Video");
            pd.setIndeterminate(false);
            pd.setMax(100);
            pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            pd.show();
            //Thread thread=new Thread(new threadUploadVideo());
            //thread.start();
            new UploadVideo().execute();
        }
    });

Asynctask for run the upload:

class UploadVideo extends AsyncTask<Void,Integer,String> {
    private FileBody fb;

    @Override
    protected String doInBackground(Void... params) {
        // Create a new HttpClient and Post Header
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("http://www.youtouch.cl/videoloader/index.php");   
        int count;
        try {
            // Add your data
            File input=new File(fileName);

            // I created a Filebody Object
            fb=new FileBody(input);
            MultipartEntity multi=new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
            multi.addPart("video",fb);          

            httppost.setEntity(multi);              
            // Execute HTTP Post Request
            HttpResponse response = httpclient.execute(httppost);

            //get the InputStream
            InputStream is=fb.getInputStream();

            //create a buffer
            byte data[] = new byte[1024];//1024

            //this var updates the progress bar
            long total=0;
            while((count=is.read(data))!=-1){
                total+=count;
                publishProgress((int)(total*100/input.length()));
            }
            is.close();             
            HttpEntity entity = response.getEntity();

            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(
                            entity.getContent(), "UTF-8"));
            String sResponse = reader.readLine();
            return sResponse;

        } catch (ClientProtocolException e) {
            Log.v("Uri Galeria", e.toString());
            e.printStackTrace();                

        } catch (IOException e) {
            Log.v("Uri Galeria", e.toString());
            e.printStackTrace();                
        }
        return "error";
    }

    @Override
    protected void onProgressUpdate(Integer... unsued) {        
        pd.setProgress(unsued[0]);
    }

    @Override
    protected void onPostExecute(String sResponse) {
        try {
            if (pd.isShowing())
                pd.dismiss();

            if (sResponse != null) {
                    Toast.makeText(getApplicationContext(),sResponse,Toast.LENGTH_SHORT).show();
                    Log.i("Splash", sResponse);                 
            }
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(),
                    e.getMessage(),
                    Toast.LENGTH_LONG).show();
            Log.e(e.getClass().getName(), e.getMessage(), e);
        }
    }


}

The progress bar load is bit slow (in starting seems be freeze and then load of 1 to 100 very fast), but works.

Sorry, my english is regular :(.



回答4:

What I used to do is to extends org.apache.http.entity.ByteArrayEntity and override the writeTo function like below, while bytes output it will pass though writeTo(), so you can count current output bytes:

@Override
public void writeTo(final OutputStream outstream) throws IOException 
{
    if (outstream == null) {
        throw new IllegalArgumentException("Output stream may not be null");
    }

    InputStream instream = new ByteArrayInputStream(this.content);

    try {
        byte[] tmp = new byte[512];
        int total = (int) this.content.length;
        int progress = 0;
        int increment = 0;
        int l;
        int percent;

        // read file and write to http output stream
        while ((l = instream.read(tmp)) != -1) {
            // check progress
            progress = progress + l;
            percent = Math.round(((float) progress / (float) total) * 100);

            // if percent exceeds increment update status notification
            // and adjust increment
            if (percent > increment) {
                increment += 10;
                // update percentage here !!
            }

            // write to output stream
            outstream.write(tmp, 0, l);
        }

        // flush output stream
        outstream.flush();
    } finally {
        // close input stream
        instream.close();
    }
}