My program is uploading a video from SD Card without a problem but I am trying to add a progress dialog to show how much bytes uploaded so far in percentage. I am using async task. However, altough I am able to show the dialog on the screen. The dialog is not updating. After the upload finished it turns to 100/100 and it dissappears. Could you please help me how can I update the progress dialog?
package com.isoft.uploader2;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class Proje2Activity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button select =(Button)findViewById(R.id.select);
Button back =(Button)findViewById(R.id.back1);
Button camera =(Button)findViewById(R.id.camera);
//Select a video from SD-Card
select.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
openGaleryVideo();
}
});
//Turn back
back.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
finish();
}
});
//Record a video
camera.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivity(intent);
}
});
}
/** Called when the activity is first created. */
public static final int SELECT_VIDEO=1;
public static final String TAG="UploadActivity";
String path="";
//Open Gallery
public void openGaleryVideo()
{
Intent intent=new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Video"),SELECT_VIDEO);
}
//Select the video and start to execute the upload class
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
{
if (requestCode == SELECT_VIDEO)
{
Uri videoUri = data.getData();
path= getPath(videoUri);
upload upload = new upload();
upload.execute();
}
}
}
//Getting the URİ from the SD Card
public String getPath(Uri uri)
{
String[] projection = { MediaStore.Video.Media.DATA};
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
//ASYNC TASK Upload Class which uploads the file and shows the progress via a dialog
public class upload extends AsyncTask<Object, Integer, Void>
{
//Initializations
public ProgressDialog dialog;
File file=new File(path);
String urlServer = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
String filename=file.getName();
int bytesRead, bytesAvailable, bufferSize,progress;
byte[] buffer;
int maxBufferSize = 20*1024*1024;
//Before start to upload the file creating a dialog
#Override
public void onPreExecute()
{
dialog = new ProgressDialog(Proje2Activity.this);
dialog.setMessage("Uploading...");
dialog.setIndeterminate(false);
dialog.setTitle("UPLOADING");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setProgress(0);
dialog.setMax(100);
dialog.show();
//Burada işlemi yapmadan önce ilk olarak ne yaptırmak istiyorsak burada yaparız.
//Örneğin burada dialog gösterip "onPostExecute()" metodunda dismiss edebiliriz.
}
//Uploading the file in background with showing the progress
#Override
public Void doInBackground(Object... arg0)
{
// TODO Auto-generated method stub
try
{
final FileInputStream fileInputStream = new FileInputStream(file);
URL url = new URL(urlServer);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setFixedLengthStreamingMode((int) file.length());
// 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");
connection.setRequestProperty("SD-FileName", filename);//This will be the file name
final DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
progress=0;
progress+=bytesRead;
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
publishProgress((int)((progress*100)/(file.length())));
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
progress+=bytesRead;
}//end of while statement
fileInputStream.close();
publishProgress(100);
outputStream.flush();
outputStream.close();
}//end of try body
catch (Exception ex)
{
//ex.printStackTrace();
Log.e("Error: ", ex.getMessage());
}
return null;
}//end of doInBackground method
//making an update on progress
#Override
public void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
dialog.setProgress(values[0]);
}//end of onProgressUpdate
//After finishing the progress the dialog will disappear!
#Override
public void onPostExecute(Void result)
{
try
{
dialog.dismiss();
} //End of the second try body
catch(Exception e)
{
}
}//end of onPostExecute method
}// end of asyncTask class
}//end of main
problems i noticed are :
your bufferSize can be total file length. so, in one read itself, the buffer can be full. i changed it to 512 to get noticeable change in progressbar
your resets progress variable inside the loop
also, you are writing the entire buffer (ie from 0 to bufferSize) to the output stream. not the actual `bytesRead. at the last portions you may get error values.
before reading again, you are not restting the buffer
updated code
bufferSize = 512;
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
progress=0;
while (bytesRead > 0)
{
progress+=bytesRead;
outputStream.write(buffer, 0, bytesRead);
bytesAvailable = fileInputStream.available();
publishProgress((int)((progress*100)/(file.length())));
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}//end of while statement
fileInputStream.close();
publishProgress(100);
outputStream.flush();
outputStream.close();
Your loop should look something like this, there was a couple of logical errors in your code.
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
progress=0;
progress+=bytesRead;
while (bytesRead > 0)
{
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
publishProgress((int)((progress/file.length())*100));
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
progress+=bytesRead;
}//end of while statement
Update: I just noticed, that you use a buffer with 20MB, change maxBufferSize to int maxBufferSize = 1024, and it should work.
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
The following errors are coming while running the code:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:864)
Caused by: java.lang.NullPointerException
at libcore.net.UriCodec.encode(UriCodec.java:132)
at java.net.URLEncoder.encode(URLEncoder.java:57)
at com.example.ayushspc.fileupload.MainActivity$BackgroundTask.doInBackground(MainActivity.java:171)
at com.example.ayushspc.fileupload.MainActivity$BackgroundTask.doInBackground(MainActivity.java:107)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:864)
Code for the MainActivity:
package com.example.ayushspc.fileupload;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
public class MainActivity extends Activity {
EditText editText;
private String text = null;
private int serverResponseCode = 0;
private ProgressDialog dialog = null;
private String upLoadServerUri = null;
private String imagepath = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.textbox);
upLoadServerUri = "";
}
public void selectFile(View view) {
Intent intent = new Intent();
intent.setType("*/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), 1);
text = editText.getText().toString();
text += "/";
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
public void uploadFile(View view) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Uplaod Started", Toast.LENGTH_SHORT).show();
}
});
new BackgroundTask().execute(imagepath, text);
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
new BgTask().execute(requestCode, resultCode, data);
}
public String getPath(Uri uri) {
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
class BackgroundTask extends AsyncTask<String, Void, Integer> {
#Override
protected Integer doInBackground(String... params) {
String fileuri = params[0];
String filePath = params[1];
HttpURLConnection conn;
DataOutputStream dos;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1024 * 1024;
int maxSize = 1024 * 1024;
File sourceFile = new File(fileuri);
final long length = sourceFile.length();
if (length / maxSize > 1) {
dialog.dismiss();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "File Larger than 1MB", Toast.LENGTH_SHORT).show();
}
});
return 0;
}
if (!sourceFile.isFile()) {
dialog.dismiss();
Log.e("uploadFile", "Source File not exist :" + imagepath);
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Source File not exist :", Toast.LENGTH_SHORT).show();
}
});
return 0;
} else {
try {
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(upLoadServerUri);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("uploaded_file", fileuri);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String data = URLEncoder.encode("file_path", "UTF-8") + "=" + URLEncoder.encode(filePath, "UTF-8");
bufferedWriter.write(data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
+ fileuri + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
final String serverResponseMessage = conn.getResponseMessage();
Log.i("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode);
if (serverResponseCode == 200) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "File Upload Complete.", Toast.LENGTH_SHORT).show();
}
});
} else {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, serverResponseMessage, Toast.LENGTH_SHORT).show();
}
});
}
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
return serverResponseCode;
} // End else block
}
}
class BgTask extends AsyncTask<Object, Void, Void> {
#Override
protected Void doInBackground(Object... params) {
Integer requestCode = (Integer) params[0];
Integer resultCode = (Integer) params[1];
Intent data = (Intent) params[2];
if (requestCode == 1 && resultCode == RESULT_OK) {
Uri selectedImageUri = data.getData();
imagepath = getPath(selectedImageUri);
}
return null;
}
}
}
And it keeps giving errors on
String data = URLEncoder.encode("file_path", "UTF-8") + "=" + URLEncoder.encode(filePath, "UTF-8");
Can anyone please point out what the error is and what should i do to rectify it?
Obviously, filePath is null. Make sure your data is non-null before operating on it.
I want to add an image uploader to my app, I can choose an image from the image folder, but when I chose an image, the image path is only displayed as "null", and when I click upload, I get this Error:
BitmapFactory﹕ Unable to decode stream: java.lang.NullPointerException:
This is my code:
package com.test.mysqltest;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class UploadToServer extends Activity implements OnClickListener{
private TextView messageText;
private Button uploadButton, btnselectpic;
private ImageView imageview;
private int serverResponseCode = 0;
private ProgressDialog dialog = null;
private String upLoadServerUri = null;
private String imagepath=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upload_to_server);
uploadButton = (Button)findViewById(R.id.uploadButton);
btnselectpic = (Button)findViewById(R.id.button_selectpic);
messageText = (TextView)findViewById(R.id.messageText);
imageview = (ImageView)findViewById(R.id.imageView_pic);
btnselectpic.setOnClickListener(this);
uploadButton.setOnClickListener(this);
upLoadServerUri = "http://www.eywow.com/webservice/UploadToServer.php";
ImageView img= new ImageView(this);
}
#Override
public void onClick(View arg0) {
if(arg0==btnselectpic)
{
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), 1);
}
else if (arg0==uploadButton) {
dialog = ProgressDialog.show(UploadToServer.this, "", "Uploading file...", true);
messageText.setText("uploading started.....");
new Thread(new Runnable() {
public void run() {
uploadFile(imagepath);
}
}).start();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK) {
//Bitmap photo = (Bitmap) data.getData().getPath();
Uri selectedImageUri = data.getData();
imagepath = getPath(selectedImageUri);
Bitmap bitmap=BitmapFactory.decodeFile(imagepath);
imageview.setImageBitmap(bitmap);
messageText.setText("Uploading file path:" +imagepath);
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
public int uploadFile(String sourceFileUri) {
String fileName = sourceFileUri;
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File(sourceFileUri);
if (!sourceFile.isFile()) {
dialog.dismiss();
Log.e("uploadFile", "Source File not exist :"+imagepath);
runOnUiThread(new Runnable() {
public void run() {
messageText.setText("Source File not exist :"+ imagepath);
}
});
return 0;
}
else
{
try {
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(upLoadServerUri);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("uploaded_file", fileName);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
+ fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
Log.i("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode);
if(serverResponseCode == 200){
runOnUiThread(new Runnable() {
public void run() {
String msg = "File Upload Completed.\n\n See uploaded file here : \n\n"
+" F:/wamp/wamp/www/uploads";
messageText.setText(msg);
Toast.makeText(UploadToServer.this, "File Upload Complete.", Toast.LENGTH_SHORT).show();
}
});
}
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
dialog.dismiss();
ex.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
messageText.setText("MalformedURLException Exception : check script url.");
Toast.makeText(UploadToServer.this, "MalformedURLException", Toast.LENGTH_SHORT).show();
}
});
Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
} catch (Exception e) {
dialog.dismiss();
e.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
messageText.setText("Got Exception : see logcat ");
Toast.makeText(UploadToServer.this, "Got Exception : see logcat ", Toast.LENGTH_SHORT).show();
}
});
Log.e("Upload file to server Exception", "Exception : " + e.getMessage(), e);
}
dialog.dismiss();
return serverResponseCode;
} // End else block
}
}
Any ideas how to solve this problem?
Use this line of code directly in onActivityResult()
Bitmap bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri));
This should work.
Edit:
Try to find yourself bro I already had written above:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK) {
...
Bitmap bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri));
imageview.setImageBitmap(bitmap);
...
}
}
It works better now, the image preview is working for the first time, but I still dont get the right file path to upload it: Image uploader
This is my updated Code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK) {
//Bitmap photo = (Bitmap) data.getData().getPath();
Uri selectedImageUri = data.getData();
try { Bitmap bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImageUri));
imageview.setImageBitmap(bitmap);
messageText.setText("Uploading file path:" +imagepath);
} catch(IOException ie) {
messageText.setText("Error");
}
}
}
I am uploading a file from android to my webserver using the DataOutputStream with the following code:
public class SnapshotUploadTask extends AsyncTask<Object, Integer, Void> {
private final File file;
private final ProgressDialog progressDialog;
private final Activity activity;
public SnapshotUploadTask(File file, ProgressDialog progressDialog, Activity activity) {
this.progressDialog = progressDialog;
this.file = file;
this.activity = activity;
}
#Override
protected void onPreExecute() {
progressDialog.setProgress(0);
}
#Override
protected Void doInBackground(Object... arg0) {
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead;
int bytesAvailable;
int bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 512;
try {
FileInputStream fileInputStream = new FileInputStream(file);
URL url = new URL("http://bla.bla.bla/upload");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("ENCTYPE", "multipart/form-data");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
connection.setRequestProperty("uploaded_file", file.getName());
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" + file.getName() + "\"" + lineEnd);
dataOutputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
final int hundredPercent = bytesAvailable;
progressDialog.setMax(hundredPercent);
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dataOutputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
final int restBytes = bytesAvailable;
final int uploadedBytes = hundredPercent - restBytes;
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog.setProgress((int) uploadedBytes);
if (restBytes <= 0) {
progressDialog.setMessage(activity.getString(R.string.camera_uploading_done));
}
}
});
}
dataOutputStream.writeBytes(lineEnd);
dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
int serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
if (serverResponseCode == 200) {
progressDialog.dismiss();
}
fileInputStream.close();
dataOutputStream.flush();
dataOutputStream.close();
} catch (Exception e) {
progressDialog.dismiss();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
Now what happens is that i update my progressDialog as soon as i have written a certain amount of bytes into the OutputStream which leads to the progressDialog reaching 100% before the data is actually received by the server.
I only know when the transmission is complete when i get to connection.getResponseCode();
What i want instead is to update the progress when the data chunks are actually received by the server. Is there a way to do that?
You need to be aware that HttpURLConnection buffers all the output unless you set fixed-length or chunked transfer mode, which you should certainly do instead of implementing it yourself. It does that so it can set the Content-Length header accurately. If you use one of these transfer modes there is no buffering.
NB You're misusing available(): see the Javadoc; and you're writing junk in most cases:
dataOutputStream.write(buffer, 0, bufferSize);
should be
dataOutputStream.write(buffer, 0, bytesRead);
You don't need all that fiddling around with available() inside the read loop either. Something like this is sufficient:
long total = 0;
int maxBufferSize = 8192; // at least. 512 is far too small.
while ((bytesRead = fileInputStream.read(buffer, 0, bufferSize)) > 0) {
dataOutputStream.write(buffer, 0, bytesRead);
total += bytesRead;
final long uploadedBytes = total;
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog.setProgress(uploadedBytes);
}
});
}
}
// at this point we are at end of stream
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog.setMessage(activity.getString(R.string.camera_uploading_done));
}
}
E&OE
I want to call startUpload(position); method in loginbutton.setOnClickListener(new View.OnClickListener() {} like this:
loginbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SaveData();
alertDialog.dismiss();
startUpload(position);
}
but always getting : position cannot be resolved to a variable
so where i am doing mistake, how can i resolve this issue..?
//Upload
public void startUpload(final int position) {
Runnable runnable = new Runnable() {
public void run() {
handler.post(new Runnable() {
public void run() {
View v = lstView.getChildAt(position - lstView.getFirstVisiblePosition());
// Show ProgressBar
ProgressBar progress = (ProgressBar)v.findViewById(R.id.progressBar);
progress.setVisibility(View.VISIBLE);
// Status
TextView status = (TextView)v.findViewById(R.id.ColStatus);
status.setText("Uploading..");
new UploadFileAsync().execute(String.valueOf(position));
}
});
}
};
new Thread(runnable).start();
}
// Async Upload
public class UploadFileAsync extends AsyncTask<String, Void, Void> {
String resServer;
int position;
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
position = Integer.parseInt(params[0]);
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
int resCode = 0;
String resMessage = "";
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
// File Path
strSDPath = ImageList.get(position).toString();
// Upload to PHP Script
String strUrlServer = "http://10.0.2.2/res/uploadFile.php";
try {
/** Check file on SD Card ***/
File file = new File(strSDPath);
if(!file.exists())
{
resServer = "{\"StatusID\":\"0\",\"Error\":\"Please check path on SD Card\"}";
return null;
}
FileInputStream fileInputStream = new FileInputStream(new File(strSDPath));
URL url = new URL(strUrlServer);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
DataOutputStream outputStream = new DataOutputStream(conn
.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream
.writeBytes("Content-Disposition: form-data; name=\"filUpload\";filename=\""
+ strSDPath + "\"" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Response Code and Message
resCode = conn.getResponseCode();
if(resCode == HttpURLConnection.HTTP_OK)
{
InputStream is = conn.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int read = 0;
while ((read = is.read()) != -1) {
bos.write(read);
}
byte[] result = bos.toByteArray();
bos.close();
resMessage = new String(result);
}
Log.d("resCode=",Integer.toString(resCode));
Log.d("resMessage=",resMessage.toString());
fileInputStream.close();
outputStream.flush();
outputStream.close();
resServer = resMessage.toString();
} catch (Exception ex) {
// Exception handling
return null;
}
return null;
}
protected void onPostExecute(Void unused) {
statusWhenFinish(position,resServer);
}
}
// when upload finish
protected void statusWhenFinish(int position, String resServer) {
View v = lstView.getChildAt(position - lstView.getFirstVisiblePosition());
// Show ProgressBar
ProgressBar progress = (ProgressBar)v.findViewById(R.id.progressBar);
progress.setVisibility(View.GONE);
// Status
TextView status = (TextView)v.findViewById(R.id.ColStatus);
/*** Default Value ***/
String strStatusID = "0";
String strMessage = "Unknow Status!";
try {
JSONObject c = new JSONObject(resServer);
strStatusID = c.getString("StatusID");
strMessage = c.getString("Message");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Prepare Status
if(strStatusID.equals("0"))
{
// When update Failed
status.setText( strMessage );
status.setTextColor(Color.RED);
// Enabled Button again
Button btnUpload = (Button) v.findViewById(R.id.btnUpload);
btnUpload.setText("Already Uploaded");
btnUpload.setTextColor(Color.RED);
btnUpload.setEnabled(true);
}
else
{
status.setText("Upload Completed.");
status.setTextColor(Color.GREEN);
}
}
}
The declaration of position is key here.
Make sure it is in the method that contains this loginButton.onClickListener code and make sure it is declared as final
If it can be resolved as a variable it's not because of your method,
it's because position is not an attribute.
So, delcare it as :
int position = -1;
And then set it to use your method.
TRY IT
Create a Global variable POSITION then assign POSITION=position in your startUpload() method , it'll work.
When referencing variables, they must be definitive within the scope of the method.
So for methods, make sure it is either passed as a parameter, or it is defined as a global variable within the class.
I have following code for downloading file from url to sdcard . This code is working fine for small file , but when the file size is large i am getting the downloaded file size 0.
Any help would be appreciated.
Java Code
setContentView(R.layout.activity_download_file);
String exStorageDirectory = Environment.getExternalStorageDirectory()
.toString();
File folder = new File(exStorageDirectory, "Folder");
folder.mkdir();
File file = new File(folder, "scjp.pdf");
try {
if (!file.exists()) {
file.createNewFile();
}
} catch (IOException e) {
e.printStackTrace();
}
downloadFile(
"http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf",
file);
}
private void downloadFile(String fileUrl, File directory) {
try {
FileOutputStream fileOutput = new FileOutputStream(directory);
URL url = new URL(fileUrl);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.connect();
InputStream inputStream = connection.getInputStream();
byte buffer[] = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, len);
}
fileOutput.close();
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Have a try with this code.
package com.example.stack;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RelativeLayout;
public class MainActivity extends Activity {
ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.enter, R.anim.enter);
setContentView(R.layout.activity_main);
// declare the dialog as a member field of your activity
// instantiate it within the onCreate method
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// execute this when the downloader must be fired
DownloadFile downloadFile = new DownloadFile();
downloadFile.execute("http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf");
}
//The AsyncTask will look like this:
// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
private class DownloadFile extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... sUrl) {
try {
URL url = new URL(sUrl[0]);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a typical 0-100% progress bar
int fileLength = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/output.pdf");
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
}
return null;
}
//The method above (doInBackground) runs always on a background thread. You shouldn't do any UI tasks there. On the other hand, the onProgressUpdate and onPreExecute run on the UI thread, so there you can change the progress bar:
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
mProgressDialog.setProgress(progress[0]);
}
}
}
Add the following permission in you manifest file .
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
i have tested in mobile too. its worked.
Try working with this code:
URL url;
long startTime = System.currentTimeMillis();
// Open a connection to that URL.
URLConnection ucon = null;
try {
url = new URL(
"http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf");
ucon = url.openConnection();
Log.i("", "image download beginning: " + url);
ucon.setReadTimeout(TIMEOUT_CONNECTION);
ucon.setConnectTimeout(TIMEOUT_SOCKET);
// Define InputStreams to read from the URLConnection.
// uses 3KB download buffer
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
FileOutputStream outStream = new FileOutputStream(
"mnt/sdcard/example.pdf");
byte[] buff = new byte[5 * 1024];
int len;
while ((len = inStream.read(buff)) != -1) {
outStream.write(buff, 0, len);
}
outStream.flush();
outStream.close();
inStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
As per the java doc for public int read (byte\[\] buffer, int offset, int length) method it returns
the number of bytes actually read or -1 if the end of the stream has
been reached.
So you should check for -1 rather then 0.
Change your while loop from
while ((len = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, len);
}
to following
while ((len = inputStream.read(buffer)) != -1) {
fileOutput.write(buffer, 0, len);
}
And as pointed out in comments you should do this in background thread or AsyncTask...
EDIT1:
Can you put some logs to see the point of error.. like if the input stream is getting opened or not... Also after the call to connect check for the HTTP response code by calling getResponseCode() method if the response code is 200 then only create the file..