I am uploading files via org.apache.http.client.HttpClient in android and I need implement progress bar. Is it possible to grab progress from: ?
HttpPost httppost = new HttpPost("some path");
HttpClient httpclient = new DefaultHttpClient();
try {
File file = new File("file path");
InputStream in = new BufferedInputStream(new FileInputStream(file));
byte[] bArray = new byte[(int) file.length()];
in.read(bArray);
String entity = Base64.encodeToString(bArray, Base64.DEFAULT);
httppost.setEntity(new StringEntity(entity));
HttpResponse response = httpclient.execute(httppost);
}
If not, please show an alternative way. Thanks
What you're going to want to do is create an AsyncTask that can handle this for you, overriding the onProgressUpdate method.
Here's a stripped down version of a something I tested in another app using HttpURLConnection. There may be some small redundancies and I think HttpURLConnection may be generally frowned upon, but this should work. Just use this class in whatever Activity class you're using (in this example, I refer to it as TheActivity) by calling new FileUploadTask().execute(). Of course you may need to tweak this to fit the needs of your app.
private class FileUploadTask extends AsyncTask<Object, Integer, Void> {
private ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(TheActivity.this);
dialog.setMessage("Uploading...");
dialog.setIndeterminate(false);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setProgress(0);
dialog.show();
}
#Override
protected Void doInBackground(Object... arg0) {
try {
File file = new File("file path");
FileInputStream fileInputStream = new FileInputStream(file);
byte[] bytes = new byte[(int) file.length()];
fileInputStream.read(bytes);
fileInputStream.close();
URL url = new URL("some path");
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
OutputStream outputStream = connection.getOutputStream();
int bufferLength = 1024;
for (int i = 0; i < bytes.length; i += bufferLength) {
int progress = (int)((i / (float) bytes.length) * 100);
publishProgress(progress);
if (bytes.length - i >= bufferLength) {
outputStream.write(bytes, i, bufferLength);
} else {
outputStream.write(bytes, i, bytes.length - i);
}
}
publishProgress(100);
outputStream.close();
outputStream.flush();
InputStream inputStream = connection.getInputStream();
// read the response
inputStream.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... progress) {
dialog.setProgress(progress[0]);
}
#Override
protected void onPostExecute(Void result) {
try {
dialog.dismiss();
} catch(Exception e) {
}
}
}
I don't think HttpURLConnection simply does the trick, as #Basbous pointed out, the actual data is bufferred until outputStream.flush() is called. According to android issue 3164, it's now fixed in post-froyo platform (android 2.2, sdk version 8), you need use - java.net.HttpURLConnection.setFixedLengthStreamingMode to work around the buffer behavior.
Related
I am trying to call an Restful api using following code. Now I want to show the progress(% of download). Is it at all possible? If, what change in code is needed for that?
BufferedReader reader=null;
try{
URL mUrl = new URL("http://dev.amazaws.com/formservice/rest/v1/registrationreports/registrationsbyproduct/132866/");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write( data );
writer.flush();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
{
sb.append(line);
}
String res = sb.toString();
}catch(Exception ex){
}finally{
try{
reader.close();
}catch(Exception ex) {}
}
Try this code, i have implemented this code in one of my application! You can get the idea how to show the percentage! and well This code actually download the JSON from server and saves it on mobile device.
public class LoginActivity extends Activity {
private ProgressDialog prgDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_layout);
}
// Button Click function, on which you want to make restApi call
public void buttonClicked(View view){
new PrefetchData().execute();
}
private class PrefetchData extends AsyncTask<Void, Integer, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// before making http calls
prgDialog = new ProgressDialog(LoginActivity.this);
prgDialog.setMessage("Downloading Data. Please wait...");
prgDialog.setIndeterminate(false);
prgDialog.setMax(100);
prgDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
prgDialog.setCancelable(false);
prgDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL("http://xyz/testJSON");
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
// Show ERROR
}
int fileLength = connection.getContentLength();
input = connection.getInputStream();
String extPath = Environment.getExternalStorageDirectory() + "/" + FILE_PATH;
// Environment.
File file = new File(extPath);
if(!file.exists()){
file.createNewFile();
}
output = new FileOutputStream(extPath);
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
if (fileLength > 0){
// only if total length is known
// publishing the progress....
publishProgress((int) (total * 100 / fileLength));
}
output.write(data, 0, count);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// After completing http call
// will close this activity and lauch main activity
Intent i = new Intent(LoginActivity.this, MainActivity.class);
startActivity(i);
// close this activity
finish();
}
//Update the progress
#Override
protected void onProgressUpdate(Integer... values)
{
prgDialog.setProgress(values[0]);
}
}
As stated in this question you most often wont know the size of the stream in advance https://stackoverflow.com/a/1119346/2122552
The stated answer also links to an api to get Filesizes. But with a RESTful API you usually dont know the exact size of the Inputstream.
But, however, if you know the size you can break it down to use 100 as 100% and calculate the progress as (downloadedBytes/fileSizeInBytes * 100). Otherwise just use an indeterminate ProgressBar.
You can check the case and make the progressbar indeterminate when you dont know the size of the answer, and otherwise calculate the progress and update it like shown in the official documentation
I am a new to android, I am trying to read pdf from server. I found different ways and tried most of them. I tried using webview, using google doc, but nothing suitable for me. and I don't prefer to use another third party or plugin.
I found this code which is working perfect, but it read from assets folder.
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_books_view);
CopyReadAssets();
}
private void CopyReadAssets()
{
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(getFilesDir(), "test.pdf");
try
{
in = assetManager.open("test.pdf");
out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag", e.getMessage());
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.parse("file://" + getFilesDir() + "/test.pdf"),
"application/pdf");
startActivity(intent);
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
I tried to modify it to:
public class TestActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
//Call an AsycTask so you don't lock the main UI thread
new RequestTask().execute();
}//end onCreate
private class RequestTask extends AsyncTask<String, String, String>
{
//Background task
protected String doInBackground(String... uri)
{
//Stuff you do in background goes here
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
//-------
String fileName="test";
String fileExtension=".pdf";
try
{
URL url = new URL("my url");
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String PATH = Environment.getExternalStorageDirectory() + "/mydownload/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, fileName+fileExtension);
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
responseString = fos.toString();
fos.flush();
fos.close();
is.close();
}
catch (ClientProtocolException e)
{
//TODO Handle problems..
}
catch (IOException e)
{
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
//Do anything with response..
//Stuff you do after the asych task is done
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.parse(result),
"application/pdf");
startActivity(intent);
}
} //end RequestTask class
but it gave me a toast message:
((Not a supported document type))
Can someone help me please, I spent almost the whole day trying to figure out the problem.
You have to use HttpClient to perform a GET request of your pdf file. This is an example returning a String buffer, you have to rearrange to create your PDF after your remote file is read
class RequestTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Do anything with response..
}
}
Than you can call
new RequestTask().execute(url);
I change the whole to more simple way using this code
//setContentView(R.layout.activity_main);
WebView webView=new WebView(GeneralHealthEducationArBooksViewActivity.this);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setPluginState(PluginState.ON);
//---you need this to prevent the webview from
// launching another browser when a url
// redirection occurs---
webView.setWebViewClient(new Callback());
String pdfURL = "your link";
webView.loadUrl(
"http://docs.google.com/gview?embedded=true&url=" + pdfURL);
setContentView(webView);
xml file
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</WebView>
Finally, pdf is displaying :)
I want to check progress of uploading file by HttpUrlConnection. How I can do this? I've tried to calculate bytes when writing data in OutputStream but it's wrong, cause real uploading happens only when I call conn.getInputStream(), so I need somehow to check inputStream. Here is my code:
public static void uploadMovie(final HashMap<String, String> dataSource, final OnLoadFinishedListener finishedListener, final ProgressListener progressListener) {
if (finishedListener != null) {
new Thread(new Runnable() {
public void run() {
try {
String boundary = getMD5(dataSource.size()+String.valueOf(System.currentTimeMillis()));
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.setCharset(Charset.forName("UTF-8"));
for (String key : dataSource.keySet()) {
if (key.equals(MoviesFragmentAdd.USERFILE)) {
FileBody userFile = new FileBody(new File(dataSource.get(key)));
multipartEntity.addPart(key, userFile);
continue;
}
multipartEntity.addPart(key, new StringBody(dataSource.get(key),ContentType.APPLICATION_JSON));
}
HttpEntity entity = multipartEntity.build();
HttpURLConnection conn = (HttpsURLConnection) new URL(URL_API + "/video/addForm/").openConnection();
conn.setUseCaches(false);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Cache-Control", "no-cache");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("Content-length", entity.getContentLength() + "");
conn.setRequestProperty(entity.getContentType().getName(),entity.getContentType().getValue());
OutputStream os = conn.getOutputStream();
entity.writeTo(os);
os.close();
//Real upload starting here -->>
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//<<--
JsonObject request = (JsonObject) gparser.parse(in.readLine());
if (!request.get("error").getAsBoolean()) {
//do something
}
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
Because you have to deal with upload, I'd suppose most time is taken when doing entity.writeTo(os);. Maybe the first contact to the server takes some time as well (DNS resolution, SSL-handshake, ...). The markers you set for "the real upload" are not correct IMO.
Now it depends on your Multipart-library, whether you can intercept writeTo. If it is clever and resource-efficient, it's iterating over the parts and streams the content one-by-one to the output stream. If not, and the .build() operation is creating a big fat byte[], then you could take this array, stream it in chunks to the server and tell your user how many percent of the upload is already done.
From a resource perspective I'd prefer not really knowing what happens. But if feedback is that important and if the movies are only a few megabytes in size, you could stream the Multipart-Entity first to a ByteArrayOutputStream and then write little chunks of the created byte-array to the server while notifying your user about progress. The following code is not validated or tested (you can see it as pseudo-code):
ByteArrayOutputStream baos = new ByteArrayOutputStream();
entity.writeTo(baos);
baos.close();
byte[] payload = baos.toByteArray();
baos = null;
OutputStream os = conn.getOutputStream();
int totalSize = payload.length;
int bytesTransferred = 0;
int chunkSize = 2000;
while (bytesTransferred < totalSize) {
int nextChunkSize = totalSize - bytesTransferred;
if (nextChunkSize > chunkSize) {
nextChunkSize = chunkSize;
}
os.write(payload, bytesTransferred, nextChunkSize); // TODO check outcome!
bytesTransferred += nextChunkSize;
// Here you can call the method which updates progress
// be sure to wrap it so UI-updates are done on the main thread!
updateProgressInfo(100 * bytesTransferred / totalSize);
}
os.close();
A more elegant way would be to write an intercepting OutputStream which registers progress and delegates the real write-operations to the underlaying "real" OutputStream.
Edit
#whizzzkey wrote:
I've re-checked it many times - entity.writeTo(os) DOESN'T do a real upload, it does conn.getResponseCode() or conn.getInputStream()
Now it's clear. HttpURLConnection is buffering your upload data, because it doesn't know the content-length. You've set the header 'Content-length', but oviously this is ignored by HUC. You have to call
conn.setFixedLengthStreamingMode(entity.getContentLength());
Then you should better remove the call to conn.setRequestProperty("Content-length", entity.getContentLength() + "");
In this case, HUC can write the headers and entity.writeTo(os) can really stream the data to the server. Otherwise the buffered data is sent when HUC knows how many bytes will be transferred. So in fact, getInputStream() tells HUC that you're finished, but before really reading the response, all the collected data has to be sent to the server.
I wouldn't recommend changing your code, but for those of you who don't know the exact size of the transferred data (in bytes, not characters!!), you can tell HUC that it should transfer the data in chunks without setting the exact content-length:
conn.setChunkedStreamingMode(-1); // use default chunk size
Right this code in your activity...
public class PublishPostToServer extends AsyncTask implements
ProgressListenerForPost {
public Context pContext;
public long totalSize;
private String response;
public PublishPostToServer(Context context) {
pContext = context;
}
protected void onPreExecute() {
showProgressDialog();
}
#Override
protected Boolean doInBackground(Void... params) {
boolean success = true;
try {
response = NetworkAdaptor.getInstance()
.upLoadMultipartImageToServer(
"",
"",
"", this, this); // Add file path, Authkey, caption
} catch (Exception e) {
success = false;
}
return success;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
//validateResponse(result, response);
}
#Override
protected void onProgressUpdate(Integer... values) {
try {
if (mProgressDialog != null) {
mProgressDialog.setProgress(values[0]);
}
} catch (Exception exception) {
}
}
#Override
public void transferred(long num) {
publishProgress((int) ((num / (float) totalSize) * 100));
}
}
private void showProgressDialog() {
try {
String dialogMsg = "Uploading Image...";
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage(dialogMsg);
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
} catch (Exception exception) {
}
}
Now, Make a NetworkAdapter Class
public String upLoadMultipartImageToServer(String sourceFileUri,
String auth_key, String caption, ProgressListenerForPost listiner,
PublishPostToServer asyncListiner) {
String upLoadServerUri = "" + "upload_image";
HttpPost httppost = new HttpPost(upLoadServerUri);
File file = new File(sourceFileUri);
if (file.exists()) {
FileBody filebodyVideo = new FileBody(file);
CustomMultiPartEntity multipartEntity = new CustomMultiPartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE, listiner);
try {
multipartEntity.addPart("auth_key", new StringBody(auth_key));
multipartEntity.addPart("caption", new StringBody(caption));
multipartEntity.addPart("image", filebodyVideo);
asyncListiner.totalSize = multipartEntity.getContentLength();
httppost.setEntity(multipartEntity);
}
catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
DefaultHttpClient mHttpClient = new DefaultHttpClient();
String response = "";
try {
response = mHttpClient.execute(httppost,
new MovieUploadResponseHandler());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response;
} else {
return null;
}
}
#SuppressWarnings("rawtypes")
private class MovieUploadResponseHandler implements ResponseHandler {
#Override
public Object handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
HttpEntity r_entity = response.getEntity();
String responseString = EntityUtils.toString(r_entity);
// DebugHelper.printData("UPLOAD", responseString);
return responseString;
}
}
public static boolean isValidResponse(String resultData) {
try {
} catch (Exception exception) {
//DebugHelper.printException(exception);
}
return true;
}
public String upLoadVideoToServer(String currentFilePath, String string,
PublishPostToServer publishPostToServer,
PublishPostToServer publishPostToServer2) {
// TODO Auto-generated method stub
return null;
}
I am trying to download an apk file through a rest service via http GET. The format recieved is JSON. I am able to recieve the data but it fails while deserializing to a java object. I get Outofmemory error.
I am running the file download process in an Asyn Task. Is there other better options to achieve the same functionality. The apk is about 2 MB. The data from a wcf service is Base64 encoded in json
private class DownloadFile extends AsyncTask<String, Integer, String>
{
#Override
protected String doInBackground(String... sUrl)
{
try
{
URL url = new URL(sUrl[0]);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Content-Type", "application/json");
c.setRequestProperty("Accept", "application/json");
c.setRequestProperty("Device","13");
c.setRequestProperty("Authorization","toughsecurity");
c.setDoInput(true);
c.connect();
String PATH = Environment.getExternalStorageDirectory() + "/download/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "app.apk");
FileOutputStream fos = new FileOutputStream(outputFile);
if(c.getResponseCode()==HttpURLConnection.HTTP_OK)
{
OutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/download/"+"temp.txt");
int read = 0;
byte[] bytes = new byte[1024];
while ((read = c.getInputStream().read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
InputStream in=new FileInputStream(Environment.getExternalStorageDirectory() + "/download/"+"temp.txt");
ObjectMapper mapper=new ObjectMapper();
AppDownload download= mapper.readValue(in, AppDownload.class);
byte[] data1=Base64Coder.decodeLines(download.Data);
byte[] content = data1;
int size = content.length;
InputStream is1 = null;
byte[] b = new byte[size];
is1 = new ByteArrayInputStream(content);
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is1.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
}
c.disconnect();
}
catch (Exception e)
{
Log.e("Jackson error",e.getMessage());
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// mProgressDialog.setProgress(progress[0]);
}
}
i wouldn't be surprised if the JSON library is barfing on a 2MB JSON file.
i know it probably isn't an option to change the API, but it's pretty strange to be returning binary data in JSON. it's not made for that. the API should provide two endpoints ... one that gets the object meta data including a link to the content, and one that returns the content only in binary form.
you could also try another JSON library.
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.
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.
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 :(.
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
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();
}
}